newrelic 13.9.0 → 13.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/NEWS.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
### v13.9.1 (2026-01-12)
|
|
2
|
+
|
|
3
|
+
#### Bug fixes
|
|
4
|
+
|
|
5
|
+
* Updated `getHostnameSafe` to invalidate the cache is trying to assign the host based on the gcp cloud run id ([#3650](https://github.com/newrelic/node-newrelic/pull/3650)) ([d395c76](https://github.com/newrelic/node-newrelic/commit/d395c76d5612a7e562efa1a807c35e805a38ab14))
|
|
6
|
+
* Updated logic to properly assign content and role in LangChain chat completion messages ([#3638](https://github.com/newrelic/node-newrelic/pull/3638)) ([407bcb6](https://github.com/newrelic/node-newrelic/commit/407bcb66b7e3be1b6f1d28bcf6e3b022a7022c96))
|
|
7
|
+
|
|
8
|
+
#### Documentation
|
|
9
|
+
|
|
10
|
+
* Updated compatibility report ([#3643](https://github.com/newrelic/node-newrelic/pull/3643)) ([8929ab3](https://github.com/newrelic/node-newrelic/commit/8929ab3ae6cc28edbef4bee41a2084154361d6e0))
|
|
11
|
+
|
|
1
12
|
### v13.9.0 (2026-01-08)
|
|
2
13
|
|
|
3
14
|
#### Features
|
package/lib/config/index.js
CHANGED
|
@@ -993,7 +993,21 @@ Config.prototype.getIPAddresses = function getIPAddresses() {
|
|
|
993
993
|
function getHostnameSafe(gcpId = null) {
|
|
994
994
|
let _hostname
|
|
995
995
|
const config = this
|
|
996
|
-
|
|
996
|
+
/**
|
|
997
|
+
* We cache the result of _hostname unless an argument is passed in.
|
|
998
|
+
* The argument of `gcpId` is only passed in during the collection of
|
|
999
|
+
* facts: see `lib/collector/facts.js`. This needs to take precedence
|
|
1000
|
+
* over whatever the hostname was previously because gcp cloud run instances
|
|
1001
|
+
* report as localhost and we want to use the cloud run id
|
|
1002
|
+
*
|
|
1003
|
+
* @param {string} gcpId GCP metadata ID
|
|
1004
|
+
* @returns {string} host name
|
|
1005
|
+
*/
|
|
1006
|
+
this.getHostnameSafe = function getCachedHostname(gcpId = null) {
|
|
1007
|
+
if (gcpId) {
|
|
1008
|
+
return getHostnameSafe.call(config, gcpId)
|
|
1009
|
+
}
|
|
1010
|
+
|
|
997
1011
|
return _hostname
|
|
998
1012
|
}
|
|
999
1013
|
try {
|
|
@@ -22,6 +22,7 @@ const { makeId } = require('../../util/hashes')
|
|
|
22
22
|
*/
|
|
23
23
|
const defaultParams = {
|
|
24
24
|
content: '',
|
|
25
|
+
role: null,
|
|
25
26
|
sequence: 0,
|
|
26
27
|
completionId: makeId(36),
|
|
27
28
|
isResponse: undefined
|
|
@@ -29,6 +30,7 @@ const defaultParams = {
|
|
|
29
30
|
|
|
30
31
|
class LangChainCompletionMessage extends LangChainEvent {
|
|
31
32
|
content
|
|
33
|
+
role
|
|
32
34
|
sequence
|
|
33
35
|
completion_id
|
|
34
36
|
is_response
|
|
@@ -47,6 +49,13 @@ class LangChainCompletionMessage extends LangChainEvent {
|
|
|
47
49
|
this.sequence = params.sequence
|
|
48
50
|
this.completion_id = params.completionId
|
|
49
51
|
this.is_response = params.isResponse ?? false
|
|
52
|
+
if (params.role) {
|
|
53
|
+
this.role = params.role
|
|
54
|
+
} else {
|
|
55
|
+
// As a backup, we can infer the role based on if it
|
|
56
|
+
// is a response or not.
|
|
57
|
+
this.role = this.is_response ? 'assistant' : 'user'
|
|
58
|
+
}
|
|
50
59
|
|
|
51
60
|
if (agent.config.ai_monitoring.record_content.enabled === true) {
|
|
52
61
|
this.content = params.content
|
|
@@ -46,7 +46,7 @@ class LangchainSubscriber extends Subscriber {
|
|
|
46
46
|
events,
|
|
47
47
|
metadata,
|
|
48
48
|
tags,
|
|
49
|
-
err
|
|
49
|
+
err
|
|
50
50
|
}) {
|
|
51
51
|
const { agent } = this
|
|
52
52
|
segment.end()
|
|
@@ -74,7 +74,8 @@ class LangchainSubscriber extends Subscriber {
|
|
|
74
74
|
events,
|
|
75
75
|
completionSummary,
|
|
76
76
|
segment,
|
|
77
|
-
transaction
|
|
77
|
+
transaction,
|
|
78
|
+
pkgVersion
|
|
78
79
|
})
|
|
79
80
|
|
|
80
81
|
if (err) {
|
|
@@ -100,8 +101,9 @@ class LangchainSubscriber extends Subscriber {
|
|
|
100
101
|
* @param {LangChainCompletionSummary} params.completionSummary LlmChatCompletionSummary event
|
|
101
102
|
* @param {TraceSegment} params.segment active segment
|
|
102
103
|
* @param {Transaction} params.transaction active transaction
|
|
104
|
+
* @param {string} params.pkgVersion module version of the LangChain package
|
|
103
105
|
*/
|
|
104
|
-
recordCompletions({ events, completionSummary, segment, transaction }) {
|
|
106
|
+
recordCompletions({ events, completionSummary, segment, transaction, pkgVersion }) {
|
|
105
107
|
const { agent, logger } = this
|
|
106
108
|
for (let i = 0; i < events.length; i += 1) {
|
|
107
109
|
let msg = events[i]
|
|
@@ -121,6 +123,7 @@ class LangchainSubscriber extends Subscriber {
|
|
|
121
123
|
sequence: i,
|
|
122
124
|
agent,
|
|
123
125
|
content: msgString,
|
|
126
|
+
role: msg?.role,
|
|
124
127
|
completionId: completionSummary.id,
|
|
125
128
|
segment,
|
|
126
129
|
transaction,
|
|
@@ -131,7 +134,7 @@ class LangchainSubscriber extends Subscriber {
|
|
|
131
134
|
|
|
132
135
|
this.recordEvent({
|
|
133
136
|
type: 'LlmChatCompletionMessage',
|
|
134
|
-
pkgVersion
|
|
137
|
+
pkgVersion,
|
|
135
138
|
msg: completionMsg
|
|
136
139
|
})
|
|
137
140
|
}
|
|
@@ -37,7 +37,7 @@ class LangchainRunnableStreamSubscriber extends LangchainSubscriber {
|
|
|
37
37
|
|
|
38
38
|
asyncEnd(data) {
|
|
39
39
|
const { agent, logger } = this
|
|
40
|
-
//
|
|
40
|
+
// Exit early if need be.
|
|
41
41
|
if (!this.enabled) {
|
|
42
42
|
if (!this.streamingEnabled) {
|
|
43
43
|
logger.warn('Langchain streaming instrumentation is disabled, stream will not be instrumented.')
|
|
@@ -48,26 +48,26 @@ class LangchainRunnableStreamSubscriber extends LangchainSubscriber {
|
|
|
48
48
|
.incrementCallCount()
|
|
49
49
|
return
|
|
50
50
|
}
|
|
51
|
-
|
|
52
|
-
// Instrument stream
|
|
53
51
|
const ctx = this.agent.tracer.getContext()
|
|
54
52
|
const { segment, transaction } = ctx
|
|
55
53
|
if (transaction?.isActive() !== true) {
|
|
56
54
|
return
|
|
57
55
|
}
|
|
58
56
|
|
|
57
|
+
// Extract data.
|
|
59
58
|
const request = data?.arguments?.[0]
|
|
60
59
|
const params = data?.arguments?.[1] || {}
|
|
61
60
|
const metadata = params?.metadata ?? {}
|
|
62
61
|
const tags = params?.tags ?? []
|
|
63
62
|
const { result: output, error: err, moduleVersion: pkgVersion } = data
|
|
64
63
|
|
|
65
|
-
//
|
|
66
|
-
// Skip instrumenting streaming and create Llm Events from
|
|
67
|
-
// the data we have
|
|
64
|
+
// Instrument stream.
|
|
68
65
|
if (output?.next) {
|
|
69
66
|
this.wrapNextHandler({ output, segment, request, metadata, tags, transaction, pkgVersion })
|
|
70
67
|
} else {
|
|
68
|
+
// Input error occurred which means a stream was not created.
|
|
69
|
+
// Skip instrumenting streaming and create Llm Events from
|
|
70
|
+
// the data we have
|
|
71
71
|
this.recordChatCompletionEvents({
|
|
72
72
|
transaction,
|
|
73
73
|
segment,
|
|
@@ -115,11 +115,16 @@ class LangchainRunnableStreamSubscriber extends LangchainSubscriber {
|
|
|
115
115
|
pkgVersion
|
|
116
116
|
})
|
|
117
117
|
} else {
|
|
118
|
+
// Concat the streamed content
|
|
118
119
|
if (typeof result?.value?.content === 'string') {
|
|
119
|
-
//
|
|
120
|
+
// LangChain BaseMessageChunk case
|
|
120
121
|
content += result.value.content
|
|
121
|
-
} else {
|
|
122
|
+
} else if (typeof result?.value === 'string') {
|
|
123
|
+
// Base LangChain case
|
|
122
124
|
content += result.value
|
|
125
|
+
} else if (typeof result?.value?.[0] === 'string') {
|
|
126
|
+
// Array parser case
|
|
127
|
+
content += result.value[0]
|
|
123
128
|
}
|
|
124
129
|
}
|
|
125
130
|
return result
|