dd-trace 6.12.0 → 6.14.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 +3 -1
- package/ci/init.js +8 -3
- package/ci/test-optimization-validation/ci-package-scripts.js +2 -2
- package/ci/test-optimization-validation/ci-remediation.js +6 -6
- package/ci/test-optimization-validation/command-blocker.js +7 -5
- package/ci/test-optimization-validation/framework-adapters/cucumber.js +1 -1
- package/ci/test-optimization-validation/framework-adapters/cypress.js +9 -11
- package/ci/test-optimization-validation/framework-adapters/vitest.js +3 -3
- package/ci/test-optimization-validation/package-check.js +1 -1
- package/ci/test-optimization-validation/report-writer.js +7 -5
- package/ci/test-optimization-validation/scenarios/ci-wiring.js +5 -4
- package/ci/vitest-no-worker-init-runner-setup.mjs +8 -0
- package/ci/vitest-no-worker-init-setup.mjs +13 -13
- package/ci/vitest-no-worker-init-v5-setup.mjs +4 -0
- package/index.d.ts +127 -26
- package/package.json +22 -19
- package/packages/datadog-esbuild/index.js +3 -1
- package/packages/datadog-instrumentations/src/bunyan.js +4 -2
- package/packages/datadog-instrumentations/src/cypress-config.js +19 -17
- package/packages/datadog-instrumentations/src/fs.js +24 -20
- package/packages/datadog-instrumentations/src/google-cloud-vertexai.js +2 -2
- package/packages/datadog-instrumentations/src/graphql.js +16 -16
- package/packages/datadog-instrumentations/src/helpers/bunyan.js +12 -3
- package/packages/datadog-instrumentations/src/helpers/graphql-jit-runtime.js +504 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +266 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +1 -2
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +95 -30
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/ai.js +0 -25
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql-jit.js +83 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql.js +85 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/mercurius.js +30 -12
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +13 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +279 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +12 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +562 -27
- package/packages/datadog-instrumentations/src/jest.js +165 -38
- package/packages/datadog-instrumentations/src/knex.js +76 -0
- package/packages/datadog-instrumentations/src/mariadb-bundle.js +1597 -0
- package/packages/datadog-instrumentations/src/mariadb.js +13 -0
- package/packages/datadog-instrumentations/src/mocha/common.js +59 -2
- package/packages/datadog-instrumentations/src/mocha/main.js +25 -15
- package/packages/datadog-instrumentations/src/mocha/utils.js +2 -1
- package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +98 -0
- package/packages/datadog-instrumentations/src/mocha/worker.js +12 -8
- package/packages/datadog-instrumentations/src/net.js +14 -17
- package/packages/datadog-instrumentations/src/next.js +212 -62
- package/packages/datadog-instrumentations/src/openai.js +42 -40
- package/packages/datadog-instrumentations/src/pg.js +15 -0
- package/packages/datadog-instrumentations/src/pino.js +15 -4
- package/packages/datadog-instrumentations/src/playwright.js +137 -27
- package/packages/datadog-instrumentations/src/rum-browser-scripts.js +40 -0
- package/packages/datadog-instrumentations/src/sequelize.js +94 -2
- package/packages/datadog-instrumentations/src/undici.js +53 -4
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +44 -7
- package/packages/datadog-instrumentations/src/vitest-main.js +92 -9
- package/packages/datadog-instrumentations/src/vitest-worker.js +82 -14
- package/packages/datadog-instrumentations/src/webdriverio.js +986 -1
- package/packages/datadog-instrumentations/src/winston.js +6 -3
- package/packages/datadog-plugin-amqp10/src/consumer.js +3 -1
- package/packages/datadog-plugin-amqp10/src/producer.js +3 -1
- package/packages/datadog-plugin-amqp10/src/util.js +2 -1
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +6 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +16 -5
- package/packages/datadog-plugin-cassandra-driver/src/index.js +8 -3
- package/packages/datadog-plugin-cucumber/src/index.js +0 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +262 -48
- package/packages/datadog-plugin-cypress/src/support.js +1 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +4 -1
- package/packages/datadog-plugin-graphql/src/execute.js +998 -196
- package/packages/datadog-plugin-graphql/src/index.js +27 -7
- package/packages/datadog-plugin-graphql/src/jit.js +136 -0
- package/packages/datadog-plugin-graphql/src/request.js +18 -27
- package/packages/datadog-plugin-graphql/src/resolve-error.js +108 -0
- package/packages/datadog-plugin-graphql/src/tools/signature.js +1 -2
- package/packages/datadog-plugin-graphql/src/tools/transforms.js +45 -3
- package/packages/datadog-plugin-graphql/src/utils.js +208 -120
- package/packages/datadog-plugin-graphql/src/validate.js +10 -23
- package/packages/datadog-plugin-http/src/client.js +2 -15
- package/packages/datadog-plugin-http2/src/client.js +2 -15
- package/packages/datadog-plugin-jest/src/index.js +0 -6
- package/packages/datadog-plugin-langchain/src/tracing.js +7 -0
- package/packages/datadog-plugin-mocha/src/index.js +403 -75
- package/packages/datadog-plugin-mongodb-core/src/query.js +6 -0
- package/packages/datadog-plugin-mysql/src/index.js +41 -15
- package/packages/datadog-plugin-net/src/tcp.js +3 -1
- package/packages/datadog-plugin-next/src/index.js +63 -29
- package/packages/datadog-plugin-openai-agents/src/integration.js +15 -11
- package/packages/datadog-plugin-playwright/src/index.js +176 -28
- package/packages/datadog-plugin-undici/src/index.js +29 -56
- package/packages/datadog-plugin-vitest/src/index.js +6 -12
- package/packages/dd-trace/src/aiguard/evaluation.js +96 -21
- package/packages/dd-trace/src/aiguard/integrations/vercel-ai.js +2 -3
- package/packages/dd-trace/src/aiguard/messages/anthropic.js +29 -10
- package/packages/dd-trace/src/aiguard/messages/openai.js +8 -1
- package/packages/dd-trace/src/aiguard/messages/vercel-ai.js +20 -6
- package/packages/dd-trace/src/aiguard/noop.js +9 -1
- package/packages/dd-trace/src/aiguard/redaction.js +183 -0
- package/packages/dd-trace/src/aiguard/sdk.js +7 -2
- package/packages/dd-trace/src/aiguard/tags.js +2 -0
- package/packages/dd-trace/src/appsec/api_security/index.js +23 -6
- package/packages/dd-trace/src/appsec/api_security/sampler.js +99 -40
- package/packages/dd-trace/src/appsec/graphql.js +6 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +3 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -1
- package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +8 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +11 -36
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/url-sensitive-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +10 -9
- package/packages/dd-trace/src/appsec/lambda.js +44 -26
- package/packages/dd-trace/src/appsec/rule_manager.js +2 -0
- package/packages/dd-trace/src/ci-visibility/encode/json-encoder.js +32 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +8 -8
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +6 -4
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +20 -4
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/request-tracker.js +7 -150
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +7 -6
- package/packages/dd-trace/src/ci-visibility/exporters/agents.js +54 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/writer.js +1 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +397 -234
- package/packages/dd-trace/src/ci-visibility/exporters/limits.js +9 -0
- package/packages/dd-trace/src/ci-visibility/exporters/request.js +323 -31
- package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +42 -0
- package/packages/dd-trace/src/ci-visibility/final-flush.js +21 -0
- package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +57 -18
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +0 -3
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +164 -71
- package/packages/dd-trace/src/ci-visibility/requests/video-request.js +176 -0
- package/packages/dd-trace/src/ci-visibility/telemetry.js +10 -7
- package/packages/dd-trace/src/ci-visibility/test-video.js +61 -0
- package/packages/dd-trace/src/config/generated-config-types.d.ts +10 -0
- package/packages/dd-trace/src/config/index.js +75 -14
- package/packages/dd-trace/src/config/parsers.js +11 -1
- package/packages/dd-trace/src/config/stable.js +3 -3
- package/packages/dd-trace/src/config/supported-configurations.json +47 -2
- package/packages/dd-trace/src/crashtracking/crashtracker.js +82 -18
- package/packages/dd-trace/src/debugger/config.js +12 -1
- package/packages/dd-trace/src/debugger/constants.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +2 -1
- package/packages/dd-trace/src/debugger/devtools_client/request-options.js +33 -0
- package/packages/dd-trace/src/debugger/devtools_client/send.js +7 -39
- package/packages/dd-trace/src/debugger/devtools_client/status.js +11 -6
- package/packages/dd-trace/src/debugger/devtools_client/tags.js +41 -0
- package/packages/dd-trace/src/debugger/index.js +23 -3
- package/packages/dd-trace/src/dogstatsd.js +532 -71
- package/packages/dd-trace/src/encode/0.4-cross-payload.js +170 -0
- package/packages/dd-trace/src/encode/0.4.js +5 -5
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +9 -8
- package/packages/dd-trace/src/evp_proxy/direct.js +27 -23
- package/packages/dd-trace/src/exporters/agent/index.js +24 -3
- package/packages/dd-trace/src/exporters/agent/writer.js +28 -11
- package/packages/dd-trace/src/exporters/agentless/index.js +7 -9
- package/packages/dd-trace/src/exporters/agentless/writer.js +100 -118
- package/packages/dd-trace/src/exporters/common/agents.js +28 -6
- package/packages/dd-trace/src/exporters/common/buffering-exporter.js +2 -2
- package/packages/dd-trace/src/exporters/common/final-flush-request-tracker.js +191 -0
- package/packages/dd-trace/src/exporters/common/request.js +31 -11
- package/packages/dd-trace/src/exporters/common/url.js +40 -1
- package/packages/dd-trace/src/exporters/common/writer.js +31 -7
- package/packages/dd-trace/src/exporters/span-stats/index.js +23 -4
- package/packages/dd-trace/src/external-logger/src/index.js +4 -3
- package/packages/dd-trace/src/flush.js +105 -0
- package/packages/dd-trace/src/id.js +14 -0
- package/packages/dd-trace/src/index.js +5 -2
- package/packages/dd-trace/src/llmobs/experiments/client.js +4 -0
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +52 -2
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +420 -105
- package/packages/dd-trace/src/llmobs/experiments/index.js +54 -42
- package/packages/dd-trace/src/llmobs/experiments/noop.js +39 -8
- package/packages/dd-trace/src/llmobs/experiments/result.js +1 -0
- package/packages/dd-trace/src/llmobs/experiments/util.js +21 -0
- package/packages/dd-trace/src/llmobs/index.js +111 -48
- package/packages/dd-trace/src/llmobs/noop.js +2 -1
- package/packages/dd-trace/src/llmobs/plugins/ai/ddTelemetry.js +22 -71
- package/packages/dd-trace/src/llmobs/plugins/ai/vercelTelemetry.js +23 -13
- package/packages/dd-trace/src/llmobs/plugins/anthropic/util.js +8 -4
- package/packages/dd-trace/src/llmobs/plugins/claude-agent-sdk/index.js +6 -3
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +7 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +13 -6
- package/packages/dd-trace/src/llmobs/plugins/openai-agents/utils.js +5 -7
- package/packages/dd-trace/src/llmobs/util.js +0 -33
- package/packages/dd-trace/src/llmobs/writers/base.js +106 -53
- package/packages/dd-trace/src/log/index.js +7 -1
- package/packages/dd-trace/src/log-submission/log-submission-plugin.js +249 -0
- package/packages/dd-trace/src/noop/span.js +5 -0
- package/packages/dd-trace/src/openfeature/writers/base.js +14 -12
- package/packages/dd-trace/src/openfeature/writers/exposures.js +8 -1
- package/packages/dd-trace/src/openfeature/writers/util.js +1 -1
- package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +45 -3
- package/packages/dd-trace/src/opentelemetry/logs/index.js +9 -25
- package/packages/dd-trace/src/opentelemetry/logs/logger_provider.js +7 -4
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +14 -4
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +18 -23
- package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +8 -0
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +18 -6
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +14 -2
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +25 -5
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +61 -25
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +19 -4
- package/packages/dd-trace/src/opentelemetry/resource-attributes.js +55 -0
- package/packages/dd-trace/src/opentelemetry/trace/index.js +6 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +10 -0
- package/packages/dd-trace/src/opentelemetry/tracer.js +26 -2
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +494 -351
- package/packages/dd-trace/src/opentracing/span.js +28 -0
- package/packages/dd-trace/src/otel-thread-ctx.js +23 -5
- package/packages/dd-trace/src/payload-tagging/index.js +2 -1
- package/packages/dd-trace/src/plugin_manager.js +2 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +1 -6
- package/packages/dd-trace/src/plugins/tracing.js +12 -10
- package/packages/dd-trace/src/plugins/util/ci.js +3 -1
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +16 -15
- package/packages/dd-trace/src/plugins/util/status-validator.js +98 -0
- package/packages/dd-trace/src/plugins/util/test.js +157 -41
- package/packages/dd-trace/src/plugins/util/url.js +2 -2
- package/packages/dd-trace/src/plugins/util/web.js +6 -74
- package/packages/dd-trace/src/profiling/config.js +1 -0
- package/packages/dd-trace/src/profiling/oom.js +11 -5
- package/packages/dd-trace/src/profiling/profiler.js +30 -13
- package/packages/dd-trace/src/profiling/profilers/events.js +3 -3
- package/packages/dd-trace/src/profiling/profilers/space.js +38 -11
- package/packages/dd-trace/src/profiling/profilers/wall.js +14 -14
- package/packages/dd-trace/src/profiling/webspan-utils.js +7 -4
- package/packages/dd-trace/src/proxy.js +108 -10
- package/packages/dd-trace/src/remote_config/index.js +319 -101
- package/packages/dd-trace/src/remote_config/scheduler.js +37 -12
- package/packages/dd-trace/src/runtime_metrics/client.js +37 -8
- package/packages/dd-trace/src/runtime_metrics/index.js +5 -0
- package/packages/dd-trace/src/runtime_metrics/otlp_runtime_metrics.js +10 -1
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +22 -7
- package/packages/dd-trace/src/sampling_rule.js +36 -9
- package/packages/dd-trace/src/serverless/telemetry-delivery-tracker.js +51 -0
- package/packages/dd-trace/src/serverless/vercel.js +155 -0
- package/packages/dd-trace/src/serverless.js +45 -21
- package/packages/dd-trace/src/service-naming/schemas/util.js +1 -1
- package/packages/dd-trace/src/span_stats.js +64 -31
- package/packages/dd-trace/src/startup-log.js +3 -2
- package/packages/dd-trace/src/telemetry/agentless-url.js +28 -0
- package/packages/dd-trace/src/telemetry/send-data.js +18 -16
- package/packages/dd-trace/src/telemetry/session-propagation.js +3 -2
- package/packages/dd-trace/src/tracer.js +26 -5
- package/packages/dd-trace/src/tracer_metadata.js +11 -3
- package/packages/dd-trace/src/web-tags-cache.js +67 -13
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
- 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/datadog-instrumentations/src/playwright-browser-scripts.js +0 -27
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +0 -53
- package/packages/dd-trace/src/encode/agentless-json.js +0 -209
|
@@ -4,7 +4,6 @@ const { channel } = require('dc-polyfill')
|
|
|
4
4
|
const BaseLLMObsPlugin = require('../base')
|
|
5
5
|
const { getModelProvider } = require('../../../../../datadog-plugin-ai/src/utils')
|
|
6
6
|
|
|
7
|
-
const toolCreationCh = channel('tracing:orchestrion:ai:tool:start')
|
|
8
7
|
const setAttributesCh = channel('dd-trace:vercel-ai:span:setAttributes')
|
|
9
8
|
|
|
10
9
|
const { MODEL_NAME, MODEL_PROVIDER, NAME } = require('../../constants/tags')
|
|
@@ -21,16 +20,10 @@ const {
|
|
|
21
20
|
getTelemetryMetadata,
|
|
22
21
|
} = require('./util')
|
|
23
22
|
|
|
24
|
-
/**
|
|
25
|
-
* @typedef {Record<string, unknown> & { description?: string, id?: string }} AvailableToolArgs
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
23
|
/**
|
|
29
24
|
* @typedef {string | number | boolean | null | undefined | string[] | number[] | boolean[]} TagValue
|
|
30
25
|
* @typedef {Record<string, TagValue>} SpanTags
|
|
31
26
|
*
|
|
32
|
-
* @typedef {{ name?: string, description?: string }} ToolForModel
|
|
33
|
-
*
|
|
34
27
|
* @typedef {{ type: 'text' | 'reasoning' | 'redacted-reasoning', text?: string, data?: string }} TextPart
|
|
35
28
|
* @typedef {{ type: 'tool-call', toolName: string, toolCallId: string, args?: unknown, input?: unknown }} ToolCallPart
|
|
36
29
|
* @typedef {(
|
|
@@ -76,58 +69,14 @@ class DdTelemetryPlugin extends BaseLLMObsPlugin {
|
|
|
76
69
|
static integration = 'ai'
|
|
77
70
|
static prefix = 'tracing:dd-trace:vercel-ai'
|
|
78
71
|
|
|
79
|
-
/**
|
|
80
|
-
* The available tools within the runtime scope of this integration.
|
|
81
|
-
* This essentially acts as a global registry for all tools made through the Vercel AI SDK.
|
|
82
|
-
* @type {Set<AvailableToolArgs>}
|
|
83
|
-
*/
|
|
84
|
-
#availableTools
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* A mapping of tool call IDs to tool names.
|
|
88
|
-
* This is used to map the tool call ID to the tool name for the output message.
|
|
89
|
-
* @type {Record<string, string>}
|
|
90
|
-
*/
|
|
91
|
-
#toolCallIdsToName
|
|
92
|
-
|
|
93
72
|
constructor (...args) {
|
|
94
73
|
super(...args)
|
|
95
74
|
|
|
96
|
-
this.#toolCallIdsToName = {}
|
|
97
|
-
this.#availableTools = new Set()
|
|
98
|
-
toolCreationCh.subscribe(ctx => {
|
|
99
|
-
const toolArgs = ctx.arguments
|
|
100
|
-
const tool = toolArgs[0] ?? {}
|
|
101
|
-
this.#availableTools.add(tool)
|
|
102
|
-
})
|
|
103
|
-
|
|
104
75
|
setAttributesCh.subscribe(({ ctx, attributes }) => {
|
|
105
76
|
Object.assign(ctx.attributes, attributes)
|
|
106
77
|
})
|
|
107
78
|
}
|
|
108
79
|
|
|
109
|
-
/**
|
|
110
|
-
* Does a best-effort attempt to find the right tool name for the given tool description.
|
|
111
|
-
* This is because the Vercel AI SDK does not tag tools by name properly, but
|
|
112
|
-
* rather by the index they were passed in. Tool names appear nowhere in the span tags.
|
|
113
|
-
*
|
|
114
|
-
* We use the tool description as the next best identifier for a tool.
|
|
115
|
-
*
|
|
116
|
-
* @param {string} toolName
|
|
117
|
-
* @param {string | undefined} toolDescription
|
|
118
|
-
* @returns {string | undefined}
|
|
119
|
-
*/
|
|
120
|
-
findToolName (toolName, toolDescription) {
|
|
121
|
-
if (Number.isNaN(Number.parseInt(toolName, 10))) return toolName
|
|
122
|
-
|
|
123
|
-
for (const availableTool of this.#availableTools) {
|
|
124
|
-
const description = availableTool.description
|
|
125
|
-
if (description === toolDescription && availableTool.id) {
|
|
126
|
-
return availableTool.id
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
80
|
/**
|
|
132
81
|
* @override
|
|
133
82
|
*/
|
|
@@ -232,7 +181,13 @@ class DdTelemetryPlugin extends BaseLLMObsPlugin {
|
|
|
232
181
|
const lastUserPrompt =
|
|
233
182
|
promptInfo.prompt ??
|
|
234
183
|
promptInfo.messages.reverse().find(message => message.role === 'user')?.content
|
|
235
|
-
|
|
184
|
+
let prompt = lastUserPrompt
|
|
185
|
+
if (Array.isArray(lastUserPrompt)) {
|
|
186
|
+
prompt = ''
|
|
187
|
+
for (const part of lastUserPrompt) {
|
|
188
|
+
if (typeof part.text === 'string') prompt += part.text
|
|
189
|
+
}
|
|
190
|
+
}
|
|
236
191
|
|
|
237
192
|
const output = tags['ai.response.object']
|
|
238
193
|
|
|
@@ -248,7 +203,13 @@ class DdTelemetryPlugin extends BaseLLMObsPlugin {
|
|
|
248
203
|
const lastUserPrompt =
|
|
249
204
|
promptInfo.prompt ??
|
|
250
205
|
promptInfo.messages.reverse().find(message => message.role === 'user')?.content
|
|
251
|
-
|
|
206
|
+
let prompt = lastUserPrompt
|
|
207
|
+
if (Array.isArray(lastUserPrompt)) {
|
|
208
|
+
prompt = ''
|
|
209
|
+
for (const part of lastUserPrompt) {
|
|
210
|
+
if (typeof part.text === 'string') prompt += part.text
|
|
211
|
+
}
|
|
212
|
+
}
|
|
252
213
|
|
|
253
214
|
const output = tags['ai.response.text']
|
|
254
215
|
|
|
@@ -263,16 +224,14 @@ class DdTelemetryPlugin extends BaseLLMObsPlugin {
|
|
|
263
224
|
* @param {SpanTags} tags
|
|
264
225
|
*/
|
|
265
226
|
setLLMOperationTags (span, tags) {
|
|
266
|
-
const toolsForModel = tags['ai.prompt.tools']?.map(getJsonStringValue)
|
|
267
|
-
|
|
268
227
|
const inputMessages = getJsonStringValue(tags['ai.prompt.messages'], [])
|
|
269
228
|
const parsedInputMessages = []
|
|
270
229
|
for (const message of inputMessages) {
|
|
271
|
-
const formattedMessages = this.formatMessage(message
|
|
230
|
+
const formattedMessages = this.formatMessage(message)
|
|
272
231
|
parsedInputMessages.push(...formattedMessages)
|
|
273
232
|
}
|
|
274
233
|
|
|
275
|
-
const outputMessage = this.formatOutputMessage(tags
|
|
234
|
+
const outputMessage = this.formatOutputMessage(tags)
|
|
276
235
|
|
|
277
236
|
this._tagger.tagLLMIO(span, parsedInputMessages, outputMessage)
|
|
278
237
|
|
|
@@ -284,8 +243,8 @@ class DdTelemetryPlugin extends BaseLLMObsPlugin {
|
|
|
284
243
|
}
|
|
285
244
|
|
|
286
245
|
setToolTags (span, tags) {
|
|
287
|
-
const
|
|
288
|
-
|
|
246
|
+
const name = getToolNameFromTags(tags)
|
|
247
|
+
|
|
289
248
|
if (name) this._tagger._setTag(span, NAME, name)
|
|
290
249
|
|
|
291
250
|
const input = tags['ai.toolCall.args']
|
|
@@ -294,7 +253,7 @@ class DdTelemetryPlugin extends BaseLLMObsPlugin {
|
|
|
294
253
|
this._tagger.tagTextIO(span, input, output)
|
|
295
254
|
}
|
|
296
255
|
|
|
297
|
-
formatOutputMessage (tags
|
|
256
|
+
formatOutputMessage (tags) {
|
|
298
257
|
const outputMessageText = tags['ai.response.text'] ?? tags['ai.response.object']
|
|
299
258
|
const outputMessageToolCalls = getJsonStringValue(tags['ai.response.toolCalls'], [])
|
|
300
259
|
|
|
@@ -302,13 +261,9 @@ class DdTelemetryPlugin extends BaseLLMObsPlugin {
|
|
|
302
261
|
for (const toolCall of outputMessageToolCalls) {
|
|
303
262
|
const toolArgs = toolCall.args ?? toolCall.input
|
|
304
263
|
const toolCallArgs = typeof toolArgs === 'string' ? getJsonStringValue(toolArgs, {}) : toolArgs
|
|
305
|
-
const toolDescription = toolsForModel?.find(tool => toolCall.toolName === tool.name)?.description
|
|
306
|
-
const name = this.findToolName(toolCall.toolName, toolDescription)
|
|
307
|
-
this.#toolCallIdsToName[toolCall.toolCallId] = name
|
|
308
|
-
|
|
309
264
|
formattedToolCalls.push({
|
|
310
265
|
arguments: toolCallArgs,
|
|
311
|
-
name,
|
|
266
|
+
name: toolCall.toolName,
|
|
312
267
|
toolId: toolCall.toolCallId,
|
|
313
268
|
type: toolCall.toolCallType ?? 'function',
|
|
314
269
|
})
|
|
@@ -328,11 +283,10 @@ class DdTelemetryPlugin extends BaseLLMObsPlugin {
|
|
|
328
283
|
* need to split into multiple messages.
|
|
329
284
|
*
|
|
330
285
|
* @param {AiSdkMessage} message
|
|
331
|
-
* @param {ToolForModel[] | null | undefined} toolsForModel
|
|
332
286
|
* @returns {Array<{role: string, content: string, toolId?: string,
|
|
333
287
|
* toolCalls?: Array<{arguments: string, name: string, toolId: string, type: string}>}>}
|
|
334
288
|
*/
|
|
335
|
-
formatMessage (message
|
|
289
|
+
formatMessage (message) {
|
|
336
290
|
const { role, content } = message
|
|
337
291
|
|
|
338
292
|
if (role === 'system') {
|
|
@@ -357,12 +311,9 @@ class DdTelemetryPlugin extends BaseLLMObsPlugin {
|
|
|
357
311
|
if (['text', 'reasoning', 'redacted-reasoning'].includes(type)) {
|
|
358
312
|
finalContent += part.text ?? part.data
|
|
359
313
|
} else if (type === 'tool-call') {
|
|
360
|
-
const toolDescription = toolsForModel?.find(tool => part.toolName === tool.name)?.description
|
|
361
|
-
const name = this.findToolName(part.toolName, toolDescription)
|
|
362
|
-
|
|
363
314
|
toolCalls.push({
|
|
364
315
|
arguments: part.args ?? part.input,
|
|
365
|
-
name,
|
|
316
|
+
name: part.toolName,
|
|
366
317
|
toolId: part.toolCallId,
|
|
367
318
|
type: 'function',
|
|
368
319
|
})
|
|
@@ -38,11 +38,15 @@ function formatLanguageModelInputMessages (instructions, messages) {
|
|
|
38
38
|
const inputMessages = []
|
|
39
39
|
|
|
40
40
|
if (instructions) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
let systemPrompt = instructions
|
|
42
|
+
if (typeof instructions !== 'string') {
|
|
43
|
+
if (Array.isArray(instructions)) {
|
|
44
|
+
systemPrompt = ''
|
|
45
|
+
for (const instruction of instructions) systemPrompt += instruction.content
|
|
46
|
+
} else {
|
|
47
|
+
systemPrompt = instructions.content
|
|
48
|
+
}
|
|
49
|
+
}
|
|
46
50
|
|
|
47
51
|
inputMessages.push({ role: 'system', content: systemPrompt })
|
|
48
52
|
}
|
|
@@ -53,13 +57,13 @@ function formatLanguageModelInputMessages (instructions, messages) {
|
|
|
53
57
|
if (role === 'system') {
|
|
54
58
|
inputMessages.push({ role, content })
|
|
55
59
|
} else if (role === 'user') {
|
|
56
|
-
|
|
57
|
-
typeof content
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
let userMessageContent = content
|
|
61
|
+
if (typeof content !== 'string') {
|
|
62
|
+
userMessageContent = ''
|
|
63
|
+
for (const part of content) {
|
|
64
|
+
if (part.type === 'text') userMessageContent += part.text
|
|
65
|
+
}
|
|
66
|
+
}
|
|
63
67
|
|
|
64
68
|
inputMessages.push({ role, content: userMessageContent })
|
|
65
69
|
} else if (role === 'assistant') {
|
|
@@ -292,7 +296,13 @@ class VercelAiTelemetryPlugin extends BaseLLMObsPlugin {
|
|
|
292
296
|
const { event, result } = ctx
|
|
293
297
|
|
|
294
298
|
const lastUserPrompt = event.messages.findLast(message => message.role === 'user')?.content
|
|
295
|
-
|
|
299
|
+
let input = lastUserPrompt
|
|
300
|
+
if (Array.isArray(lastUserPrompt)) {
|
|
301
|
+
input = ''
|
|
302
|
+
for (const part of lastUserPrompt) {
|
|
303
|
+
if (part.type === 'text') input += part.text
|
|
304
|
+
}
|
|
305
|
+
}
|
|
296
306
|
|
|
297
307
|
const output =
|
|
298
308
|
ctx.isStream
|
|
@@ -38,16 +38,20 @@ function formatAnthropicToolResultContent (content) {
|
|
|
38
38
|
if (typeof content === 'string') {
|
|
39
39
|
return content
|
|
40
40
|
} else if (Array.isArray(content)) {
|
|
41
|
-
|
|
41
|
+
let formattedContent = ''
|
|
42
42
|
for (const toolResultBlock of content) {
|
|
43
|
+
let part
|
|
43
44
|
if (toolResultBlock.text) {
|
|
44
|
-
|
|
45
|
+
part = toolResultBlock.text
|
|
45
46
|
} else if (toolResultBlock.type === 'image') {
|
|
46
|
-
|
|
47
|
+
part = '([IMAGE DETECTED])'
|
|
47
48
|
}
|
|
49
|
+
if (part === undefined) continue
|
|
50
|
+
if (formattedContent) formattedContent += ','
|
|
51
|
+
formattedContent += part
|
|
48
52
|
}
|
|
49
53
|
|
|
50
|
-
return formattedContent
|
|
54
|
+
return formattedContent
|
|
51
55
|
}
|
|
52
56
|
return JSON.stringify(content)
|
|
53
57
|
}
|
|
@@ -18,12 +18,15 @@ function getToolOutputText (raw) {
|
|
|
18
18
|
if (raw == null) return
|
|
19
19
|
|
|
20
20
|
if (Array.isArray(raw)) {
|
|
21
|
-
|
|
21
|
+
let output = ''
|
|
22
|
+
let separator = ''
|
|
22
23
|
for (const block of raw) {
|
|
23
24
|
const text = getToolOutputText(block)
|
|
24
|
-
if (text)
|
|
25
|
+
if (!text) continue
|
|
26
|
+
output += separator + text
|
|
27
|
+
separator = '\n'
|
|
25
28
|
}
|
|
26
|
-
return output
|
|
29
|
+
return output
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
if (raw.type === 'tool_result') return getToolOutputText(raw.content)
|
|
@@ -46,6 +46,13 @@ class BaseLangChainLLMObsPlugin extends LLMObsPlugin {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
error (ctx) {
|
|
50
|
+
// NodeInterrupt or GraphInterrupt "errors" for control flow, do not mark as real errors
|
|
51
|
+
if (ctx.error?.is_bubble_up) return
|
|
52
|
+
|
|
53
|
+
super.error(ctx)
|
|
54
|
+
}
|
|
55
|
+
|
|
49
56
|
getLLMObsSpanRegisterOptions (ctx) {
|
|
50
57
|
const span = ctx.currentStore?.span
|
|
51
58
|
const spanContext = span?.context()
|
|
@@ -134,15 +134,17 @@ function hasMultimodalInputs (variables) {
|
|
|
134
134
|
* @returns {{ content: string, audioParts: Array<{ mimeType: string, content: string }> }}
|
|
135
135
|
*/
|
|
136
136
|
function extractContentParts (parts) {
|
|
137
|
-
|
|
137
|
+
let content = ''
|
|
138
|
+
let hasContent = false
|
|
138
139
|
const audioParts = []
|
|
139
140
|
|
|
140
141
|
for (const part of parts) {
|
|
141
142
|
const partType = part?.type ?? ''
|
|
143
|
+
let extracted
|
|
142
144
|
if (partType === 'text') {
|
|
143
|
-
extracted
|
|
145
|
+
extracted = part.text ?? ''
|
|
144
146
|
} else if (partType === 'image_url') {
|
|
145
|
-
extracted
|
|
147
|
+
extracted = IMAGE_FALLBACK
|
|
146
148
|
} else if (partType === 'input_audio') {
|
|
147
149
|
const inputAudio = part.input_audio ?? {}
|
|
148
150
|
const data = inputAudio.data
|
|
@@ -151,14 +153,19 @@ function extractContentParts (parts) {
|
|
|
151
153
|
// is needed. Only fall back to "[audio]" when there's no audio to capture.
|
|
152
154
|
audioParts.push(formatAudioPart(data, audioMimeTypeFromFormat(inputAudio.format, AUDIO_MIME_TYPES)))
|
|
153
155
|
} else {
|
|
154
|
-
extracted
|
|
156
|
+
extracted = AUDIO_FALLBACK
|
|
155
157
|
}
|
|
156
158
|
} else {
|
|
157
|
-
extracted
|
|
159
|
+
extracted = `[${partType}]`
|
|
158
160
|
}
|
|
161
|
+
|
|
162
|
+
if (extracted === undefined) continue
|
|
163
|
+
if (hasContent) content += '\n'
|
|
164
|
+
content += extracted
|
|
165
|
+
hasContent = true
|
|
159
166
|
}
|
|
160
167
|
|
|
161
|
-
return { content
|
|
168
|
+
return { content, audioParts }
|
|
162
169
|
}
|
|
163
170
|
|
|
164
171
|
/**
|
|
@@ -11,23 +11,23 @@ const { safeJsonParse } = require('../../util')
|
|
|
11
11
|
* @returns {{ content: string, audioParts: Array<{ mimeType: string, content: string }> }}
|
|
12
12
|
*/
|
|
13
13
|
function extractMessageContent (parts) {
|
|
14
|
-
|
|
14
|
+
let content = ''
|
|
15
15
|
const audioParts = []
|
|
16
16
|
|
|
17
17
|
for (const part of parts) {
|
|
18
18
|
if (!part) continue
|
|
19
19
|
const text = extractTextFromContentItem(part)
|
|
20
20
|
if (text) {
|
|
21
|
-
|
|
21
|
+
content += text
|
|
22
22
|
continue
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
const extracted = extractContentParts([part])
|
|
26
|
-
if (extracted.content)
|
|
26
|
+
if (extracted.content) content += extracted.content
|
|
27
27
|
if (extracted.audioParts.length > 0) audioParts.push(...extracted.audioParts)
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
return { content
|
|
30
|
+
return { content, audioParts }
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/**
|
|
@@ -167,13 +167,11 @@ function extractOutputMessages (result) {
|
|
|
167
167
|
if (item.type === 'message') {
|
|
168
168
|
let content = ''
|
|
169
169
|
if (Array.isArray(item.content)) {
|
|
170
|
-
const textParts = []
|
|
171
170
|
for (const contentItem of item.content) {
|
|
172
171
|
if (contentItem?.type === 'output_text' && contentItem.text) {
|
|
173
|
-
|
|
172
|
+
content += contentItem.text
|
|
174
173
|
}
|
|
175
174
|
}
|
|
176
|
-
content = textParts.join('')
|
|
177
175
|
} else if (typeof item.content === 'string') {
|
|
178
176
|
content = item.content
|
|
179
177
|
}
|
|
@@ -337,37 +337,6 @@ function resolveAgentAttribution (tags, span) {
|
|
|
337
337
|
return { name: tags[PARENT_AGENT_NAME], spanId: tags[PARENT_AGENT_SPAN_ID] }
|
|
338
338
|
}
|
|
339
339
|
|
|
340
|
-
/**
|
|
341
|
-
* Removes all `key=value` entries for the given key from a comma-separated tagset string.
|
|
342
|
-
*
|
|
343
|
-
* @param {string} tags - Existing tagset string (may be empty).
|
|
344
|
-
* @param {string} key
|
|
345
|
-
* @returns {string}
|
|
346
|
-
*/
|
|
347
|
-
function stripTagsetEntry (tags, key) {
|
|
348
|
-
if (!tags.includes(key)) return tags
|
|
349
|
-
return tags.split(',').filter(entry => !entry.startsWith(`${key}=`)).join(',')
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* Appends `key=value` to the tagset string with a comma separator, but only when `value` is
|
|
354
|
-
* truthy, passes the optional `safeguard` predicate, and fits within `maxTagSetLength`. Returns
|
|
355
|
-
* the original `tags` unchanged when the value is absent, unsafe, or would overflow the budget.
|
|
356
|
-
*
|
|
357
|
-
* @param {string} tags - Existing tagset string (may be empty).
|
|
358
|
-
* @param {string} key
|
|
359
|
-
* @param {string | undefined} value
|
|
360
|
-
* @param {((v: string) => boolean) | null} [safeguard]
|
|
361
|
-
* @param {number} [maxTagSetLength]
|
|
362
|
-
* @returns {string}
|
|
363
|
-
*/
|
|
364
|
-
function appendOptionalPropagatedTag (tags, key, value, safeguard, maxTagSetLength) {
|
|
365
|
-
if (!value || (safeguard && !safeguard(value))) return tags
|
|
366
|
-
const entry = `${tags ? ',' : ''}${key}=${value}`
|
|
367
|
-
if (maxTagSetLength != null && tags.length + entry.length > maxTagSetLength) return tags
|
|
368
|
-
return `${tags}${entry}`
|
|
369
|
-
}
|
|
370
|
-
|
|
371
340
|
function spanHasError (span) {
|
|
372
341
|
const spanContext = span.context()
|
|
373
342
|
return !!(spanContext.getTag('error') || spanContext.getTag('error.type'))
|
|
@@ -518,7 +487,6 @@ function formatAudioPart (data, mimeType) {
|
|
|
518
487
|
|
|
519
488
|
module.exports = {
|
|
520
489
|
agentNameWireSafe,
|
|
521
|
-
appendOptionalPropagatedTag,
|
|
522
490
|
audioMimeTypeFromFormat,
|
|
523
491
|
encodeUnicode,
|
|
524
492
|
findGenAIAncestorSpanId,
|
|
@@ -527,7 +495,6 @@ module.exports = {
|
|
|
527
495
|
normalizeLlmObsTraceId,
|
|
528
496
|
formatAudioPart,
|
|
529
497
|
resolveAgentAttribution,
|
|
530
|
-
stripTagsetEntry,
|
|
531
498
|
validateCostTags,
|
|
532
499
|
validateKind,
|
|
533
500
|
getFunctionArguments,
|