dd-trace 5.60.0 → 5.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +6 -0
- package/package.json +5 -8
- package/packages/datadog-code-origin/index.js +3 -0
- package/packages/datadog-instrumentations/src/azure-functions.js +5 -0
- package/packages/datadog-instrumentations/src/azure-service-bus.js +38 -0
- package/packages/datadog-instrumentations/src/fastify.js +17 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/next.js +17 -18
- package/packages/datadog-instrumentations/src/sequelize.js +4 -14
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +6 -38
- package/packages/datadog-plugin-azure-functions/src/index.js +57 -28
- package/packages/datadog-plugin-azure-service-bus/src/index.js +15 -0
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +36 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +24 -23
- package/packages/datadog-plugin-langchain/src/handlers/default.js +0 -18
- package/packages/datadog-plugin-langchain/src/handlers/embedding.js +0 -48
- package/packages/datadog-plugin-langchain/src/handlers/language_models.js +18 -0
- package/packages/datadog-plugin-langchain/src/tracing.js +5 -17
- package/packages/dd-trace/src/appsec/iast/analyzers/cookie-analyzer.js +8 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +2 -2
- package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +11 -10
- package/packages/dd-trace/src/appsec/iast/analyzers/set-cookies-header-interceptor.js +25 -18
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +13 -5
- package/packages/dd-trace/src/appsec/iast/analyzers/unvalidated-redirect-analyzer.js +5 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/xcontenttype-header-missing-analyzer.js +2 -2
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +4 -0
- package/packages/dd-trace/src/appsec/iast/index.js +25 -7
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +79 -21
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +1 -3
- package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +0 -4
- package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +4 -8
- package/packages/dd-trace/src/datastreams/schemas/schema_sampler.js +2 -4
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/ci.js +8 -0
- package/packages/dd-trace/src/plugins/util/git.js +50 -15
- package/packages/dd-trace/src/profiling/profilers/events.js +3 -3
- package/packages/dd-trace/src/profiling/profilers/space.js +4 -3
- package/packages/dd-trace/src/profiling/profilers/wall.js +5 -4
- package/packages/dd-trace/src/remote_config/scheduler.js +2 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +4 -0
- package/packages/dd-trace/src/supported-configurations.json +1 -0
- package/packages/datadog-plugin-langchain/src/handlers/chain.js +0 -50
- package/packages/datadog-plugin-langchain/src/handlers/language_models/chat_model.js +0 -101
- package/packages/datadog-plugin-langchain/src/handlers/language_models/index.js +0 -48
- package/packages/datadog-plugin-langchain/src/handlers/language_models/llm.js +0 -58
|
@@ -485,27 +485,41 @@ function getGitMetadata (ciMetadata) {
|
|
|
485
485
|
|
|
486
486
|
if (headCommitSha) {
|
|
487
487
|
if (isShallowRepository()) {
|
|
488
|
-
|
|
488
|
+
fetchHeadCommitSha(headCommitSha)
|
|
489
489
|
}
|
|
490
490
|
|
|
491
|
-
tags[GIT_COMMIT_HEAD_MESSAGE] =
|
|
492
|
-
sanitizedExec('git', ['show', '-s', '--format=%B', headCommitSha], null, null, null, false)
|
|
493
|
-
|
|
494
491
|
const [
|
|
492
|
+
gitHeadCommitSha,
|
|
493
|
+
headAuthorDate,
|
|
495
494
|
headAuthorName,
|
|
496
495
|
headAuthorEmail,
|
|
497
|
-
|
|
496
|
+
headCommitterDate,
|
|
498
497
|
headCommitterName,
|
|
499
498
|
headCommitterEmail,
|
|
500
|
-
|
|
501
|
-
] = sanitizedExec(
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
499
|
+
headCommitMessage
|
|
500
|
+
] = sanitizedExec(
|
|
501
|
+
'git',
|
|
502
|
+
[
|
|
503
|
+
'show',
|
|
504
|
+
'-s',
|
|
505
|
+
'--format=\'%H","%aI","%an","%ae","%cI","%cn","%ce","%B\'',
|
|
506
|
+
headCommitSha
|
|
507
|
+
],
|
|
508
|
+
null,
|
|
509
|
+
null,
|
|
510
|
+
null,
|
|
511
|
+
false
|
|
512
|
+
).split('","')
|
|
513
|
+
|
|
514
|
+
if (gitHeadCommitSha) {
|
|
515
|
+
tags[GIT_COMMIT_HEAD_AUTHOR_DATE] = headAuthorDate
|
|
516
|
+
tags[GIT_COMMIT_HEAD_AUTHOR_EMAIL] = headAuthorEmail
|
|
517
|
+
tags[GIT_COMMIT_HEAD_AUTHOR_NAME] = headAuthorName
|
|
518
|
+
tags[GIT_COMMIT_HEAD_COMMITTER_DATE] = headCommitterDate
|
|
519
|
+
tags[GIT_COMMIT_HEAD_COMMITTER_EMAIL] = headCommitterEmail
|
|
520
|
+
tags[GIT_COMMIT_HEAD_COMMITTER_NAME] = headCommitterName
|
|
521
|
+
tags[GIT_COMMIT_HEAD_MESSAGE] = headCommitMessage
|
|
522
|
+
}
|
|
509
523
|
}
|
|
510
524
|
|
|
511
525
|
const entries = [
|
|
@@ -544,6 +558,26 @@ function getGitInformationDiscrepancy () {
|
|
|
544
558
|
return { gitRepositoryUrl, gitCommitSHA }
|
|
545
559
|
}
|
|
546
560
|
|
|
561
|
+
function fetchHeadCommitSha (headSha) {
|
|
562
|
+
const remoteName = getGitRemoteName()
|
|
563
|
+
|
|
564
|
+
sanitizedExec(
|
|
565
|
+
'git',
|
|
566
|
+
[
|
|
567
|
+
'fetch',
|
|
568
|
+
'--update-shallow',
|
|
569
|
+
'--filter=blob:none',
|
|
570
|
+
'--recurse-submodules=no',
|
|
571
|
+
'--no-write-fetch-head',
|
|
572
|
+
remoteName,
|
|
573
|
+
headSha
|
|
574
|
+
],
|
|
575
|
+
{ name: TELEMETRY_GIT_COMMAND, tags: { command: 'fetch_head_commit_sha' } },
|
|
576
|
+
{ name: TELEMETRY_GIT_COMMAND_MS, tags: { command: 'fetch_head_commit_sha' } },
|
|
577
|
+
{ name: TELEMETRY_GIT_COMMAND_ERRORS, tags: { command: 'fetch_head_commit_sha' } }
|
|
578
|
+
)
|
|
579
|
+
}
|
|
580
|
+
|
|
547
581
|
module.exports = {
|
|
548
582
|
getGitMetadata,
|
|
549
583
|
getLatestCommits,
|
|
@@ -561,5 +595,6 @@ module.exports = {
|
|
|
561
595
|
checkAndFetchBranch,
|
|
562
596
|
getLocalBranches,
|
|
563
597
|
getMergeBase,
|
|
564
|
-
getCounts
|
|
598
|
+
getCounts,
|
|
599
|
+
fetchHeadCommitSha
|
|
565
600
|
}
|
|
@@ -375,10 +375,10 @@ function createPossionProcessSamplingFilter (samplingIntervalMillis) {
|
|
|
375
375
|
* source with a sampling event filter and an event serializer.
|
|
376
376
|
*/
|
|
377
377
|
class EventsProfiler {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
this.eventSerializer = new EventSerializer()
|
|
378
|
+
type = 'events'
|
|
379
|
+
eventSerializer = new EventSerializer()
|
|
381
380
|
|
|
381
|
+
constructor (options = {}) {
|
|
382
382
|
const eventHandler = event => this.eventSerializer.addEvent(event)
|
|
383
383
|
const eventFilter = options.timelineSamplingEnabled
|
|
384
384
|
// options.samplingInterval comes in microseconds, we need millis
|
|
@@ -8,13 +8,14 @@ function strategiesToCallbackMode (strategies, callbackMode) {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
class NativeSpaceProfiler {
|
|
11
|
+
type = 'space'
|
|
12
|
+
_pprof
|
|
13
|
+
_started = false
|
|
14
|
+
|
|
11
15
|
constructor (options = {}) {
|
|
12
|
-
this.type = 'space'
|
|
13
16
|
this._samplingInterval = options.heapSamplingInterval || 512 * 1024
|
|
14
17
|
this._stackDepth = options.stackDepth || 64
|
|
15
|
-
this._pprof = undefined
|
|
16
18
|
this._oomMonitoring = options.oomMonitoring || {}
|
|
17
|
-
this._started = false
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
start ({ mapper, nearOOMCallback } = {}) {
|
|
@@ -69,8 +69,12 @@ function ensureChannelsActivated () {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
class NativeWallProfiler {
|
|
72
|
+
type = 'wall'
|
|
73
|
+
_mapper
|
|
74
|
+
_pprof
|
|
75
|
+
_started = false
|
|
76
|
+
|
|
72
77
|
constructor (options = {}) {
|
|
73
|
-
this.type = 'wall'
|
|
74
78
|
this._samplingIntervalMicros = options.samplingInterval || 1e6 / 99 // 99hz
|
|
75
79
|
this._flushIntervalMillis = options.flushInterval || 60 * 1e3 // 60 seconds
|
|
76
80
|
this._codeHotspotsEnabled = !!options.codeHotspotsEnabled
|
|
@@ -86,8 +90,6 @@ class NativeWallProfiler {
|
|
|
86
90
|
// cpu profiling is enabled.
|
|
87
91
|
this._withContexts = this._captureSpanData || this._timelineEnabled || this._cpuProfilingEnabled
|
|
88
92
|
this._v8ProfilerBugWorkaroundEnabled = !!options.v8ProfilerBugWorkaroundEnabled
|
|
89
|
-
this._mapper = undefined
|
|
90
|
-
this._pprof = undefined
|
|
91
93
|
|
|
92
94
|
// Bind these to this so they can be used as callbacks
|
|
93
95
|
if (this._withContexts && this._captureSpanData) {
|
|
@@ -97,7 +99,6 @@ class NativeWallProfiler {
|
|
|
97
99
|
this._generateLabels = this._generateLabels.bind(this)
|
|
98
100
|
|
|
99
101
|
this._logger = options.logger
|
|
100
|
-
this._started = false
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
codeHotspotsEnabled () {
|
|
@@ -16,6 +16,10 @@ const messaging = {
|
|
|
16
16
|
opName: () => 'amqp.send',
|
|
17
17
|
serviceName: amqpServiceName
|
|
18
18
|
},
|
|
19
|
+
'azure-service-bus': {
|
|
20
|
+
opName: () => 'azure.servicebus.send',
|
|
21
|
+
serviceName: ({ tracerService }) => `${tracerService}-azure-service-bus`
|
|
22
|
+
},
|
|
19
23
|
'google-cloud-pubsub': {
|
|
20
24
|
opName: () => 'pubsub.request',
|
|
21
25
|
serviceName: ({ tracerService }) => `${tracerService}-pubsub`
|
|
@@ -209,6 +209,7 @@
|
|
|
209
209
|
"DD_TRACE_AWS_SDK_STEPFUNCTIONS_ENABLED": ["A"],
|
|
210
210
|
"DD_TRACE_AXIOS_ENABLED": ["A"],
|
|
211
211
|
"DD_TRACE_AZURE_FUNCTIONS_ENABLED": ["A"],
|
|
212
|
+
"DD_TRACE_AZURE_SERVICE_BUS_ENABLED": ["A"],
|
|
212
213
|
"DD_TRACE_BAGGAGE_MAX_BYTES": ["A"],
|
|
213
214
|
"DD_TRACE_BAGGAGE_MAX_ITEMS": ["A"],
|
|
214
215
|
"DD_TRACE_BAGGAGE_TAG_KEYS": ["A"],
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const LangChainHandler = require('./default')
|
|
4
|
-
|
|
5
|
-
class LangChainChainHandler extends LangChainHandler {
|
|
6
|
-
getSpanStartTags (ctx, provider, span) {
|
|
7
|
-
const tags = {}
|
|
8
|
-
|
|
9
|
-
if (!this.isPromptCompletionSampled(span)) return tags
|
|
10
|
-
|
|
11
|
-
let inputs = ctx.args?.[0]
|
|
12
|
-
inputs = Array.isArray(inputs) ? inputs : [inputs]
|
|
13
|
-
|
|
14
|
-
for (const idx in inputs) {
|
|
15
|
-
const input = inputs[idx]
|
|
16
|
-
if (input !== null && typeof input === 'object') {
|
|
17
|
-
for (const [key, value] of Object.entries(input)) {
|
|
18
|
-
// these are mappings to the python client names, ie lc_kwargs
|
|
19
|
-
// only present on BaseMessage types
|
|
20
|
-
if (key.includes('lc_')) continue
|
|
21
|
-
tags[`langchain.request.inputs.${idx}.${key}`] = this.normalize(value)
|
|
22
|
-
}
|
|
23
|
-
} else {
|
|
24
|
-
tags[`langchain.request.inputs.${idx}`] = this.normalize(input)
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return tags
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
getSpanEndTags (ctx, span) {
|
|
32
|
-
const tags = {}
|
|
33
|
-
|
|
34
|
-
if (!this.isPromptCompletionSampled(span)) return tags
|
|
35
|
-
|
|
36
|
-
let outputs = ctx.result
|
|
37
|
-
outputs = Array.isArray(outputs) ? outputs : [outputs]
|
|
38
|
-
|
|
39
|
-
for (const idx in outputs) {
|
|
40
|
-
const output = outputs[idx]
|
|
41
|
-
tags[`langchain.response.outputs.${idx}`] = this.normalize(
|
|
42
|
-
typeof output === 'string' ? output : JSON.stringify(output)
|
|
43
|
-
)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return tags
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
module.exports = LangChainChainHandler
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const LangChainLanguageModelHandler = require('.')
|
|
4
|
-
|
|
5
|
-
const COMPLETIONS = 'langchain.response.completions'
|
|
6
|
-
|
|
7
|
-
class LangChainChatModelHandler extends LangChainLanguageModelHandler {
|
|
8
|
-
getSpanStartTags (ctx, provider, span) {
|
|
9
|
-
const tags = {}
|
|
10
|
-
|
|
11
|
-
const inputs = ctx.args?.[0]
|
|
12
|
-
|
|
13
|
-
for (const messageSetIndex in inputs) {
|
|
14
|
-
const messageSet = inputs[messageSetIndex]
|
|
15
|
-
|
|
16
|
-
for (const messageIndex in messageSet) {
|
|
17
|
-
const message = messageSet[messageIndex]
|
|
18
|
-
if (this.isPromptCompletionSampled(span)) {
|
|
19
|
-
tags[`langchain.request.messages.${messageSetIndex}.${messageIndex}.content`] =
|
|
20
|
-
this.normalize(message.content) || ''
|
|
21
|
-
}
|
|
22
|
-
tags[`langchain.request.messages.${messageSetIndex}.${messageIndex}.message_type`] = message.constructor.name
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const instance = ctx.instance
|
|
27
|
-
const identifyingParams = (typeof instance._identifyingParams === 'function' && instance._identifyingParams()) || {}
|
|
28
|
-
for (const [param, val] of Object.entries(identifyingParams)) {
|
|
29
|
-
if (param.toLowerCase().includes('apikey') || param.toLowerCase().includes('apitoken')) continue
|
|
30
|
-
if (val !== null && typeof val === 'object') {
|
|
31
|
-
for (const [key, value] of Object.entries(val)) {
|
|
32
|
-
tags[`langchain.request.${provider}.parameters.${param}.${key}`] = value
|
|
33
|
-
}
|
|
34
|
-
} else {
|
|
35
|
-
tags[`langchain.request.${provider}.parameters.${param}`] = val
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return tags
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
getSpanEndTags (ctx, span) {
|
|
43
|
-
const { result } = ctx
|
|
44
|
-
|
|
45
|
-
const tags = {}
|
|
46
|
-
|
|
47
|
-
const sampled = this.isPromptCompletionSampled(span)
|
|
48
|
-
|
|
49
|
-
this.extractTokenMetrics(ctx.currentStore?.span, result)
|
|
50
|
-
|
|
51
|
-
for (const messageSetIdx in result?.generations) {
|
|
52
|
-
const messageSet = result.generations[messageSetIdx]
|
|
53
|
-
|
|
54
|
-
for (const chatCompletionIdx in messageSet) {
|
|
55
|
-
const chatCompletion = messageSet[chatCompletionIdx]
|
|
56
|
-
|
|
57
|
-
const text = chatCompletion.text
|
|
58
|
-
const message = chatCompletion.message
|
|
59
|
-
let toolCalls = message.tool_calls
|
|
60
|
-
|
|
61
|
-
if (text && sampled) {
|
|
62
|
-
tags[
|
|
63
|
-
`${COMPLETIONS}.${messageSetIdx}.${chatCompletionIdx}.content`
|
|
64
|
-
] = this.normalize(text)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
tags[
|
|
68
|
-
`${COMPLETIONS}.${messageSetIdx}.${chatCompletionIdx}.message_type`
|
|
69
|
-
] = message.constructor.name
|
|
70
|
-
|
|
71
|
-
if (toolCalls) {
|
|
72
|
-
if (!Array.isArray(toolCalls)) {
|
|
73
|
-
toolCalls = [toolCalls]
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
for (const toolCallIndex in toolCalls) {
|
|
77
|
-
const toolCall = toolCalls[toolCallIndex]
|
|
78
|
-
|
|
79
|
-
tags[
|
|
80
|
-
`${COMPLETIONS}.${messageSetIdx}.${chatCompletionIdx}.tool_calls.${toolCallIndex}.id`
|
|
81
|
-
] = toolCall.id
|
|
82
|
-
tags[
|
|
83
|
-
`${COMPLETIONS}.${messageSetIdx}.${chatCompletionIdx}.tool_calls.${toolCallIndex}.name`
|
|
84
|
-
] = toolCall.name
|
|
85
|
-
|
|
86
|
-
const args = toolCall.args || {}
|
|
87
|
-
for (const [name, value] of Object.entries(args)) {
|
|
88
|
-
tags[
|
|
89
|
-
`${COMPLETIONS}.${messageSetIdx}.${chatCompletionIdx}.tool_calls.${toolCallIndex}.args.${name}`
|
|
90
|
-
] = this.normalize(value)
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return tags
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
module.exports = LangChainChatModelHandler
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { getTokensFromLlmOutput } = require('../../tokens')
|
|
4
|
-
const LangChainHandler = require('../default')
|
|
5
|
-
|
|
6
|
-
class LangChainLanguageModelHandler extends LangChainHandler {
|
|
7
|
-
extractApiKey (instance) {
|
|
8
|
-
const key = Object.keys(instance)
|
|
9
|
-
.find(key => {
|
|
10
|
-
const lower = key.toLowerCase()
|
|
11
|
-
return lower.includes('apikey') || lower.includes('apitoken')
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
let apiKey = instance[key]
|
|
15
|
-
if (apiKey?.secretValue && typeof apiKey.secretValue === 'function') {
|
|
16
|
-
apiKey = apiKey.secretValue()
|
|
17
|
-
}
|
|
18
|
-
if (!apiKey || apiKey.length < 4) return ''
|
|
19
|
-
return `...${apiKey.slice(-4)}`
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
extractProvider (instance) {
|
|
23
|
-
return typeof instance._llmType === 'function' && instance._llmType().split('-')[0]
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
extractModel (instance) {
|
|
27
|
-
for (const attr of ['model', 'modelName', 'modelId', 'modelKey', 'repoId']) {
|
|
28
|
-
const modelName = instance[attr]
|
|
29
|
-
if (modelName) return modelName
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
extractTokenMetrics (span, result) {
|
|
34
|
-
if (!span || !result) return
|
|
35
|
-
|
|
36
|
-
// we do not tag token metrics for non-openai providers
|
|
37
|
-
const provider = span.context()._tags['langchain.request.provider']
|
|
38
|
-
if (provider !== 'openai') return
|
|
39
|
-
|
|
40
|
-
const tokens = getTokensFromLlmOutput(result)
|
|
41
|
-
|
|
42
|
-
for (const [tokenKey, tokenCount] of Object.entries(tokens)) {
|
|
43
|
-
span.setTag(`langchain.tokens.${tokenKey}_tokens`, tokenCount)
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
module.exports = LangChainLanguageModelHandler
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const LangChainLanguageModelHandler = require('.')
|
|
4
|
-
|
|
5
|
-
class LangChainLLMHandler extends LangChainLanguageModelHandler {
|
|
6
|
-
getSpanStartTags (ctx, provider, span) {
|
|
7
|
-
const tags = {}
|
|
8
|
-
|
|
9
|
-
const prompts = ctx.args?.[0]
|
|
10
|
-
for (const promptIdx in prompts) {
|
|
11
|
-
if (!this.isPromptCompletionSampled(span)) continue
|
|
12
|
-
|
|
13
|
-
const prompt = prompts[promptIdx]
|
|
14
|
-
tags[`langchain.request.prompts.${promptIdx}.content`] = this.normalize(prompt) || ''
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const instance = ctx.instance
|
|
18
|
-
const identifyingParams = (typeof instance._identifyingParams === 'function' && instance._identifyingParams()) || {}
|
|
19
|
-
for (const [param, val] of Object.entries(identifyingParams)) {
|
|
20
|
-
if (param.toLowerCase().includes('apikey') || param.toLowerCase().includes('apitoken')) continue
|
|
21
|
-
if (val !== null && typeof val === 'object') {
|
|
22
|
-
for (const [key, value] of Object.entries(val)) {
|
|
23
|
-
tags[`langchain.request.${provider}.parameters.${param}.${key}`] = value
|
|
24
|
-
}
|
|
25
|
-
} else {
|
|
26
|
-
tags[`langchain.request.${provider}.parameters.${param}`] = val
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return tags
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
getSpanEndTags (ctx, span) {
|
|
34
|
-
const { result } = ctx
|
|
35
|
-
|
|
36
|
-
const tags = {}
|
|
37
|
-
const sampled = this.isPromptCompletionSampled(span)
|
|
38
|
-
|
|
39
|
-
this.extractTokenMetrics(ctx.currentStore?.span, result)
|
|
40
|
-
|
|
41
|
-
for (const completionIdx in result?.generations) {
|
|
42
|
-
const completion = result.generations[completionIdx]
|
|
43
|
-
if (sampled) {
|
|
44
|
-
tags[`langchain.response.completions.${completionIdx}.text`] = this.normalize(completion[0].text) || ''
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (completion && completion[0].generationInfo) {
|
|
48
|
-
const generationInfo = completion[0].generationInfo
|
|
49
|
-
tags[`langchain.response.completions.${completionIdx}.finish_reason`] = generationInfo.finishReason
|
|
50
|
-
tags[`langchain.response.completions.${completionIdx}.logprobs`] = generationInfo.logprobs
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return tags
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
module.exports = LangChainLLMHandler
|