dd-trace 5.61.1 → 5.63.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/README.md +0 -5
- package/package.json +2 -2
- package/packages/datadog-instrumentations/src/ai.js +140 -0
- package/packages/datadog-instrumentations/src/apollo-server.js +50 -8
- package/packages/datadog-instrumentations/src/aws-sdk.js +49 -60
- package/packages/datadog-instrumentations/src/couchbase.js +102 -65
- package/packages/datadog-instrumentations/src/fastify.js +61 -55
- package/packages/datadog-instrumentations/src/graphql.js +90 -122
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +2 -22
- package/packages/datadog-instrumentations/src/hono.js +11 -8
- package/packages/datadog-instrumentations/src/http2/server.js +14 -20
- package/packages/datadog-instrumentations/src/knex.js +15 -17
- package/packages/datadog-instrumentations/src/microgateway-core.js +16 -15
- package/packages/datadog-instrumentations/src/mongodb-core.js +35 -32
- package/packages/datadog-instrumentations/src/mongodb.js +9 -13
- package/packages/datadog-instrumentations/src/mongoose.js +25 -29
- package/packages/datadog-instrumentations/src/next.js +4 -8
- package/packages/datadog-instrumentations/src/openai.js +0 -2
- package/packages/datadog-instrumentations/src/oracledb.js +39 -33
- package/packages/datadog-instrumentations/src/pg.js +38 -48
- package/packages/datadog-plugin-aerospike/src/index.js +11 -11
- package/packages/datadog-plugin-ai/src/index.js +17 -0
- package/packages/datadog-plugin-ai/src/tracing.js +33 -0
- package/packages/datadog-plugin-ai/src/utils.js +28 -0
- package/packages/datadog-plugin-amqp10/src/consumer.js +2 -2
- package/packages/datadog-plugin-amqp10/src/index.js +1 -1
- package/packages/datadog-plugin-amqp10/src/producer.js +3 -3
- package/packages/datadog-plugin-amqplib/src/client.js +3 -3
- package/packages/datadog-plugin-amqplib/src/consumer.js +2 -2
- package/packages/datadog-plugin-amqplib/src/index.js +1 -1
- package/packages/datadog-plugin-amqplib/src/producer.js +2 -2
- package/packages/datadog-plugin-apollo/src/gateway/execute.js +2 -4
- package/packages/datadog-plugin-apollo/src/gateway/fetch.js +2 -4
- package/packages/datadog-plugin-apollo/src/gateway/index.js +1 -1
- package/packages/datadog-plugin-apollo/src/gateway/plan.js +2 -4
- package/packages/datadog-plugin-apollo/src/gateway/postprocessing.js +2 -4
- package/packages/datadog-plugin-apollo/src/gateway/request.js +2 -4
- package/packages/datadog-plugin-apollo/src/gateway/validate.js +2 -4
- package/packages/datadog-plugin-apollo/src/index.js +1 -1
- package/packages/datadog-plugin-avsc/src/index.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/base.js +70 -46
- package/packages/datadog-plugin-aws-sdk/src/index.js +1 -3
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/index.js +1 -3
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +3 -3
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +22 -20
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +3 -3
- package/packages/datadog-plugin-aws-sdk/src/services/sfn.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +3 -3
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +17 -15
- package/packages/datadog-plugin-aws-sdk/src/services/states.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +1 -1
- package/packages/datadog-plugin-azure-functions/src/index.js +5 -5
- package/packages/datadog-plugin-azure-service-bus/src/index.js +1 -1
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +2 -2
- package/packages/datadog-plugin-bunyan/src/index.js +3 -5
- package/packages/datadog-plugin-cassandra-driver/src/index.js +3 -3
- package/packages/datadog-plugin-child_process/src/index.js +2 -2
- package/packages/datadog-plugin-confluentinc-kafka-javascript/src/batch-consumer.js +1 -3
- package/packages/datadog-plugin-confluentinc-kafka-javascript/src/consumer.js +1 -3
- package/packages/datadog-plugin-confluentinc-kafka-javascript/src/index.js +1 -1
- package/packages/datadog-plugin-confluentinc-kafka-javascript/src/producer.js +1 -3
- package/packages/datadog-plugin-connect/src/index.js +1 -3
- package/packages/datadog-plugin-couchbase/src/index.js +39 -19
- package/packages/datadog-plugin-cucumber/src/index.js +1 -3
- package/packages/datadog-plugin-cypress/src/index.js +1 -3
- package/packages/datadog-plugin-dd-trace-api/src/index.js +1 -3
- package/packages/datadog-plugin-dns/src/index.js +1 -1
- package/packages/datadog-plugin-dns/src/lookup.js +2 -2
- package/packages/datadog-plugin-dns/src/lookup_service.js +2 -2
- package/packages/datadog-plugin-dns/src/resolve.js +2 -2
- package/packages/datadog-plugin-dns/src/reverse.js +2 -2
- package/packages/datadog-plugin-elasticsearch/src/index.js +1 -1
- package/packages/datadog-plugin-express/src/code_origin.js +1 -3
- package/packages/datadog-plugin-express/src/index.js +1 -1
- package/packages/datadog-plugin-express/src/tracing.js +1 -3
- package/packages/datadog-plugin-fastify/src/code_origin.js +1 -3
- package/packages/datadog-plugin-fastify/src/index.js +1 -1
- package/packages/datadog-plugin-fastify/src/tracing.js +18 -3
- package/packages/datadog-plugin-fetch/src/index.js +2 -2
- package/packages/datadog-plugin-find-my-way/src/index.js +1 -3
- package/packages/datadog-plugin-fs/src/index.js +2 -2
- package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +3 -3
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -2
- package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +1 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +2 -2
- package/packages/datadog-plugin-google-cloud-vertexai/src/index.js +1 -1
- package/packages/datadog-plugin-google-cloud-vertexai/src/tracing.js +2 -4
- package/packages/datadog-plugin-graphql/src/execute.js +16 -9
- package/packages/datadog-plugin-graphql/src/index.js +1 -1
- package/packages/datadog-plugin-graphql/src/parse.js +12 -7
- package/packages/datadog-plugin-graphql/src/resolve.js +50 -16
- package/packages/datadog-plugin-graphql/src/validate.js +13 -7
- package/packages/datadog-plugin-grpc/src/client.js +4 -4
- package/packages/datadog-plugin-grpc/src/index.js +1 -1
- package/packages/datadog-plugin-grpc/src/server.js +3 -3
- package/packages/datadog-plugin-hapi/src/index.js +1 -3
- package/packages/datadog-plugin-hono/src/index.js +1 -3
- package/packages/datadog-plugin-http/src/client.js +2 -2
- package/packages/datadog-plugin-http/src/index.js +1 -1
- package/packages/datadog-plugin-http/src/server.js +3 -7
- package/packages/datadog-plugin-http2/src/client.js +2 -2
- package/packages/datadog-plugin-http2/src/index.js +1 -1
- package/packages/datadog-plugin-http2/src/server.js +22 -11
- package/packages/datadog-plugin-ioredis/src/index.js +1 -3
- package/packages/datadog-plugin-iovalkey/src/index.js +2 -4
- package/packages/datadog-plugin-jest/src/index.js +1 -3
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +2 -2
- package/packages/datadog-plugin-kafkajs/src/consumer.js +2 -2
- package/packages/datadog-plugin-kafkajs/src/index.js +1 -1
- package/packages/datadog-plugin-kafkajs/src/producer.js +3 -3
- package/packages/datadog-plugin-koa/src/index.js +1 -3
- package/packages/datadog-plugin-langchain/src/index.js +2 -2
- package/packages/datadog-plugin-langchain/src/tracing.js +30 -48
- package/packages/datadog-plugin-mariadb/src/index.js +2 -2
- package/packages/datadog-plugin-memcached/src/index.js +1 -1
- package/packages/datadog-plugin-microgateway-core/src/index.js +4 -4
- package/packages/datadog-plugin-mocha/src/index.js +1 -3
- package/packages/datadog-plugin-moleculer/src/client.js +2 -2
- package/packages/datadog-plugin-moleculer/src/index.js +1 -1
- package/packages/datadog-plugin-moleculer/src/server.js +2 -2
- package/packages/datadog-plugin-mongodb-core/src/index.js +9 -5
- package/packages/datadog-plugin-mongoose/src/index.js +20 -0
- package/packages/datadog-plugin-mysql/src/index.js +2 -2
- package/packages/datadog-plugin-mysql2/src/index.js +1 -1
- package/packages/datadog-plugin-net/src/index.js +1 -1
- package/packages/datadog-plugin-net/src/ipc.js +2 -2
- package/packages/datadog-plugin-net/src/tcp.js +2 -2
- package/packages/datadog-plugin-next/src/index.js +1 -3
- package/packages/datadog-plugin-nyc/src/index.js +1 -3
- package/packages/datadog-plugin-openai/src/index.js +1 -1
- package/packages/datadog-plugin-openai/src/tracing.js +7 -411
- package/packages/datadog-plugin-opensearch/src/index.js +1 -3
- package/packages/datadog-plugin-oracledb/src/index.js +9 -5
- package/packages/datadog-plugin-pg/src/index.js +8 -5
- package/packages/datadog-plugin-pino/src/index.js +3 -5
- package/packages/datadog-plugin-playwright/src/index.js +1 -3
- package/packages/datadog-plugin-prisma/src/client.js +4 -6
- package/packages/datadog-plugin-prisma/src/engine.js +3 -3
- package/packages/datadog-plugin-prisma/src/index.js +1 -1
- package/packages/datadog-plugin-protobufjs/src/index.js +2 -6
- package/packages/datadog-plugin-redis/src/index.js +2 -2
- package/packages/datadog-plugin-restify/src/index.js +1 -3
- package/packages/datadog-plugin-rhea/src/consumer.js +1 -1
- package/packages/datadog-plugin-rhea/src/index.js +1 -1
- package/packages/datadog-plugin-rhea/src/producer.js +2 -2
- package/packages/datadog-plugin-router/src/index.js +1 -3
- package/packages/datadog-plugin-selenium/src/index.js +1 -3
- package/packages/datadog-plugin-sharedb/src/index.js +1 -1
- package/packages/datadog-plugin-tedious/src/index.js +3 -3
- package/packages/datadog-plugin-undici/src/index.js +2 -4
- package/packages/datadog-plugin-vitest/src/index.js +1 -3
- package/packages/datadog-plugin-web/src/index.js +1 -3
- package/packages/datadog-plugin-winston/src/index.js +3 -5
- package/packages/dd-trace/src/appsec/channels.js +1 -0
- package/packages/dd-trace/src/appsec/graphql.js +14 -12
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +14 -7
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +4 -4
- package/packages/dd-trace/src/appsec/recommended.json +271 -2
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +1 -1
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +1 -3
- package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +1 -3
- package/packages/dd-trace/src/config.js +1 -1
- package/packages/dd-trace/src/datastreams/checkpointer.js +23 -2
- package/packages/dd-trace/src/datastreams/processor.js +4 -3
- package/packages/dd-trace/src/guardrails/telemetry.js +18 -2
- package/packages/dd-trace/src/llmobs/plugins/ai/index.js +351 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +179 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +30 -50
- package/packages/dd-trace/src/llmobs/plugins/openai.js +3 -5
- package/packages/dd-trace/src/llmobs/plugins/vertexai.js +3 -5
- package/packages/dd-trace/src/llmobs/writers/base.js +3 -2
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +25 -2
- package/packages/dd-trace/src/opentracing/span_context.js +4 -0
- package/packages/dd-trace/src/plugin_manager.js +8 -4
- package/packages/dd-trace/src/plugins/apollo.js +3 -3
- package/packages/dd-trace/src/plugins/cache.js +1 -1
- package/packages/dd-trace/src/plugins/client.js +3 -3
- package/packages/dd-trace/src/plugins/consumer.js +3 -3
- package/packages/dd-trace/src/plugins/database.js +2 -2
- package/packages/dd-trace/src/plugins/index.js +2 -0
- package/packages/dd-trace/src/plugins/log_plugin.js +1 -5
- package/packages/dd-trace/src/plugins/outbound.js +1 -1
- package/packages/dd-trace/src/plugins/plugin.js +1 -1
- package/packages/dd-trace/src/plugins/producer.js +3 -3
- package/packages/dd-trace/src/plugins/server.js +3 -3
- package/packages/dd-trace/src/plugins/storage.js +1 -1
- package/packages/dd-trace/src/plugins/tracing.js +24 -6
- package/packages/dd-trace/src/plugins/util/ci.js +11 -7
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +15 -19
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +44 -3
- package/packages/dd-trace/src/plugins/util/tags.js +2 -0
- package/packages/dd-trace/src/plugins/util/web.js +26 -7
- package/packages/dd-trace/src/profiling/config.js +2 -0
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +2 -21
- package/packages/dd-trace/src/profiling/libuv-size.js +49 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns.js +2 -6
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookup.js +1 -3
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookupservice.js +1 -3
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_resolve.js +1 -3
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_reverse.js +1 -3
- package/packages/dd-trace/src/profiling/profilers/event_plugins/event.js +24 -23
- package/packages/dd-trace/src/profiling/profilers/event_plugins/fs.js +3 -9
- package/packages/dd-trace/src/profiling/profilers/event_plugins/net.js +3 -9
- package/packages/dd-trace/src/profiling/profilers/events.js +83 -64
- package/packages/dd-trace/src/profiling/profilers/poisson.js +105 -0
- package/packages/dd-trace/src/profiling/profilers/wall.js +3 -3
- package/packages/dd-trace/src/remote_config/manager.js +1 -1
- package/packages/dd-trace/src/supported-configurations.json +2 -0
- package/packages/dd-trace/src/tracer_metadata.js +1 -1
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const BaseLLMObsPlugin = require('../base')
|
|
4
|
+
const { getModelProvider } = require('../../../../../datadog-plugin-ai/src/utils')
|
|
5
|
+
|
|
6
|
+
const { channel } = require('dc-polyfill')
|
|
7
|
+
|
|
8
|
+
const toolCreationCh = channel('dd-trace:vercel-ai:tool')
|
|
9
|
+
const setAttributesCh = channel('dd-trace:vercel-ai:span:setAttributes')
|
|
10
|
+
|
|
11
|
+
const { MODEL_NAME, MODEL_PROVIDER, NAME } = require('../../constants/tags')
|
|
12
|
+
const {
|
|
13
|
+
getSpanTags,
|
|
14
|
+
getOperation,
|
|
15
|
+
getUsage,
|
|
16
|
+
getJsonStringValue,
|
|
17
|
+
getModelMetadata,
|
|
18
|
+
getGenerationMetadata,
|
|
19
|
+
getToolNameFromTags,
|
|
20
|
+
getToolCallResultContent
|
|
21
|
+
} = require('./util')
|
|
22
|
+
|
|
23
|
+
const SPAN_NAME_TO_KIND_MAPPING = {
|
|
24
|
+
// embeddings
|
|
25
|
+
embed: 'workflow',
|
|
26
|
+
embedMany: 'workflow',
|
|
27
|
+
doEmbed: 'embedding',
|
|
28
|
+
// object generation
|
|
29
|
+
generateObject: 'workflow',
|
|
30
|
+
streamObject: 'workflow',
|
|
31
|
+
// text generation
|
|
32
|
+
generateText: 'workflow',
|
|
33
|
+
streamText: 'workflow',
|
|
34
|
+
// llm operations
|
|
35
|
+
doGenerate: 'llm',
|
|
36
|
+
doStream: 'llm',
|
|
37
|
+
// tools
|
|
38
|
+
toolCall: 'tool'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
class VercelAILLMObsPlugin extends BaseLLMObsPlugin {
|
|
42
|
+
static id = 'ai'
|
|
43
|
+
static integration = 'ai'
|
|
44
|
+
static prefix = 'tracing:dd-trace:vercel-ai'
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The available tools within the runtime scope of this integration.
|
|
48
|
+
* This essentially acts as a global registry for all tools made through the Vercel AI SDK.
|
|
49
|
+
* @type {Set<Record<string, any>>}
|
|
50
|
+
*/
|
|
51
|
+
#availableTools
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* A mapping of tool call IDs to tool names.
|
|
55
|
+
* This is used to map the tool call ID to the tool name for the output message.
|
|
56
|
+
* @type {Record<string, string>}
|
|
57
|
+
*/
|
|
58
|
+
#toolCallIdsToName
|
|
59
|
+
|
|
60
|
+
constructor (...args) {
|
|
61
|
+
super(...args)
|
|
62
|
+
|
|
63
|
+
this.#toolCallIdsToName = {}
|
|
64
|
+
this.#availableTools = new Set()
|
|
65
|
+
toolCreationCh.subscribe(toolArgs => {
|
|
66
|
+
this.#availableTools.add(toolArgs)
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
setAttributesCh.subscribe(({ ctx, attributes }) => {
|
|
70
|
+
Object.assign(ctx.attributes, attributes)
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Does a best-effort attempt to find the right tool name for the given tool description.
|
|
76
|
+
* This is because the Vercel AI SDK does not tag tools by name properly, but
|
|
77
|
+
* rather by the index they were passed in. Tool names appear nowhere in the span tags.
|
|
78
|
+
*
|
|
79
|
+
* We use the tool description as the next best identifier for a tool.
|
|
80
|
+
*
|
|
81
|
+
* @param {string} toolDescription
|
|
82
|
+
* @returns {string}
|
|
83
|
+
*/
|
|
84
|
+
findToolName (toolDescription) {
|
|
85
|
+
for (const availableTool of this.#availableTools) {
|
|
86
|
+
const description = availableTool.description
|
|
87
|
+
if (description === toolDescription) {
|
|
88
|
+
return availableTool.id
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
getLLMObsSpanRegisterOptions (ctx) {
|
|
94
|
+
const span = ctx.currentStore?.span
|
|
95
|
+
const operation = getOperation(span)
|
|
96
|
+
const kind = SPAN_NAME_TO_KIND_MAPPING[operation]
|
|
97
|
+
if (!kind) return
|
|
98
|
+
|
|
99
|
+
return { kind, name: operation }
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
setLLMObsTags (ctx) {
|
|
103
|
+
const span = ctx.currentStore?.span
|
|
104
|
+
if (!span) return
|
|
105
|
+
|
|
106
|
+
const operation = getOperation(span)
|
|
107
|
+
const kind = SPAN_NAME_TO_KIND_MAPPING[operation]
|
|
108
|
+
if (!kind) return
|
|
109
|
+
|
|
110
|
+
const tags = getSpanTags(ctx)
|
|
111
|
+
|
|
112
|
+
if (['embedding', 'llm'].includes(kind)) {
|
|
113
|
+
this._tagger._setTag(span, MODEL_NAME, tags['ai.model.id'])
|
|
114
|
+
this._tagger._setTag(span, MODEL_PROVIDER, getModelProvider(tags))
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
switch (operation) {
|
|
118
|
+
case 'embed':
|
|
119
|
+
case 'embedMany':
|
|
120
|
+
this.setEmbeddingWorkflowTags(span, tags)
|
|
121
|
+
break
|
|
122
|
+
case 'doEmbed':
|
|
123
|
+
this.setEmbeddingTags(span, tags)
|
|
124
|
+
break
|
|
125
|
+
case 'generateObject':
|
|
126
|
+
case 'streamObject':
|
|
127
|
+
this.setObjectGenerationTags(span, tags)
|
|
128
|
+
break
|
|
129
|
+
case 'generateText':
|
|
130
|
+
case 'streamText':
|
|
131
|
+
this.setTextGenerationTags(span, tags)
|
|
132
|
+
break
|
|
133
|
+
case 'doGenerate':
|
|
134
|
+
case 'doStream':
|
|
135
|
+
this.setLLMOperationTags(span, tags)
|
|
136
|
+
break
|
|
137
|
+
case 'toolCall':
|
|
138
|
+
this.setToolTags(span, tags)
|
|
139
|
+
break
|
|
140
|
+
default:
|
|
141
|
+
break
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
setEmbeddingWorkflowTags (span, tags) {
|
|
146
|
+
const inputs = tags['ai.value'] ?? tags['ai.values']
|
|
147
|
+
const parsedInputs = Array.isArray(inputs)
|
|
148
|
+
? inputs.map(input => getJsonStringValue(input, ''))
|
|
149
|
+
: getJsonStringValue(inputs, '')
|
|
150
|
+
|
|
151
|
+
const embeddingsOutput = tags['ai.embedding'] ?? tags['ai.embeddings']
|
|
152
|
+
const isSingleEmbedding = !Array.isArray(embeddingsOutput)
|
|
153
|
+
const numberOfEmbeddings = isSingleEmbedding ? 1 : embeddingsOutput.length
|
|
154
|
+
const embeddingsLength = getJsonStringValue(isSingleEmbedding ? embeddingsOutput : embeddingsOutput?.[0], []).length
|
|
155
|
+
const output = `[${numberOfEmbeddings} embedding(s) returned with size ${embeddingsLength}]`
|
|
156
|
+
|
|
157
|
+
this._tagger.tagTextIO(span, parsedInputs, output)
|
|
158
|
+
|
|
159
|
+
const metadata = getGenerationMetadata(tags)
|
|
160
|
+
this._tagger.tagMetadata(span, metadata)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
setEmbeddingTags (span, tags) {
|
|
164
|
+
const inputs = tags['ai.values']
|
|
165
|
+
if (!Array.isArray(inputs)) return
|
|
166
|
+
|
|
167
|
+
const parsedInputs = inputs.map(input => getJsonStringValue(input, ''))
|
|
168
|
+
|
|
169
|
+
const embeddingsOutput = tags['ai.embeddings']
|
|
170
|
+
const numberOfEmbeddings = embeddingsOutput?.length
|
|
171
|
+
const embeddingsLength = getJsonStringValue(embeddingsOutput?.[0], []).length
|
|
172
|
+
const output = `[${numberOfEmbeddings} embedding(s) returned with size ${embeddingsLength}]`
|
|
173
|
+
|
|
174
|
+
this._tagger.tagEmbeddingIO(span, parsedInputs, output)
|
|
175
|
+
|
|
176
|
+
const usage = tags['ai.usage.tokens']
|
|
177
|
+
this._tagger.tagMetrics(span, {
|
|
178
|
+
inputTokens: usage,
|
|
179
|
+
totalTokens: usage
|
|
180
|
+
})
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
setObjectGenerationTags (span, tags) {
|
|
184
|
+
const promptInfo = getJsonStringValue(tags['ai.prompt'], {})
|
|
185
|
+
const lastUserPrompt =
|
|
186
|
+
promptInfo.prompt ??
|
|
187
|
+
promptInfo.messages.reverse().find(message => message.role === 'user')?.content
|
|
188
|
+
const prompt = Array.isArray(lastUserPrompt) ? lastUserPrompt.map(part => part.text ?? '').join('') : lastUserPrompt
|
|
189
|
+
|
|
190
|
+
const output = tags['ai.response.object']
|
|
191
|
+
|
|
192
|
+
this._tagger.tagTextIO(span, prompt, output)
|
|
193
|
+
|
|
194
|
+
const metadata = getGenerationMetadata(tags) ?? {}
|
|
195
|
+
metadata.schema = getJsonStringValue(tags['ai.schema'], {})
|
|
196
|
+
this._tagger.tagMetadata(span, metadata)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
setTextGenerationTags (span, tags) {
|
|
200
|
+
const promptInfo = getJsonStringValue(tags['ai.prompt'], {})
|
|
201
|
+
const lastUserPrompt =
|
|
202
|
+
promptInfo.prompt ??
|
|
203
|
+
promptInfo.messages.reverse().find(message => message.role === 'user')?.content
|
|
204
|
+
const prompt = Array.isArray(lastUserPrompt) ? lastUserPrompt.map(part => part.text ?? '').join('') : lastUserPrompt
|
|
205
|
+
|
|
206
|
+
const output = tags['ai.response.text']
|
|
207
|
+
|
|
208
|
+
this._tagger.tagTextIO(span, prompt, output)
|
|
209
|
+
|
|
210
|
+
const metadata = getGenerationMetadata(tags)
|
|
211
|
+
this._tagger.tagMetadata(span, metadata)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
setLLMOperationTags (span, tags) {
|
|
215
|
+
const toolsForModel = tags['ai.prompt.tools']?.map(getJsonStringValue)
|
|
216
|
+
|
|
217
|
+
const inputMessages = getJsonStringValue(tags['ai.prompt.messages'], [])
|
|
218
|
+
const parsedInputMessages = []
|
|
219
|
+
for (const message of inputMessages) {
|
|
220
|
+
const formattedMessages = this.formatMessage(message, toolsForModel)
|
|
221
|
+
parsedInputMessages.push(...formattedMessages)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const outputMessage = this.formatOutputMessage(tags, toolsForModel)
|
|
225
|
+
|
|
226
|
+
this._tagger.tagLLMIO(span, parsedInputMessages, outputMessage)
|
|
227
|
+
|
|
228
|
+
const metadata = getModelMetadata(tags)
|
|
229
|
+
this._tagger.tagMetadata(span, metadata)
|
|
230
|
+
|
|
231
|
+
const usage = getUsage(tags)
|
|
232
|
+
this._tagger.tagMetrics(span, usage)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
setToolTags (span, tags) {
|
|
236
|
+
const toolCallId = tags['ai.toolCall.id']
|
|
237
|
+
const name = getToolNameFromTags(tags) ?? this.#toolCallIdsToName[toolCallId]
|
|
238
|
+
if (name) this._tagger._setTag(span, NAME, name)
|
|
239
|
+
|
|
240
|
+
const input = tags['ai.toolCall.args']
|
|
241
|
+
const output = tags['ai.toolCall.result']
|
|
242
|
+
|
|
243
|
+
this._tagger.tagTextIO(span, input, output)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
formatOutputMessage (tags, toolsForModel) {
|
|
247
|
+
const outputMessageText = tags['ai.response.text'] ?? tags['ai.response.object']
|
|
248
|
+
const outputMessageToolCalls = getJsonStringValue(tags['ai.response.toolCalls'], [])
|
|
249
|
+
|
|
250
|
+
const formattedToolCalls = []
|
|
251
|
+
for (const toolCall of outputMessageToolCalls) {
|
|
252
|
+
const toolCallArgs = getJsonStringValue(toolCall.args, {})
|
|
253
|
+
const toolDescription = toolsForModel?.find(tool => toolCall.toolName === tool.name)?.description
|
|
254
|
+
const name = this.findToolName(toolDescription)
|
|
255
|
+
this.#toolCallIdsToName[toolCall.toolCallId] = name
|
|
256
|
+
|
|
257
|
+
formattedToolCalls.push({
|
|
258
|
+
arguments: toolCallArgs,
|
|
259
|
+
name,
|
|
260
|
+
toolId: toolCall.toolCallId,
|
|
261
|
+
type: 'function'
|
|
262
|
+
})
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return {
|
|
266
|
+
role: 'assistant',
|
|
267
|
+
content: outputMessageText,
|
|
268
|
+
toolCalls: formattedToolCalls
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Returns a list of formatted messages from a message object.
|
|
274
|
+
* Most of these will just be one entry, but in the case of a "tool" role,
|
|
275
|
+
* it is possible to have multiple tool call results in a single message that we
|
|
276
|
+
* need to split into multiple messages.
|
|
277
|
+
*
|
|
278
|
+
* @param {*} message
|
|
279
|
+
* @param {*} toolsForModel
|
|
280
|
+
* @returns {Array<{role: string, content: string, toolId?: string,
|
|
281
|
+
* toolCalls?: Array<{arguments: string, name: string, toolId: string, type: string}>}>}
|
|
282
|
+
*/
|
|
283
|
+
formatMessage (message, toolsForModel) {
|
|
284
|
+
const { role, content } = message
|
|
285
|
+
|
|
286
|
+
if (role === 'system') {
|
|
287
|
+
return [{ role, content }]
|
|
288
|
+
} else if (role === 'user') {
|
|
289
|
+
let finalContent = ''
|
|
290
|
+
for (const part of content) {
|
|
291
|
+
const { type } = part
|
|
292
|
+
if (type === 'text') {
|
|
293
|
+
finalContent += part.text
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return [{ role, content: finalContent }]
|
|
298
|
+
} else if (role === 'assistant') {
|
|
299
|
+
const toolCalls = []
|
|
300
|
+
let finalContent = ''
|
|
301
|
+
|
|
302
|
+
for (const part of content) {
|
|
303
|
+
const { type } = part
|
|
304
|
+
// TODO(sabrenner): do we want to include reasoning?
|
|
305
|
+
if (['text', 'reasoning', 'redacted-reasoning'].includes(type)) {
|
|
306
|
+
finalContent += part.text ?? part.data
|
|
307
|
+
} else if (type === 'tool-call') {
|
|
308
|
+
const toolDescription = toolsForModel?.find(tool => part.toolName === tool.name)?.description
|
|
309
|
+
const name = this.findToolName(toolDescription)
|
|
310
|
+
|
|
311
|
+
toolCalls.push({
|
|
312
|
+
arguments: part.args,
|
|
313
|
+
name,
|
|
314
|
+
toolId: part.toolCallId,
|
|
315
|
+
type: 'function'
|
|
316
|
+
})
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
const finalMessage = {
|
|
321
|
+
role,
|
|
322
|
+
content: finalContent
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (toolCalls.length) {
|
|
326
|
+
finalMessage.toolCalls = toolCalls.length ? toolCalls : undefined
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return [finalMessage]
|
|
330
|
+
} else if (role === 'tool') {
|
|
331
|
+
const finalMessages = []
|
|
332
|
+
for (const part of content) {
|
|
333
|
+
if (part.type === 'tool-result') {
|
|
334
|
+
const safeResult = getToolCallResultContent(part)
|
|
335
|
+
|
|
336
|
+
finalMessages.push({
|
|
337
|
+
role,
|
|
338
|
+
content: safeResult,
|
|
339
|
+
toolId: part.toolCallId
|
|
340
|
+
})
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return finalMessages
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return []
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
module.exports = VercelAILLMObsPlugin
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const MODEL_METADATA_KEYS = new Set([
|
|
4
|
+
'frequency_penalty',
|
|
5
|
+
'max_tokens',
|
|
6
|
+
'presence_penalty',
|
|
7
|
+
'temperature',
|
|
8
|
+
'top_p',
|
|
9
|
+
'top_k',
|
|
10
|
+
'stop_sequences'
|
|
11
|
+
])
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Get the span tags from the context (either the attributes or the span tags).
|
|
15
|
+
*
|
|
16
|
+
* @param {Record<string, any>} ctx
|
|
17
|
+
* @returns {Record<string, any>}
|
|
18
|
+
*/
|
|
19
|
+
function getSpanTags (ctx) {
|
|
20
|
+
const span = ctx.currentStore?.span
|
|
21
|
+
const carrier = ctx.attributes ?? span?.context()._tags ?? {}
|
|
22
|
+
return carrier
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get the operation name from the span name
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* span._name = 'ai.generateText'
|
|
30
|
+
* getOperation(span) // 'generateText'
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* span._name = 'ai.generateText.doGenerate'
|
|
34
|
+
* getOperation(span) // 'doGenerate'
|
|
35
|
+
*
|
|
36
|
+
* @param {import('../../../opentracing/span')} span
|
|
37
|
+
* @returns {string}
|
|
38
|
+
*/
|
|
39
|
+
function getOperation (span) {
|
|
40
|
+
const name = span._name
|
|
41
|
+
if (!name) return
|
|
42
|
+
|
|
43
|
+
return name.split('.').pop()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get the LLM token usage from the span tags
|
|
48
|
+
* @param {Record<string, string>} tags
|
|
49
|
+
* @returns {{inputTokens: number, outputTokens: number, totalTokens: number}}
|
|
50
|
+
*/
|
|
51
|
+
function getUsage (tags) {
|
|
52
|
+
const usage = {}
|
|
53
|
+
const inputTokens = tags['ai.usage.promptTokens']
|
|
54
|
+
const outputTokens = tags['ai.usage.completionTokens']
|
|
55
|
+
|
|
56
|
+
if (inputTokens != null) usage.inputTokens = inputTokens
|
|
57
|
+
if (outputTokens != null) usage.outputTokens = outputTokens
|
|
58
|
+
|
|
59
|
+
const totalTokens = inputTokens + outputTokens
|
|
60
|
+
if (!Number.isNaN(totalTokens)) usage.totalTokens = totalTokens
|
|
61
|
+
|
|
62
|
+
return usage
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Safely JSON parses a string value with a default fallback
|
|
67
|
+
* @param {string} str
|
|
68
|
+
* @param {any} defaultValue
|
|
69
|
+
* @returns {Record<string, any> | string | Array<any>}
|
|
70
|
+
*/
|
|
71
|
+
function getJsonStringValue (str, defaultValue) {
|
|
72
|
+
let maybeValue = defaultValue
|
|
73
|
+
try {
|
|
74
|
+
maybeValue = JSON.parse(str)
|
|
75
|
+
} catch {
|
|
76
|
+
// do nothing
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return maybeValue
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Get the model metadata from the span tags (top_p, top_k, temperature, etc.)
|
|
84
|
+
* @param {import('../../../opentracing/span')} span
|
|
85
|
+
* @returns {Record<string, string> | null}
|
|
86
|
+
*/
|
|
87
|
+
function getModelMetadata (tags) {
|
|
88
|
+
const modelMetadata = {}
|
|
89
|
+
for (const metadata of MODEL_METADATA_KEYS) {
|
|
90
|
+
const metadataTagKey = `gen_ai.request.${metadata}`
|
|
91
|
+
const metadataValue = tags[metadataTagKey]
|
|
92
|
+
if (metadataValue) {
|
|
93
|
+
modelMetadata[metadata] = metadataValue
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return Object.keys(modelMetadata).length ? modelMetadata : null
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Get the generation metadata from the span tags (maxSteps, maxRetries, etc.)
|
|
102
|
+
* @param {Record<string, string>} tags
|
|
103
|
+
* @returns {Record<string, string> | null}
|
|
104
|
+
*/
|
|
105
|
+
function getGenerationMetadata (tags) {
|
|
106
|
+
const metadata = {}
|
|
107
|
+
|
|
108
|
+
for (const tag of Object.keys(tags)) {
|
|
109
|
+
if (!tag.startsWith('ai.settings')) continue
|
|
110
|
+
|
|
111
|
+
const settingKey = tag.split('.').pop()
|
|
112
|
+
const transformedKey = settingKey.replaceAll(/[A-Z]/g, letter => '_' + letter.toLowerCase())
|
|
113
|
+
if (MODEL_METADATA_KEYS.has(transformedKey)) continue
|
|
114
|
+
|
|
115
|
+
const settingValue = tags[tag]
|
|
116
|
+
metadata[settingKey] = settingValue
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return Object.keys(metadata).length ? metadata : null
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Get the tool name from the span tags.
|
|
124
|
+
* If the tool name is a parsable number, or is not found, null is returned.
|
|
125
|
+
* Older versions of the ai sdk would tag the tool name as its index in the tools array.
|
|
126
|
+
*
|
|
127
|
+
* @param {Record<string, string>} tags
|
|
128
|
+
* @returns {string | null}
|
|
129
|
+
*/
|
|
130
|
+
function getToolNameFromTags (tags) {
|
|
131
|
+
const toolName = tags['ai.toolCall.name']
|
|
132
|
+
if (!toolName) return null
|
|
133
|
+
|
|
134
|
+
const parsedToolName = Number.parseInt(toolName)
|
|
135
|
+
if (!Number.isNaN(parsedToolName)) return null
|
|
136
|
+
|
|
137
|
+
return toolName
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Get the content of a tool call result.
|
|
142
|
+
* Version 5 of the ai sdk sets this tag as `content.output`, with a `
|
|
143
|
+
* @param {Record<string, any>} content
|
|
144
|
+
* @returns {string}
|
|
145
|
+
*/
|
|
146
|
+
function getToolCallResultContent (content) {
|
|
147
|
+
const { output, result } = content
|
|
148
|
+
if (output) {
|
|
149
|
+
if (output.type === 'text') {
|
|
150
|
+
return output.value
|
|
151
|
+
} else if (output.type === 'json') {
|
|
152
|
+
return JSON.stringify(output.value)
|
|
153
|
+
}
|
|
154
|
+
return '[Unparsable Tool Result]'
|
|
155
|
+
} else if (result) {
|
|
156
|
+
if (typeof result === 'string') {
|
|
157
|
+
return result
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
return JSON.stringify(result)
|
|
162
|
+
} catch {
|
|
163
|
+
return '[Unparsable Tool Result]'
|
|
164
|
+
}
|
|
165
|
+
} else {
|
|
166
|
+
return '[Unsupported Tool Result]'
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
module.exports = {
|
|
171
|
+
getSpanTags,
|
|
172
|
+
getOperation,
|
|
173
|
+
getUsage,
|
|
174
|
+
getJsonStringValue,
|
|
175
|
+
getModelMetadata,
|
|
176
|
+
getGenerationMetadata,
|
|
177
|
+
getToolNameFromTags,
|
|
178
|
+
getToolCallResultContent
|
|
179
|
+
}
|
|
@@ -25,11 +25,9 @@ const ToolHandler = require('./handlers/tool')
|
|
|
25
25
|
const VectorStoreHandler = require('./handlers/vectorstore')
|
|
26
26
|
|
|
27
27
|
class BaseLangChainLLMObsPlugin extends LLMObsPlugin {
|
|
28
|
-
static
|
|
29
|
-
static
|
|
30
|
-
static
|
|
31
|
-
return 'tracing:apm:langchain:invoke'
|
|
32
|
-
}
|
|
28
|
+
static integration = 'langchain'
|
|
29
|
+
static id = 'langchain'
|
|
30
|
+
static prefix = 'tracing:apm:langchain:invoke'
|
|
33
31
|
|
|
34
32
|
constructor () {
|
|
35
33
|
super(...arguments)
|
|
@@ -150,75 +148,57 @@ class BaseLangChainLLMObsPlugin extends LLMObsPlugin {
|
|
|
150
148
|
}
|
|
151
149
|
|
|
152
150
|
class RunnableSequenceInvokePlugin extends BaseLangChainLLMObsPlugin {
|
|
153
|
-
static
|
|
154
|
-
static
|
|
155
|
-
static
|
|
156
|
-
return 'tracing:orchestrion:@langchain/core:RunnableSequence_invoke'
|
|
157
|
-
}
|
|
151
|
+
static id = 'llmobs_langchain_rs_invoke'
|
|
152
|
+
static lcType = 'chain'
|
|
153
|
+
static prefix = 'tracing:orchestrion:@langchain/core:RunnableSequence_invoke'
|
|
158
154
|
}
|
|
159
155
|
|
|
160
156
|
class RunnableSequenceBatchPlugin extends BaseLangChainLLMObsPlugin {
|
|
161
|
-
static
|
|
162
|
-
static
|
|
163
|
-
static
|
|
164
|
-
return 'tracing:orchestrion:@langchain/core:RunnableSequence_batch'
|
|
165
|
-
}
|
|
157
|
+
static id = 'llmobs_langchain_rs_batch'
|
|
158
|
+
static lcType = 'chain'
|
|
159
|
+
static prefix = 'tracing:orchestrion:@langchain/core:RunnableSequence_batch'
|
|
166
160
|
}
|
|
167
161
|
|
|
168
162
|
class BaseChatModelGeneratePlugin extends BaseLangChainLLMObsPlugin {
|
|
169
|
-
static
|
|
170
|
-
static
|
|
171
|
-
static
|
|
172
|
-
return 'tracing:orchestrion:@langchain/core:BaseChatModel_generate'
|
|
173
|
-
}
|
|
163
|
+
static id = 'llmobs_langchain_chat_model_generate'
|
|
164
|
+
static lcType = 'chat_model'
|
|
165
|
+
static prefix = 'tracing:orchestrion:@langchain/core:BaseChatModel_generate'
|
|
174
166
|
}
|
|
175
167
|
|
|
176
168
|
class BaseLLMGeneratePlugin extends BaseLangChainLLMObsPlugin {
|
|
177
|
-
static
|
|
178
|
-
static
|
|
179
|
-
static
|
|
180
|
-
return 'tracing:orchestrion:@langchain/core:BaseLLM_generate'
|
|
181
|
-
}
|
|
169
|
+
static id = 'llmobs_langchain_llm_generate'
|
|
170
|
+
static lcType = 'llm'
|
|
171
|
+
static prefix = 'tracing:orchestrion:@langchain/core:BaseLLM_generate'
|
|
182
172
|
}
|
|
183
173
|
|
|
184
174
|
class EmbeddingsEmbedQueryPlugin extends BaseLangChainLLMObsPlugin {
|
|
185
|
-
static
|
|
186
|
-
static
|
|
187
|
-
static
|
|
188
|
-
return 'tracing:apm:@langchain/core:Embeddings_embedQuery'
|
|
189
|
-
}
|
|
175
|
+
static id = 'llmobs_langchain_embeddings_embed_query'
|
|
176
|
+
static lcType = 'embedding'
|
|
177
|
+
static prefix = 'tracing:apm:@langchain/core:Embeddings_embedQuery'
|
|
190
178
|
}
|
|
191
179
|
|
|
192
180
|
class EmbeddingsEmbedDocumentsPlugin extends BaseLangChainLLMObsPlugin {
|
|
193
|
-
static
|
|
194
|
-
static
|
|
195
|
-
static
|
|
196
|
-
return 'tracing:apm:@langchain/core:Embeddings_embedDocuments'
|
|
197
|
-
}
|
|
181
|
+
static id = 'llmobs_langchain_embeddings_embed_documents'
|
|
182
|
+
static lcType = 'embedding'
|
|
183
|
+
static prefix = 'tracing:apm:@langchain/core:Embeddings_embedDocuments'
|
|
198
184
|
}
|
|
199
185
|
|
|
200
186
|
class ToolInvokePlugin extends BaseLangChainLLMObsPlugin {
|
|
201
|
-
static
|
|
202
|
-
static
|
|
203
|
-
static
|
|
204
|
-
return 'tracing:orchestrion:@langchain/core:Tool_invoke'
|
|
205
|
-
}
|
|
187
|
+
static id = 'llmobs_langchain_tool_invoke'
|
|
188
|
+
static lcType = 'tool'
|
|
189
|
+
static prefix = 'tracing:orchestrion:@langchain/core:Tool_invoke'
|
|
206
190
|
}
|
|
207
191
|
|
|
208
192
|
class VectorStoreSimilaritySearchPlugin extends BaseLangChainLLMObsPlugin {
|
|
209
|
-
static
|
|
210
|
-
static
|
|
211
|
-
static
|
|
212
|
-
return 'tracing:orchestrion:@langchain/core:VectorStore_similaritySearch'
|
|
213
|
-
}
|
|
193
|
+
static id = 'llmobs_langchain_vectorstore_similarity_search'
|
|
194
|
+
static lcType = 'similarity_search'
|
|
195
|
+
static prefix = 'tracing:orchestrion:@langchain/core:VectorStore_similaritySearch'
|
|
214
196
|
}
|
|
215
197
|
|
|
216
198
|
class VectorStoreSimilaritySearchWithScorePlugin extends BaseLangChainLLMObsPlugin {
|
|
217
|
-
static
|
|
218
|
-
static
|
|
219
|
-
static
|
|
220
|
-
return 'tracing:orchestrion:@langchain/core:VectorStore_similaritySearchWithScore'
|
|
221
|
-
}
|
|
199
|
+
static id = 'llmobs_langchain_vectorstore_similarity_search_with_score'
|
|
200
|
+
static lcType = 'similarity_search'
|
|
201
|
+
static prefix = 'tracing:orchestrion:@langchain/core:VectorStore_similaritySearchWithScore'
|
|
222
202
|
}
|
|
223
203
|
|
|
224
204
|
module.exports = [
|
|
@@ -10,11 +10,9 @@ function isIterable (obj) {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
class OpenAiLLMObsPlugin extends LLMObsPlugin {
|
|
13
|
-
static
|
|
14
|
-
static
|
|
15
|
-
static
|
|
16
|
-
return 'tracing:apm:openai:request'
|
|
17
|
-
}
|
|
13
|
+
static id = 'openai'
|
|
14
|
+
static integration = 'openai'
|
|
15
|
+
static prefix = 'tracing:apm:openai:request'
|
|
18
16
|
|
|
19
17
|
getLLMObsSpanRegisterOptions (ctx) {
|
|
20
18
|
const resource = ctx.methodName
|
|
@@ -7,11 +7,9 @@ const {
|
|
|
7
7
|
} = require('../../../../datadog-plugin-google-cloud-vertexai/src/utils')
|
|
8
8
|
|
|
9
9
|
class VertexAILLMObsPlugin extends LLMObsPlugin {
|
|
10
|
-
static
|
|
11
|
-
static
|
|
12
|
-
static
|
|
13
|
-
return 'tracing:apm:vertexai:request'
|
|
14
|
-
}
|
|
10
|
+
static integration = 'vertexai' // used for llmobs telemetry
|
|
11
|
+
static id = 'vertexai'
|
|
12
|
+
static prefix = 'tracing:apm:vertexai:request'
|
|
15
13
|
|
|
16
14
|
getLLMObsSpanRegisterOptions (ctx) {
|
|
17
15
|
const history = ctx.instance?.historyInternal || []
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const request = require('../../exporters/common/request')
|
|
4
|
+
const { getEnvironmentVariable } = require('../../config-helper')
|
|
4
5
|
const { URL, format } = require('node:url')
|
|
5
6
|
const path = require('node:path')
|
|
6
7
|
|
|
@@ -17,8 +18,8 @@ const { parseResponseAndLog } = require('./util')
|
|
|
17
18
|
|
|
18
19
|
class BaseLLMObsWriter {
|
|
19
20
|
constructor ({ interval, timeout, eventType, config, endpoint, intake }) {
|
|
20
|
-
this._interval = interval
|
|
21
|
-
this._timeout = timeout
|
|
21
|
+
this._interval = interval ?? getEnvironmentVariable('_DD_LLMOBS_FLUSH_INTERVAL') ?? 1000 // 1s
|
|
22
|
+
this._timeout = timeout ?? getEnvironmentVariable('_DD_LLMOBS_TIMEOUT') ?? 5000 // 5s
|
|
22
23
|
this._eventType = eventType
|
|
23
24
|
|
|
24
25
|
this._buffer = []
|