dd-trace 5.104.0 → 5.105.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/LICENSE-3rdparty.csv +90 -102
- package/index.d.ts +82 -3
- package/package.json +15 -15
- package/packages/datadog-core/src/storage.js +1 -1
- package/packages/datadog-instrumentations/src/aerospike.js +1 -1
- package/packages/datadog-instrumentations/src/ai.js +8 -7
- package/packages/datadog-instrumentations/src/aws-sdk.js +13 -0
- package/packages/datadog-instrumentations/src/azure-cosmos.js +7 -0
- package/packages/datadog-instrumentations/src/azure-functions.js +3 -0
- package/packages/datadog-instrumentations/src/cucumber.js +78 -5
- package/packages/datadog-instrumentations/src/dns.js +54 -18
- package/packages/datadog-instrumentations/src/fastify.js +142 -82
- package/packages/datadog-instrumentations/src/graphql.js +188 -62
- package/packages/datadog-instrumentations/src/helpers/ai-messages.js +322 -14
- package/packages/datadog-instrumentations/src/helpers/hooks.js +4 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/openai-ai-guard.js +269 -0
- package/packages/datadog-instrumentations/src/helpers/promise-instrumentor.js +42 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -3
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/azure-cosmos.js +50 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/langgraph.js +4 -2
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +85 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +37 -236
- package/packages/datadog-instrumentations/src/hono.js +54 -3
- package/packages/datadog-instrumentations/src/http/server.js +9 -4
- package/packages/datadog-instrumentations/src/jest/coverage-backfill.js +163 -0
- package/packages/datadog-instrumentations/src/jest.js +360 -150
- package/packages/datadog-instrumentations/src/kafkajs.js +120 -16
- package/packages/datadog-instrumentations/src/mocha/main.js +128 -17
- package/packages/datadog-instrumentations/src/nats.js +182 -0
- package/packages/datadog-instrumentations/src/nyc.js +38 -1
- package/packages/datadog-instrumentations/src/openai.js +33 -18
- package/packages/datadog-instrumentations/src/oracledb.js +6 -1
- package/packages/datadog-instrumentations/src/pino.js +17 -5
- package/packages/datadog-instrumentations/src/playwright.js +515 -292
- package/packages/datadog-instrumentations/src/router.js +76 -32
- package/packages/datadog-instrumentations/src/stripe.js +1 -1
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +1 -1
- package/packages/datadog-plugin-azure-cosmos/src/index.js +144 -0
- package/packages/datadog-plugin-azure-event-hubs/src/producer.js +1 -1
- package/packages/datadog-plugin-azure-functions/src/index.js +5 -2
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +1 -1
- package/packages/datadog-plugin-bunyan/src/index.js +28 -0
- package/packages/datadog-plugin-cucumber/src/index.js +17 -3
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +199 -28
- package/packages/datadog-plugin-cypress/src/support.js +69 -1
- package/packages/datadog-plugin-dns/src/lookup.js +8 -6
- package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +1 -1
- package/packages/datadog-plugin-graphql/src/execute.js +2 -0
- package/packages/datadog-plugin-graphql/src/resolve.js +64 -67
- package/packages/datadog-plugin-http/src/server.js +40 -15
- package/packages/datadog-plugin-jest/src/index.js +11 -3
- package/packages/datadog-plugin-jest/src/util.js +15 -8
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +1 -1
- package/packages/datadog-plugin-kafkajs/src/producer.js +3 -0
- package/packages/datadog-plugin-langgraph/src/stream.js +1 -1
- package/packages/datadog-plugin-mocha/src/index.js +19 -4
- package/packages/datadog-plugin-mongodb-core/src/index.js +281 -40
- package/packages/datadog-plugin-nats/src/consumer.js +43 -0
- package/packages/datadog-plugin-nats/src/index.js +20 -0
- package/packages/datadog-plugin-nats/src/producer.js +62 -0
- package/packages/datadog-plugin-nats/src/util.js +33 -0
- package/packages/datadog-plugin-next/src/index.js +5 -3
- package/packages/datadog-plugin-openai/src/tracing.js +15 -2
- package/packages/datadog-plugin-oracledb/src/index.js +13 -2
- package/packages/datadog-plugin-pino/src/index.js +42 -0
- package/packages/datadog-plugin-playwright/src/index.js +4 -4
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +1 -1
- package/packages/datadog-plugin-rhea/src/producer.js +1 -1
- package/packages/datadog-plugin-router/src/index.js +33 -44
- package/packages/datadog-plugin-selenium/src/index.js +1 -1
- package/packages/datadog-plugin-vitest/src/index.js +5 -13
- package/packages/datadog-plugin-winston/src/index.js +30 -0
- package/packages/datadog-shimmer/src/shimmer.js +33 -40
- package/packages/dd-trace/src/aiguard/index.js +1 -1
- package/packages/dd-trace/src/aiguard/sdk.js +1 -1
- package/packages/dd-trace/src/appsec/api_security_sampler.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +1 -1
- package/packages/dd-trace/src/appsec/reporter.js +5 -6
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +1 -1
- package/packages/dd-trace/src/appsec/sdk/utils.js +1 -1
- package/packages/dd-trace/src/appsec/user_tracking.js +5 -4
- package/packages/dd-trace/src/baggage.js +7 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +0 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +25 -13
- package/packages/dd-trace/src/ci-visibility/test-optimization-cache.js +70 -6
- package/packages/dd-trace/src/config/generated-config-types.d.ts +6 -2
- package/packages/dd-trace/src/config/supported-configurations.json +27 -8
- package/packages/dd-trace/src/datastreams/writer.js +2 -4
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +5 -8
- package/packages/dd-trace/src/encode/0.4.js +124 -108
- package/packages/dd-trace/src/encode/0.5.js +114 -26
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +31 -23
- package/packages/dd-trace/src/encode/agentless-json.js +4 -2
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +32 -13
- package/packages/dd-trace/src/encode/span-stats.js +16 -16
- package/packages/dd-trace/src/encode/tags-processors.js +16 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/genai/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +9 -7
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +0 -16
- package/packages/dd-trace/src/llmobs/span_processor.js +3 -3
- package/packages/dd-trace/src/llmobs/tagger.js +9 -1
- package/packages/dd-trace/src/llmobs/telemetry.js +1 -1
- package/packages/dd-trace/src/llmobs/util.js +66 -3
- package/packages/dd-trace/src/log/index.js +1 -1
- package/packages/dd-trace/src/msgpack/chunk.js +394 -10
- package/packages/dd-trace/src/msgpack/index.js +96 -2
- package/packages/dd-trace/src/openfeature/encoding.js +70 -0
- package/packages/dd-trace/src/openfeature/flagging_provider.js +20 -0
- package/packages/dd-trace/src/openfeature/span-enrichment-hook.js +143 -0
- package/packages/dd-trace/src/openfeature/span-enrichment.js +149 -0
- package/packages/dd-trace/src/opentelemetry/span-helpers.js +4 -3
- package/packages/dd-trace/src/opentelemetry/span.js +1 -1
- package/packages/dd-trace/src/opentracing/propagation/log.js +18 -7
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +62 -67
- package/packages/dd-trace/src/opentracing/span.js +59 -19
- package/packages/dd-trace/src/opentracing/span_context.js +49 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +20 -20
- package/packages/dd-trace/src/plugins/database.js +7 -6
- package/packages/dd-trace/src/plugins/index.js +4 -0
- package/packages/dd-trace/src/plugins/log_injection.js +56 -0
- package/packages/dd-trace/src/plugins/log_plugin.js +3 -48
- package/packages/dd-trace/src/plugins/outbound.js +1 -1
- package/packages/dd-trace/src/plugins/plugin.js +15 -17
- package/packages/dd-trace/src/plugins/tracing.js +43 -5
- package/packages/dd-trace/src/plugins/util/test.js +236 -13
- package/packages/dd-trace/src/plugins/util/web.js +79 -65
- package/packages/dd-trace/src/priority_sampler.js +2 -2
- package/packages/dd-trace/src/profiling/profiler.js +2 -2
- package/packages/dd-trace/src/profiling/profilers/wall.js +10 -4
- package/packages/dd-trace/src/sampling_rule.js +7 -7
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +10 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +8 -0
- package/packages/dd-trace/src/service-naming/source-resolver.js +46 -0
- package/packages/dd-trace/src/span_format.js +190 -58
- package/packages/dd-trace/src/spanleak.js +1 -1
- package/packages/dd-trace/src/standalone/index.js +3 -3
- package/packages/dd-trace/src/tagger.js +0 -2
- package/vendor/dist/@apm-js-collab/code-transformer/index.js +70 -39
- package/vendor/dist/@datadog/sketches-js/LICENSE +10 -36
- package/vendor/dist/@datadog/sketches-js/index.js +1 -1
- package/vendor/dist/protobufjs/index.js +1 -1
- package/vendor/dist/protobufjs/minimal/index.js +1 -1
- package/packages/dd-trace/src/msgpack/encoder.js +0 -308
- package/packages/dd-trace/src/plugins/structured_log_plugin.js +0 -9
|
@@ -44,7 +44,8 @@ class BaseLangChainLLMObsPlugin extends LLMObsPlugin {
|
|
|
44
44
|
|
|
45
45
|
getLLMObsSpanRegisterOptions (ctx) {
|
|
46
46
|
const span = ctx.currentStore?.span
|
|
47
|
-
const
|
|
47
|
+
const spanContext = span?.context()
|
|
48
|
+
const tags = spanContext?.getTags() || {}
|
|
48
49
|
|
|
49
50
|
const modelProvider = tags['langchain.request.provider'] // could be undefined
|
|
50
51
|
const modelName = tags['langchain.request.model'] // could be undefined
|
|
@@ -76,7 +77,7 @@ class BaseLangChainLLMObsPlugin extends LLMObsPlugin {
|
|
|
76
77
|
return
|
|
77
78
|
}
|
|
78
79
|
|
|
79
|
-
const provider = span?.context()
|
|
80
|
+
const provider = span?.context()?.getTag('langchain.request.provider')
|
|
80
81
|
const integrationName = this.getIntegrationName(type, provider)
|
|
81
82
|
this.setMetadata(span, provider)
|
|
82
83
|
|
|
@@ -93,14 +94,15 @@ class BaseLangChainLLMObsPlugin extends LLMObsPlugin {
|
|
|
93
94
|
const metadata = {}
|
|
94
95
|
|
|
95
96
|
// these fields won't be set for non model-based operations
|
|
97
|
+
const spanContext = span?.context()
|
|
96
98
|
const temperature =
|
|
97
|
-
|
|
98
|
-
|
|
99
|
+
spanContext?.getTag(`langchain.request.${provider}.parameters.temperature`) ||
|
|
100
|
+
spanContext?.getTag(`langchain.request.${provider}.parameters.model_kwargs.temperature`)
|
|
99
101
|
|
|
100
102
|
const maxTokens =
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
103
|
+
spanContext?.getTag(`langchain.request.${provider}.parameters.max_tokens`) ||
|
|
104
|
+
spanContext?.getTag(`langchain.request.${provider}.parameters.maxTokens`) ||
|
|
105
|
+
spanContext?.getTag(`langchain.request.${provider}.parameters.model_kwargs.max_tokens`)
|
|
104
106
|
|
|
105
107
|
if (temperature) {
|
|
106
108
|
metadata.temperature = Number.parseFloat(temperature)
|
|
@@ -35,7 +35,7 @@ class PregelStreamLLMObsPlugin extends LLMObsPlugin {
|
|
|
35
35
|
|
|
36
36
|
class NextStreamLLMObsPlugin extends LLMObsPlugin {
|
|
37
37
|
static id = 'llmobs_langgraph_next_stream'
|
|
38
|
-
static prefix = 'tracing:orchestrion:@langchain/langgraph:
|
|
38
|
+
static prefix = 'tracing:orchestrion:@langchain/langgraph:Pregel_stream:next'
|
|
39
39
|
|
|
40
40
|
start () {} // no-op: span was already registered by PregelStreamLLMObsPlugin
|
|
41
41
|
|
|
@@ -63,7 +63,7 @@ class OpenAiLLMObsPlugin extends LLMObsPlugin {
|
|
|
63
63
|
|
|
64
64
|
const inputs = ctx.args[0] // completion, chat completion, and embeddings take one argument
|
|
65
65
|
const response = ctx.result?.data // no result if error
|
|
66
|
-
const error = !!span.context().
|
|
66
|
+
const error = !!span.context().getTag('error')
|
|
67
67
|
|
|
68
68
|
const operation = getOperation(methodName)
|
|
69
69
|
|
|
@@ -11,8 +11,6 @@ const {
|
|
|
11
11
|
SPAN_KIND,
|
|
12
12
|
OUTPUT_VALUE,
|
|
13
13
|
INPUT_VALUE,
|
|
14
|
-
LLMOBS_TRACE_ID_BRIDGE_KEY,
|
|
15
|
-
LLMOBS_PARENT_ID_BRIDGE_KEY,
|
|
16
14
|
} = require('./constants/tags')
|
|
17
15
|
const {
|
|
18
16
|
getFunctionArguments,
|
|
@@ -553,20 +551,6 @@ class LLMObs extends NoopLLMObs {
|
|
|
553
551
|
...options,
|
|
554
552
|
parent: parentStore?.span,
|
|
555
553
|
})
|
|
556
|
-
|
|
557
|
-
// Bridge tags read by the dd-go LLMObs trace-indexer to correlate OTel
|
|
558
|
-
// gen_ai.* spans with SDK LLMObs spans. Written once per local trace,
|
|
559
|
-
// on the first successful SDK LLMObs span registration. The shared
|
|
560
|
-
// _trace.tags bag is serialized to the first span in every flushed
|
|
561
|
-
// chunk's meta, so partial flush is covered automatically without a
|
|
562
|
-
// separate flush-time processor. Writing only after registerLLMObsSpan
|
|
563
|
-
// succeeds avoids poisoning _trace.tags with bridge tags pointing at a
|
|
564
|
-
// span that will never produce an LLMObs event.
|
|
565
|
-
const traceTags = span?.context?.()._trace?.tags
|
|
566
|
-
if (this.enabled && traceTags && !traceTags[LLMOBS_TRACE_ID_BRIDGE_KEY]) {
|
|
567
|
-
traceTags[LLMOBS_TRACE_ID_BRIDGE_KEY] = span.context().toTraceId(true)
|
|
568
|
-
traceTags[LLMOBS_PARENT_ID_BRIDGE_KEY] = span.context().toSpanId()
|
|
569
|
-
}
|
|
570
554
|
}
|
|
571
555
|
|
|
572
556
|
try {
|
|
@@ -107,7 +107,7 @@ class LLMObsSpanProcessor {
|
|
|
107
107
|
// those cases avoids dd-go reparenting OTel children under a span that
|
|
108
108
|
// has no corresponding LLMObs event.
|
|
109
109
|
if (enqueued) {
|
|
110
|
-
span.context().
|
|
110
|
+
span.context().setTag(LLMOBS_SUBMITTED_TAG_KEY, '1')
|
|
111
111
|
}
|
|
112
112
|
} catch (e) {
|
|
113
113
|
// this should be a rare case
|
|
@@ -123,7 +123,7 @@ class LLMObsSpanProcessor {
|
|
|
123
123
|
format (span) {
|
|
124
124
|
let inputType, outputType
|
|
125
125
|
|
|
126
|
-
const spanTags = span.context().
|
|
126
|
+
const spanTags = span.context().getTags()
|
|
127
127
|
const mlObsTags = LLMObsTagger.tagMap.get(span)
|
|
128
128
|
|
|
129
129
|
const spanKind = mlObsTags[SPAN_KIND]
|
|
@@ -318,7 +318,7 @@ class LLMObsSpanProcessor {
|
|
|
318
318
|
language: 'javascript',
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
-
const errType = span.context().
|
|
321
|
+
const errType = span.context().getTag(ERROR_TYPE) || error?.name
|
|
322
322
|
if (errType) tags.error_type = errType
|
|
323
323
|
|
|
324
324
|
if (sessionId) tags.session_id = sessionId
|
|
@@ -43,7 +43,7 @@ const {
|
|
|
43
43
|
INSTRUMENTATION_METHOD_ANNOTATED,
|
|
44
44
|
} = require('./constants/tags')
|
|
45
45
|
const { storage } = require('./storage')
|
|
46
|
-
const { validateCostTags } = require('./util')
|
|
46
|
+
const { findGenAIAncestorSpanId, validateCostTags, writeBridgeTags } = require('./util')
|
|
47
47
|
|
|
48
48
|
// global registry of LLMObs spans
|
|
49
49
|
// maps LLMObs spans to their annotations
|
|
@@ -97,6 +97,13 @@ class LLMObsTagger {
|
|
|
97
97
|
|
|
98
98
|
this._register(span)
|
|
99
99
|
|
|
100
|
+
// When the registering span sits below an OTel `gen_ai.*` ancestor, use
|
|
101
|
+
// that ancestor as the parent_id fallback and suppress the bridge
|
|
102
|
+
// parent_id tag so the indexer doesn't invert the trace.
|
|
103
|
+
const genAIAncestorSpanId = findGenAIAncestorSpanId(span)
|
|
104
|
+
|
|
105
|
+
writeBridgeTags(span, { includeParentId: genAIAncestorSpanId === null })
|
|
106
|
+
|
|
100
107
|
this._setTag(span, ML_APP, spanMlApp)
|
|
101
108
|
|
|
102
109
|
if (name) this._setTag(span, NAME, name)
|
|
@@ -113,6 +120,7 @@ class LLMObsTagger {
|
|
|
113
120
|
const parentId =
|
|
114
121
|
parent?.context().toSpanId() ??
|
|
115
122
|
span.context()._trace.tags[PROPAGATED_PARENT_ID_KEY] ??
|
|
123
|
+
genAIAncestorSpanId ??
|
|
116
124
|
ROOT_PARENT_ID
|
|
117
125
|
this._setTag(span, PARENT_ID_KEY, parentId)
|
|
118
126
|
|
|
@@ -45,7 +45,7 @@ function incrementLLMObsSpanStartCount (tags, value = 1) {
|
|
|
45
45
|
|
|
46
46
|
function incrementLLMObsSpanFinishedCount (span, value = 1) {
|
|
47
47
|
const mlObsTags = LLMObsTagger.tagMap.get(span)
|
|
48
|
-
const spanTags = span.context().
|
|
48
|
+
const spanTags = span.context().getTags()
|
|
49
49
|
|
|
50
50
|
const isRootSpan = mlObsTags[PARENT_ID_KEY] === ROOT_PARENT_ID
|
|
51
51
|
const hasSessionId = mlObsTags[SESSION_ID] != null
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const log = require('../log')
|
|
4
|
-
const {
|
|
4
|
+
const {
|
|
5
|
+
LLMOBS_PARENT_ID_BRIDGE_KEY,
|
|
6
|
+
LLMOBS_TRACE_ID_BRIDGE_KEY,
|
|
7
|
+
SPAN_KINDS,
|
|
8
|
+
} = require('./constants/tags')
|
|
5
9
|
|
|
6
10
|
// LLM I/O is overwhelmingly ASCII (English prompts and code). Walk once
|
|
7
11
|
// looking for the first non-ASCII char; if there is none, hand the input
|
|
@@ -233,8 +237,8 @@ function getFunctionArguments (fn, args = []) {
|
|
|
233
237
|
}
|
|
234
238
|
|
|
235
239
|
function spanHasError (span) {
|
|
236
|
-
const
|
|
237
|
-
return !!(
|
|
240
|
+
const spanContext = span.context()
|
|
241
|
+
return !!(spanContext.getTag('error') || spanContext.getTag('error.type'))
|
|
238
242
|
}
|
|
239
243
|
|
|
240
244
|
// LLM SDKs stream tool-call argument JSON across SSE chunks; a malformed
|
|
@@ -248,11 +252,70 @@ function safeJsonParse (value, fallback) {
|
|
|
248
252
|
}
|
|
249
253
|
}
|
|
250
254
|
|
|
255
|
+
// Bridge tags read by the trace-indexer to pull OTel `gen_ai.*` spans into
|
|
256
|
+
// the same LLMObs trace. Written once per local trace (first-writer wins on
|
|
257
|
+
// `_trace.tags`). Pass `includeParentId: false` when the span sits below an
|
|
258
|
+
// OTel `gen_ai.*` ancestor — without it the indexer treats this span as the
|
|
259
|
+
// LLMObs root and hoists the gen_ai ancestors under it, inverting the trace.
|
|
260
|
+
/**
|
|
261
|
+
* @param {import('../opentracing/span')} span
|
|
262
|
+
* @param {{ includeParentId?: boolean }} [opts]
|
|
263
|
+
*/
|
|
264
|
+
function writeBridgeTags (span, { includeParentId = true } = {}) {
|
|
265
|
+
const traceTags = span?.context?.()._trace?.tags
|
|
266
|
+
if (!traceTags || traceTags[LLMOBS_TRACE_ID_BRIDGE_KEY]) return
|
|
267
|
+
traceTags[LLMOBS_TRACE_ID_BRIDGE_KEY] = span.context().toTraceId(true)
|
|
268
|
+
if (includeParentId) {
|
|
269
|
+
traceTags[LLMOBS_PARENT_ID_BRIDGE_KEY] = span.context().toSpanId()
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Walks the APM parent chain for the nearest ancestor with any `gen_ai.*`
|
|
274
|
+
// tag. Lets an auto-instrumented LLMObs span nested under a manual OTel
|
|
275
|
+
// workflow point its `parent_id` at the OTel parent so the SDK-emitted
|
|
276
|
+
// event renders under it instead of as a parallel root.
|
|
277
|
+
/**
|
|
278
|
+
* @param {import('../opentracing/span')} span
|
|
279
|
+
* @returns {string | null}
|
|
280
|
+
*/
|
|
281
|
+
function findGenAIAncestorSpanId (span) {
|
|
282
|
+
const ctx = span?.context?.()
|
|
283
|
+
let parentId = ctx?._parentId?.toString(10)
|
|
284
|
+
if (!parentId || parentId === '0') return null
|
|
285
|
+
|
|
286
|
+
const started = ctx._trace?.started
|
|
287
|
+
if (!started || started.length === 0) return null
|
|
288
|
+
|
|
289
|
+
// Linear scan per hop — parent chains are short, avoids a per-call Map.
|
|
290
|
+
while (parentId && parentId !== '0') {
|
|
291
|
+
let parent = null
|
|
292
|
+
for (const s of started) {
|
|
293
|
+
if (s.context()._spanId.toString(10) === parentId) {
|
|
294
|
+
parent = s
|
|
295
|
+
break
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (!parent) return null
|
|
299
|
+
|
|
300
|
+
const tags = parent.context().getTags()
|
|
301
|
+
if (tags) {
|
|
302
|
+
for (const key of Object.keys(tags)) {
|
|
303
|
+
if (key.startsWith('gen_ai.')) return parentId
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
parentId = parent.context()._parentId?.toString(10)
|
|
308
|
+
}
|
|
309
|
+
return null
|
|
310
|
+
}
|
|
311
|
+
|
|
251
312
|
module.exports = {
|
|
252
313
|
encodeUnicode,
|
|
314
|
+
findGenAIAncestorSpanId,
|
|
253
315
|
validateCostTags,
|
|
254
316
|
validateKind,
|
|
255
317
|
getFunctionArguments,
|
|
256
318
|
safeJsonParse,
|
|
257
319
|
spanHasError,
|
|
320
|
+
writeBridgeTags,
|
|
258
321
|
}
|
|
@@ -107,7 +107,7 @@ function publishFormatted (ch, formatter, ...args) {
|
|
|
107
107
|
|
|
108
108
|
function getErrorLog (err) {
|
|
109
109
|
if (typeof err?.delegate === 'function') {
|
|
110
|
-
const result = err.delegate()
|
|
110
|
+
const result = err.delegate(...err.args)
|
|
111
111
|
return Array.isArray(result) ? Log.parse(...result) : Log.parse(result)
|
|
112
112
|
}
|
|
113
113
|
return err
|