dd-trace 5.59.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 +7 -7
- package/packages/datadog-code-origin/index.js +3 -0
- package/packages/datadog-instrumentations/src/apollo-server.js +14 -3
- 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/openai.js +13 -114
- 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-google-cloud-vertexai/src/tracing.js +3 -155
- 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/datadog-plugin-openai/src/stream-helpers.js +114 -0
- package/packages/datadog-plugin-openai/src/tracing.js +38 -0
- 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/appsec/reporter.js +3 -15
- package/packages/dd-trace/src/appsec/waf/index.js +20 -1
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +2 -1
- package/packages/dd-trace/src/config.js +0 -16
- 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/debugger/config.js +16 -0
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -6
- package/packages/dd-trace/src/debugger/devtools_client/index.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/log.js +19 -0
- package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/send.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/state.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -1
- package/packages/dd-trace/src/debugger/index.js +13 -3
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/ci.js +23 -7
- package/packages/dd-trace/src/plugins/util/git.js +53 -18
- package/packages/dd-trace/src/plugins/util/tags.js +8 -6
- 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/capabilities.js +2 -1
- package/packages/dd-trace/src/remote_config/index.js +2 -0
- 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
package/index.d.ts
CHANGED
|
@@ -167,6 +167,7 @@ interface Plugins {
|
|
|
167
167
|
"avsc": tracer.plugins.avsc;
|
|
168
168
|
"aws-sdk": tracer.plugins.aws_sdk;
|
|
169
169
|
"azure-functions": tracer.plugins.azure_functions;
|
|
170
|
+
"azure-service-bus": tracer.plugins.azure_service_bus;
|
|
170
171
|
"bunyan": tracer.plugins.bunyan;
|
|
171
172
|
"cassandra-driver": tracer.plugins.cassandra_driver;
|
|
172
173
|
"child_process": tracer.plugins.child_process;
|
|
@@ -1381,6 +1382,11 @@ declare namespace tracer {
|
|
|
1381
1382
|
*/
|
|
1382
1383
|
interface azure_functions extends Instrumentation {}
|
|
1383
1384
|
|
|
1385
|
+
/**
|
|
1386
|
+
* This plugin automatically instruments the
|
|
1387
|
+
* @azure/service-bus module
|
|
1388
|
+
*/
|
|
1389
|
+
interface azure_service_bus extends Integration {}
|
|
1384
1390
|
/**
|
|
1385
1391
|
* This plugin patches the [bunyan](https://github.com/trentm/node-bunyan)
|
|
1386
1392
|
* to automatically inject trace identifiers in log records when the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.61.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
],
|
|
115
115
|
"dependencies": {
|
|
116
116
|
"@datadog/libdatadog": "0.7.0",
|
|
117
|
-
"@datadog/native-appsec": "10.0.
|
|
117
|
+
"@datadog/native-appsec": "10.0.1",
|
|
118
118
|
"@datadog/native-iast-taint-tracking": "4.0.0",
|
|
119
119
|
"@datadog/native-metrics": "3.1.1",
|
|
120
120
|
"@datadog/pprof": "5.9.0",
|
|
@@ -124,7 +124,7 @@
|
|
|
124
124
|
"@opentelemetry/api": "1.8.0",
|
|
125
125
|
"@opentelemetry/core": "^1.14.0",
|
|
126
126
|
"crypto-randomuuid": "^1.0.0",
|
|
127
|
-
"dc-polyfill": "^0.1.
|
|
127
|
+
"dc-polyfill": "^0.1.10",
|
|
128
128
|
"ignore": "^7.0.5",
|
|
129
129
|
"import-in-the-middle": "^1.14.2",
|
|
130
130
|
"istanbul-lib-coverage": "^3.2.2",
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
"@msgpack/msgpack": "^3.1.2",
|
|
156
156
|
"@stylistic/eslint-plugin": "^5.0.0",
|
|
157
157
|
"@types/node": "^18.19.106",
|
|
158
|
-
"axios": "^1.
|
|
158
|
+
"axios": "^1.11.0",
|
|
159
159
|
"benchmark": "^2.1.4",
|
|
160
160
|
"body-parser": "^2.2.0",
|
|
161
161
|
"chai": "^4.5.0",
|
|
@@ -165,15 +165,15 @@
|
|
|
165
165
|
"eslint-plugin-mocha": "^10.5.0",
|
|
166
166
|
"eslint-plugin-n": "^17.20.0",
|
|
167
167
|
"eslint-plugin-promise": "^7.2.1",
|
|
168
|
-
"eslint-plugin-unicorn": "^
|
|
168
|
+
"eslint-plugin-unicorn": "^60.0.0",
|
|
169
169
|
"express": "^5.1.0",
|
|
170
170
|
"get-port": "^5.1.1",
|
|
171
171
|
"glob": "^7.2.3",
|
|
172
|
-
"globals": "^
|
|
172
|
+
"globals": "^16.3.0",
|
|
173
173
|
"graphql": "*",
|
|
174
174
|
"jszip": "^3.10.1",
|
|
175
175
|
"mocha": "^11.6.0",
|
|
176
|
-
"multer": "^2.0.
|
|
176
|
+
"multer": "^2.0.2",
|
|
177
177
|
"nock": "^11.9.1",
|
|
178
178
|
"nyc": "^15.1.0",
|
|
179
179
|
"octokit": "^5.0.3",
|
|
@@ -38,9 +38,12 @@ function exitTags (topOfStackFunc) {
|
|
|
38
38
|
function tag (type, topOfStackFunc, limit) {
|
|
39
39
|
// The `Error.prepareStackTrace` API doesn't support resolving source maps.
|
|
40
40
|
// Fall back to manually parsing the stack trace.
|
|
41
|
+
const originalLimit = Error.stackTraceLimit
|
|
42
|
+
Error.stackTraceLimit = Infinity
|
|
41
43
|
const dummy = {}
|
|
42
44
|
Error.captureStackTrace(dummy, topOfStackFunc)
|
|
43
45
|
const frames = parseUserLandFrames(dummy.stack, limit)
|
|
46
|
+
Error.stackTraceLimit = originalLimit
|
|
44
47
|
|
|
45
48
|
const tags = {
|
|
46
49
|
'_dd.code_origin.type': type
|
|
@@ -77,6 +77,17 @@ function apolloServerHook (apolloServer) {
|
|
|
77
77
|
return apolloServer
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
addHook(
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
addHook(
|
|
81
|
+
{ name: '@apollo/server', file: 'dist/cjs/ApolloServer.js', versions: ['>=4.0.0 <5.0.0'] },
|
|
82
|
+
apolloServerHook
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
addHook(
|
|
86
|
+
{ name: '@apollo/server', file: 'dist/cjs/express4/index.js', versions: ['>=4.0.0 <5.0.0'] },
|
|
87
|
+
apolloExpress4Hook
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
addHook(
|
|
91
|
+
{ name: '@apollo/server', file: 'dist/cjs/utils/HeaderMap.js', versions: ['>=4.0.0 <5.0.0'] },
|
|
92
|
+
apolloHeaderMapHook
|
|
93
|
+
)
|
|
@@ -11,6 +11,7 @@ const azureFunctionsChannel = dc.tracingChannel('datadog:azure:functions:invoke'
|
|
|
11
11
|
addHook({ name: '@azure/functions', versions: ['>=4'] }, azureFunction => {
|
|
12
12
|
const { app } = azureFunction
|
|
13
13
|
|
|
14
|
+
// Http triggers
|
|
14
15
|
shimmer.wrap(app, 'deleteRequest', wrapHandler)
|
|
15
16
|
shimmer.wrap(app, 'http', wrapHandler)
|
|
16
17
|
shimmer.wrap(app, 'get', wrapHandler)
|
|
@@ -18,6 +19,10 @@ addHook({ name: '@azure/functions', versions: ['>=4'] }, azureFunction => {
|
|
|
18
19
|
shimmer.wrap(app, 'post', wrapHandler)
|
|
19
20
|
shimmer.wrap(app, 'put', wrapHandler)
|
|
20
21
|
|
|
22
|
+
// Service Bus triggers
|
|
23
|
+
shimmer.wrap(app, 'serviceBusQueue', wrapHandler)
|
|
24
|
+
shimmer.wrap(app, 'serviceBusTopic', wrapHandler)
|
|
25
|
+
|
|
21
26
|
return azureFunction
|
|
22
27
|
})
|
|
23
28
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
channel,
|
|
5
|
+
addHook
|
|
6
|
+
} = require('./helpers/instrument')
|
|
7
|
+
|
|
8
|
+
const shimmer = require('../../datadog-shimmer')
|
|
9
|
+
|
|
10
|
+
const producerStartCh = channel('apm:azure-service-bus:send:start')
|
|
11
|
+
const producerErrorCh = channel('apm:azure-service-bus:send:error')
|
|
12
|
+
const producerFinishCh = channel('apm:azure-service-bus:send:finish')
|
|
13
|
+
|
|
14
|
+
addHook({ name: '@azure/service-bus', versions: ['>=7.9.2'] }, (obj) => {
|
|
15
|
+
const ServiceBusClient = obj.ServiceBusClient
|
|
16
|
+
shimmer.wrap(ServiceBusClient.prototype, 'createSender', createSender => function (queueOrTopicName) {
|
|
17
|
+
const sender = createSender.apply(this, arguments)
|
|
18
|
+
shimmer.wrap(sender._sender, 'send', send => function (msg) {
|
|
19
|
+
const ctx = { sender, msg }
|
|
20
|
+
return producerStartCh.runStores(ctx, () => {
|
|
21
|
+
return send.apply(this, arguments)
|
|
22
|
+
.then(
|
|
23
|
+
response => {
|
|
24
|
+
producerFinishCh.publish(ctx)
|
|
25
|
+
},
|
|
26
|
+
error => {
|
|
27
|
+
ctx.error = error
|
|
28
|
+
producerErrorCh.publish(ctx)
|
|
29
|
+
producerFinishCh.publish(ctx)
|
|
30
|
+
throw error
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
return sender
|
|
36
|
+
})
|
|
37
|
+
return obj
|
|
38
|
+
})
|
|
@@ -11,6 +11,7 @@ const queryParamsReadCh = channel('datadog:fastify:query-params:finish')
|
|
|
11
11
|
const cookieParserReadCh = channel('datadog:fastify-cookie:read:finish')
|
|
12
12
|
const responsePayloadReadCh = channel('datadog:fastify:response:finish')
|
|
13
13
|
const pathParamsReadCh = channel('datadog:fastify:path-params:finish')
|
|
14
|
+
const finishSetHeaderCh = channel('datadog:fastify:set-header:finish')
|
|
14
15
|
|
|
15
16
|
const parsingResources = new WeakMap()
|
|
16
17
|
const cookiesPublished = new WeakSet()
|
|
@@ -275,3 +276,19 @@ addHook({ name: 'fastify', versions: ['2'] }, fastify => {
|
|
|
275
276
|
addHook({ name: 'fastify', versions: ['1'] }, fastify => {
|
|
276
277
|
return shimmer.wrapFunction(fastify, fastify => wrapFastify(fastify, false))
|
|
277
278
|
})
|
|
279
|
+
|
|
280
|
+
function wrapReplyHeader (Reply) {
|
|
281
|
+
shimmer.wrap(Reply.prototype, 'header', header => function (key, value) {
|
|
282
|
+
const result = header.apply(this, arguments)
|
|
283
|
+
|
|
284
|
+
if (finishSetHeaderCh.hasSubscribers && key && value) {
|
|
285
|
+
finishSetHeaderCh.publish({ name: key, value, res: getRes(this) })
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
return result
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
return Reply
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
addHook({ name: 'fastify', file: 'lib/reply.js', versions: ['1', '2', '>=3'] }, wrapReplyHeader)
|
|
@@ -6,6 +6,7 @@ module.exports = {
|
|
|
6
6
|
'apollo-server-core': () => require('../apollo-server-core'),
|
|
7
7
|
'@aws-sdk/smithy-client': () => require('../aws-sdk'),
|
|
8
8
|
'@azure/functions': () => require('../azure-functions'),
|
|
9
|
+
'@azure/service-bus': () => require('../azure-service-bus'),
|
|
9
10
|
'@cucumber/cucumber': () => require('../cucumber'),
|
|
10
11
|
'@playwright/test': () => require('../playwright'),
|
|
11
12
|
'@elastic/elasticsearch': () => require('../elasticsearch'),
|
|
@@ -141,6 +141,20 @@ function instrument (req, res, handler, error) {
|
|
|
141
141
|
requests.add(req)
|
|
142
142
|
|
|
143
143
|
const ctx = { req, res }
|
|
144
|
+
// Parse query parameters from request URL
|
|
145
|
+
if (queryParsedChannel.hasSubscribers && req.url) {
|
|
146
|
+
// req.url is only the relative path (/foo?bar=baz) and new URL() needs a full URL
|
|
147
|
+
// so we give it a dummy base
|
|
148
|
+
const { searchParams } = new URL(req.url, 'http://dummy')
|
|
149
|
+
const query = {}
|
|
150
|
+
for (const key of searchParams.keys()) {
|
|
151
|
+
if (!query[key]) {
|
|
152
|
+
query[key] = searchParams.getAll(key)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
queryParsedChannel.publish({ query })
|
|
157
|
+
}
|
|
144
158
|
|
|
145
159
|
return startChannel.runStores(ctx, () => {
|
|
146
160
|
try {
|
|
@@ -280,24 +294,9 @@ addHook({
|
|
|
280
294
|
versions: ['>=13'],
|
|
281
295
|
file: 'dist/server/web/spec-extension/request.js'
|
|
282
296
|
}, request => {
|
|
283
|
-
|
|
284
|
-
return function wrappedGet () {
|
|
285
|
-
const nextUrl = originalGet.apply(this, arguments)
|
|
286
|
-
if (queryParsedChannel.hasSubscribers) {
|
|
287
|
-
const query = {}
|
|
288
|
-
for (const key of nextUrl.searchParams.keys()) {
|
|
289
|
-
if (!query[key]) {
|
|
290
|
-
query[key] = nextUrl.searchParams.getAll(key)
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
queryParsedChannel.publish({ query })
|
|
295
|
-
}
|
|
296
|
-
return nextUrl
|
|
297
|
-
}
|
|
298
|
-
})
|
|
297
|
+
const requestProto = Object.getPrototypeOf(request.NextRequest.prototype)
|
|
299
298
|
|
|
300
|
-
shimmer.massWrap(
|
|
299
|
+
shimmer.massWrap(requestProto, ['text', 'json'], function (originalMethod) {
|
|
301
300
|
return async function wrappedJson () {
|
|
302
301
|
const body = await originalMethod.apply(this, arguments)
|
|
303
302
|
|
|
@@ -307,7 +306,7 @@ addHook({
|
|
|
307
306
|
}
|
|
308
307
|
})
|
|
309
308
|
|
|
310
|
-
shimmer.wrap(
|
|
309
|
+
shimmer.wrap(requestProto, 'formData', function (originalFormData) {
|
|
311
310
|
return async function wrappedFormData () {
|
|
312
311
|
const body = await originalFormData.apply(this, arguments)
|
|
313
312
|
|
|
@@ -5,6 +5,7 @@ const shimmer = require('../../datadog-shimmer')
|
|
|
5
5
|
|
|
6
6
|
const dc = require('dc-polyfill')
|
|
7
7
|
const ch = dc.tracingChannel('apm:openai:request')
|
|
8
|
+
const onStreamedChunkCh = dc.channel('apm:openai:request:chunk')
|
|
8
9
|
|
|
9
10
|
const V4_PACKAGE_SHIMS = [
|
|
10
11
|
{
|
|
@@ -160,79 +161,12 @@ addHook({ name: 'openai', file: 'dist/api.js', versions: ['>=3.0.0 <4'] }, expor
|
|
|
160
161
|
return exports
|
|
161
162
|
})
|
|
162
163
|
|
|
163
|
-
function addStreamedChunk (content, chunk) {
|
|
164
|
-
content.usage = chunk.usage // add usage if it was specified to be returned
|
|
165
|
-
for (const choice of chunk.choices) {
|
|
166
|
-
const choiceIdx = choice.index
|
|
167
|
-
const oldChoice = content.choices.find(choice => choice?.index === choiceIdx)
|
|
168
|
-
if (oldChoice) {
|
|
169
|
-
if (!oldChoice.finish_reason) {
|
|
170
|
-
oldChoice.finish_reason = choice.finish_reason
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// delta exists on chat completions
|
|
174
|
-
const delta = choice.delta
|
|
175
|
-
|
|
176
|
-
if (delta) {
|
|
177
|
-
const content = delta.content
|
|
178
|
-
if (content) {
|
|
179
|
-
if (oldChoice.delta.content) { // we don't want to append to undefined
|
|
180
|
-
oldChoice.delta.content += content
|
|
181
|
-
} else {
|
|
182
|
-
oldChoice.delta.content = content
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
} else {
|
|
186
|
-
const text = choice.text
|
|
187
|
-
if (text) {
|
|
188
|
-
if (oldChoice.text) {
|
|
189
|
-
oldChoice.text += text
|
|
190
|
-
} else {
|
|
191
|
-
oldChoice.text = text
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// tools only exist on chat completions
|
|
197
|
-
const tools = delta && choice.delta.tool_calls
|
|
198
|
-
|
|
199
|
-
if (tools) {
|
|
200
|
-
oldChoice.delta.tool_calls = tools.map((newTool, toolIdx) => {
|
|
201
|
-
const oldTool = oldChoice.delta.tool_calls?.[toolIdx]
|
|
202
|
-
|
|
203
|
-
if (oldTool) {
|
|
204
|
-
oldTool.function.arguments += newTool.function.arguments
|
|
205
|
-
return oldTool
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
return newTool
|
|
209
|
-
})
|
|
210
|
-
}
|
|
211
|
-
} else {
|
|
212
|
-
// we don't know which choices arrive in which order
|
|
213
|
-
content.choices[choiceIdx] = choice
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
function convertBufferstoObjects (chunks) {
|
|
219
|
-
return Buffer
|
|
220
|
-
.concat(chunks) // combine the buffers
|
|
221
|
-
.toString() // stringify
|
|
222
|
-
.split(/(?=data:)/) // split on "data:"
|
|
223
|
-
.map(chunk => chunk.replaceAll('\n', '').slice(6)) // remove newlines and 'data: ' from the front
|
|
224
|
-
.slice(0, -1) // remove the last [DONE] message
|
|
225
|
-
.map(JSON.parse) // parse all of the returned objects
|
|
226
|
-
}
|
|
227
|
-
|
|
228
164
|
/**
|
|
229
165
|
* For streamed responses, we need to accumulate all of the content in
|
|
230
166
|
* the chunks, and let the combined content be the final response.
|
|
231
167
|
* This way, spans look the same as when not streamed.
|
|
232
168
|
*/
|
|
233
|
-
function wrapStreamIterator (response, options,
|
|
234
|
-
let processChunksAsBuffers = false
|
|
235
|
-
let chunks = []
|
|
169
|
+
function wrapStreamIterator (response, options, ctx) {
|
|
236
170
|
return function (itr) {
|
|
237
171
|
return function () {
|
|
238
172
|
const iterator = itr.apply(this, arguments)
|
|
@@ -240,39 +174,11 @@ function wrapStreamIterator (response, options, n, ctx) {
|
|
|
240
174
|
return next.apply(this, arguments)
|
|
241
175
|
.then(res => {
|
|
242
176
|
const { done, value: chunk } = res
|
|
243
|
-
|
|
244
|
-
if (chunk) {
|
|
245
|
-
chunks.push(chunk)
|
|
246
|
-
// TODO(BridgeAR): It likely depends on the options being passed
|
|
247
|
-
// through if the stream returns buffers or not. By reading that,
|
|
248
|
-
// we don't have to do the instanceof check anymore, which is
|
|
249
|
-
// relatively expensive.
|
|
250
|
-
if (chunk instanceof Buffer) {
|
|
251
|
-
// this operation should be safe
|
|
252
|
-
// if one chunk is a buffer (versus a plain object), the rest should be as well
|
|
253
|
-
processChunksAsBuffers = true
|
|
254
|
-
}
|
|
255
|
-
}
|
|
177
|
+
onStreamedChunkCh.publish({ ctx, chunk, done })
|
|
256
178
|
|
|
257
179
|
if (done) {
|
|
258
|
-
let body = {}
|
|
259
|
-
if (processChunksAsBuffers) {
|
|
260
|
-
chunks = convertBufferstoObjects(chunks)
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
if (chunks.length) {
|
|
264
|
-
// Define the initial body having all the content outside of choices from the first chunk
|
|
265
|
-
// this will include import data like created, id, model, etc.
|
|
266
|
-
body = { ...chunks[0], choices: Array.from({ length: n }) }
|
|
267
|
-
// Start from the first chunk, and add its choices into the body
|
|
268
|
-
for (const chunk_ of chunks) {
|
|
269
|
-
addStreamedChunk(body, chunk_)
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
180
|
finish(ctx, {
|
|
274
181
|
headers: response.headers,
|
|
275
|
-
data: body,
|
|
276
182
|
request: {
|
|
277
183
|
path: response.url,
|
|
278
184
|
method: options.method
|
|
@@ -312,17 +218,6 @@ for (const extension of extensions) {
|
|
|
312
218
|
// chat.completions and completions
|
|
313
219
|
const stream = streamedResponse && getOption(arguments, 'stream', false)
|
|
314
220
|
|
|
315
|
-
// we need to compute how many prompts we are sending in streamed cases for completions
|
|
316
|
-
// not applicable for chat completiond
|
|
317
|
-
let n
|
|
318
|
-
if (stream) {
|
|
319
|
-
n = getOption(arguments, 'n', 1)
|
|
320
|
-
const prompt = getOption(arguments, 'prompt')
|
|
321
|
-
if (Array.isArray(prompt) && typeof prompt[0] !== 'number') {
|
|
322
|
-
n *= prompt.length
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
221
|
const client = this._client || this.client
|
|
327
222
|
|
|
328
223
|
const ctx = {
|
|
@@ -348,7 +243,7 @@ for (const extension of extensions) {
|
|
|
348
243
|
const parsedPromise = origApiPromParse.apply(this, arguments)
|
|
349
244
|
.then(body => Promise.all([this.responsePromise, body]))
|
|
350
245
|
|
|
351
|
-
return handleUnwrappedAPIPromise(parsedPromise, ctx, stream
|
|
246
|
+
return handleUnwrappedAPIPromise(parsedPromise, ctx, stream)
|
|
352
247
|
})
|
|
353
248
|
|
|
354
249
|
return unwrappedPromise
|
|
@@ -361,7 +256,7 @@ for (const extension of extensions) {
|
|
|
361
256
|
const parsedPromise = origApiPromParse.apply(this, arguments)
|
|
362
257
|
.then(body => Promise.all([this.responsePromise, body]))
|
|
363
258
|
|
|
364
|
-
return handleUnwrappedAPIPromise(parsedPromise, ctx, stream
|
|
259
|
+
return handleUnwrappedAPIPromise(parsedPromise, ctx, stream)
|
|
365
260
|
})
|
|
366
261
|
|
|
367
262
|
ch.end.publish(ctx)
|
|
@@ -375,15 +270,15 @@ for (const extension of extensions) {
|
|
|
375
270
|
}
|
|
376
271
|
}
|
|
377
272
|
|
|
378
|
-
function handleUnwrappedAPIPromise (apiProm, ctx, stream
|
|
273
|
+
function handleUnwrappedAPIPromise (apiProm, ctx, stream) {
|
|
379
274
|
return apiProm
|
|
380
275
|
.then(([{ response, options }, body]) => {
|
|
381
276
|
if (stream) {
|
|
382
277
|
if (body.iterator) {
|
|
383
|
-
shimmer.wrap(body, 'iterator', wrapStreamIterator(response, options,
|
|
278
|
+
shimmer.wrap(body, 'iterator', wrapStreamIterator(response, options, ctx))
|
|
384
279
|
} else {
|
|
385
280
|
shimmer.wrap(
|
|
386
|
-
body.response.body, Symbol.asyncIterator, wrapStreamIterator(response, options,
|
|
281
|
+
body.response.body, Symbol.asyncIterator, wrapStreamIterator(response, options, ctx)
|
|
387
282
|
)
|
|
388
283
|
}
|
|
389
284
|
} else {
|
|
@@ -412,7 +307,11 @@ function finish (ctx, response, error) {
|
|
|
412
307
|
ch.error.publish(ctx)
|
|
413
308
|
}
|
|
414
309
|
|
|
415
|
-
|
|
310
|
+
// for successful streamed responses, we've already set the result on ctx.body,
|
|
311
|
+
// so we don't want to override it here
|
|
312
|
+
ctx.result ??= {}
|
|
313
|
+
Object.assign(ctx.result, response)
|
|
314
|
+
|
|
416
315
|
ch.asyncEnd.publish(ctx)
|
|
417
316
|
}
|
|
418
317
|
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const {
|
|
4
4
|
channel,
|
|
5
|
-
addHook
|
|
6
|
-
AsyncResource
|
|
5
|
+
addHook
|
|
7
6
|
} = require('./helpers/instrument')
|
|
8
7
|
|
|
9
8
|
const shimmer = require('../../datadog-shimmer')
|
|
@@ -18,8 +17,6 @@ addHook({ name: 'sequelize', versions: ['>=4'] }, Sequelize => {
|
|
|
18
17
|
return query.apply(this, arguments)
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
22
|
-
|
|
23
20
|
let dialect
|
|
24
21
|
if (this.options && this.options.dialect) {
|
|
25
22
|
dialect = this.options.dialect
|
|
@@ -33,22 +30,15 @@ addHook({ name: 'sequelize', versions: ['>=4'] }, Sequelize => {
|
|
|
33
30
|
result = result[0]
|
|
34
31
|
}
|
|
35
32
|
|
|
36
|
-
|
|
37
|
-
finishCh.publish({ result })
|
|
38
|
-
}, this).apply(this)
|
|
33
|
+
finishCh.runStores({ result }, () => {})
|
|
39
34
|
}
|
|
40
35
|
|
|
41
|
-
return
|
|
42
|
-
startCh.publish({
|
|
43
|
-
sql,
|
|
44
|
-
dialect
|
|
45
|
-
})
|
|
46
|
-
|
|
36
|
+
return startCh.runStores({ sql, dialect }, () => {
|
|
47
37
|
const promise = query.apply(this, arguments)
|
|
48
38
|
promise.then(onFinish, () => { onFinish() })
|
|
49
39
|
|
|
50
40
|
return promise
|
|
51
|
-
}
|
|
41
|
+
})
|
|
52
42
|
}
|
|
53
43
|
})
|
|
54
44
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const BaseAwsSdkPlugin = require('../../base')
|
|
4
|
-
const { parseModelId
|
|
4
|
+
const { parseModelId } = require('./utils')
|
|
5
5
|
|
|
6
6
|
const enabledOperations = new Set(['invokeModel'])
|
|
7
7
|
|
|
@@ -20,44 +20,12 @@ class BedrockRuntime extends BaseAwsSdkPlugin {
|
|
|
20
20
|
generateTags (params, operation, response) {
|
|
21
21
|
const { modelProvider, modelName } = parseModelId(params.modelId)
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return tags
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function buildTagsFromParams (requestParams, textAndResponseReason, modelProvider, modelName, operation) {
|
|
33
|
-
const tags = {}
|
|
34
|
-
|
|
35
|
-
// add request tags
|
|
36
|
-
tags['resource.name'] = operation
|
|
37
|
-
tags['aws.bedrock.request.model'] = modelName
|
|
38
|
-
tags['aws.bedrock.request.model_provider'] = modelProvider.toLowerCase()
|
|
39
|
-
tags['aws.bedrock.request.prompt'] = requestParams.prompt
|
|
40
|
-
tags['aws.bedrock.request.temperature'] = requestParams.temperature
|
|
41
|
-
tags['aws.bedrock.request.top_p'] = requestParams.topP
|
|
42
|
-
tags['aws.bedrock.request.top_k'] = requestParams.topK
|
|
43
|
-
tags['aws.bedrock.request.max_tokens'] = requestParams.maxTokens
|
|
44
|
-
tags['aws.bedrock.request.stop_sequences'] = requestParams.stopSequences
|
|
45
|
-
tags['aws.bedrock.request.input_type'] = requestParams.inputType
|
|
46
|
-
tags['aws.bedrock.request.truncate'] = requestParams.truncate
|
|
47
|
-
tags['aws.bedrock.request.stream'] = requestParams.stream
|
|
48
|
-
tags['aws.bedrock.request.n'] = requestParams.n
|
|
49
|
-
|
|
50
|
-
// add response tags
|
|
51
|
-
if (modelName.includes('embed')) {
|
|
52
|
-
tags['aws.bedrock.response.embedding_length'] = textAndResponseReason.message.length
|
|
53
|
-
}
|
|
54
|
-
if (textAndResponseReason.choiceId) {
|
|
55
|
-
tags['aws.bedrock.response.choices.id'] = textAndResponseReason.choiceId
|
|
23
|
+
return {
|
|
24
|
+
'resource.name': operation,
|
|
25
|
+
'aws.bedrock.request.model': modelName,
|
|
26
|
+
'aws.bedrock.request.model_provider': modelProvider.toLowerCase()
|
|
27
|
+
}
|
|
56
28
|
}
|
|
57
|
-
tags['aws.bedrock.response.choices.text'] = textAndResponseReason.message
|
|
58
|
-
tags['aws.bedrock.response.choices.finish_reason'] = textAndResponseReason.finishReason
|
|
59
|
-
|
|
60
|
-
return tags
|
|
61
29
|
}
|
|
62
30
|
|
|
63
31
|
module.exports = BedrockRuntime
|