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
|
@@ -5,7 +5,7 @@ const { storage } = require('../../datadog-core')
|
|
|
5
5
|
const tags = require('../../../ext/tags')
|
|
6
6
|
const formats = require('../../../ext/formats')
|
|
7
7
|
const HTTP_HEADERS = formats.HTTP_HEADERS
|
|
8
|
-
const
|
|
8
|
+
const { getClientStatusValidator } = require('../../dd-trace/src/plugins/util/status-validator')
|
|
9
9
|
const { buildClientHttpUrl } = require('../../dd-trace/src/plugins/util/url')
|
|
10
10
|
const { stripQueryAndFragment } = require('../../dd-trace/src/util')
|
|
11
11
|
const { CLIENT_PORT_KEY } = require('../../dd-trace/src/constants')
|
|
@@ -16,6 +16,8 @@ const {
|
|
|
16
16
|
HTTP_RESPONSE_HEADERS,
|
|
17
17
|
} = tags
|
|
18
18
|
|
|
19
|
+
const UPGRADE_CHANNEL = 'apm:undici:request:upgrade'
|
|
20
|
+
|
|
19
21
|
// WeakMap to store span context for native undici request objects
|
|
20
22
|
const requestContexts = new WeakMap()
|
|
21
23
|
|
|
@@ -33,6 +35,7 @@ class UndiciPlugin extends HttpClientPlugin {
|
|
|
33
35
|
this.addSub('undici:request:headers', this.#onNativeRequestHeaders.bind(this))
|
|
34
36
|
this.addSub('undici:request:trailers', this.#onNativeRequestTrailers.bind(this))
|
|
35
37
|
this.addSub('undici:request:error', this.#onNativeRequestError.bind(this))
|
|
38
|
+
this.addSub(UPGRADE_CHANNEL, this.#onNativeRequestUpgrade.bind(this))
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
// ===========================================
|
|
@@ -112,30 +115,15 @@ class UndiciPlugin extends HttpClientPlugin {
|
|
|
112
115
|
// Store span context for request for later retrieval
|
|
113
116
|
requestContexts.set(request, {
|
|
114
117
|
span,
|
|
115
|
-
store,
|
|
116
|
-
uri,
|
|
117
118
|
method,
|
|
118
119
|
})
|
|
119
|
-
|
|
120
|
-
// Enter the span context
|
|
121
|
-
storage('legacy').enterWith({ ...store, span })
|
|
122
120
|
}
|
|
123
121
|
|
|
124
122
|
#onNativeRequestBodySent ({ request }) {
|
|
125
123
|
const ctx = requestContexts.get(request)
|
|
126
124
|
if (!ctx || ctx.method !== 'CONNECT') return
|
|
127
125
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
this.config.hooks.request(span, null, null)
|
|
131
|
-
|
|
132
|
-
span.finish()
|
|
133
|
-
|
|
134
|
-
requestContexts.delete(request)
|
|
135
|
-
|
|
136
|
-
if (store) {
|
|
137
|
-
storage('legacy').enterWith(store)
|
|
138
|
-
}
|
|
126
|
+
this.#finishNativeRequest(request)
|
|
139
127
|
}
|
|
140
128
|
|
|
141
129
|
#onNativeRequestHeaders ({ request, response }) {
|
|
@@ -160,50 +148,48 @@ class UndiciPlugin extends HttpClientPlugin {
|
|
|
160
148
|
}
|
|
161
149
|
|
|
162
150
|
#onNativeRequestTrailers ({ request }) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const { span, store } = ctx
|
|
167
|
-
|
|
168
|
-
// Call the request hook if configured
|
|
169
|
-
this.config.hooks.request(span, null, null)
|
|
170
|
-
|
|
171
|
-
// Finish the span
|
|
172
|
-
span.finish()
|
|
151
|
+
this.#finishNativeRequest(request)
|
|
152
|
+
}
|
|
173
153
|
|
|
174
|
-
|
|
175
|
-
|
|
154
|
+
#onNativeRequestError ({ request, error }) {
|
|
155
|
+
this.#finishNativeRequest(request, error)
|
|
156
|
+
}
|
|
176
157
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
158
|
+
/**
|
|
159
|
+
* @param {{ error?: Error, headers: unknown, request: object, statusCode: number }} context
|
|
160
|
+
*/
|
|
161
|
+
#onNativeRequestUpgrade ({ error, headers, request, statusCode }) {
|
|
162
|
+
this.#onNativeRequestHeaders({ request, response: { headers, statusCode } })
|
|
163
|
+
this.#finishNativeRequest(request, error)
|
|
181
164
|
}
|
|
182
165
|
|
|
183
|
-
|
|
166
|
+
/**
|
|
167
|
+
* @param {object} request
|
|
168
|
+
* @param {Error} [error]
|
|
169
|
+
*/
|
|
170
|
+
#finishNativeRequest (request, error) {
|
|
184
171
|
const ctx = requestContexts.get(request)
|
|
185
172
|
if (!ctx) return
|
|
186
173
|
|
|
187
|
-
const { span
|
|
174
|
+
const { span } = ctx
|
|
188
175
|
|
|
189
176
|
// Don't record AbortError as an error - it's user-initiated cancellation
|
|
190
177
|
if (error && error.name !== 'AbortError') {
|
|
191
178
|
span.setTag('error', error)
|
|
192
179
|
}
|
|
193
180
|
|
|
194
|
-
|
|
195
|
-
|
|
181
|
+
const requestHook = this.config.hooks.request
|
|
182
|
+
if (requestHook !== noop) {
|
|
183
|
+
this.tracer.scope().activate(span, () => {
|
|
184
|
+
requestHook(span, null, null)
|
|
185
|
+
})
|
|
186
|
+
}
|
|
196
187
|
|
|
197
188
|
// Finish the span
|
|
198
189
|
span.finish()
|
|
199
190
|
|
|
200
191
|
// Clean up
|
|
201
192
|
requestContexts.delete(request)
|
|
202
|
-
|
|
203
|
-
// Restore parent store
|
|
204
|
-
if (store) {
|
|
205
|
-
storage('legacy').enterWith(store)
|
|
206
|
-
}
|
|
207
193
|
}
|
|
208
194
|
|
|
209
195
|
// ===========================================
|
|
@@ -302,7 +288,7 @@ function normalizeHeaders (headers) {
|
|
|
302
288
|
}
|
|
303
289
|
|
|
304
290
|
function normalizeConfig (config) {
|
|
305
|
-
const validateStatus =
|
|
291
|
+
const validateStatus = getClientStatusValidator(config)
|
|
306
292
|
const hooks = getHooks(config)
|
|
307
293
|
|
|
308
294
|
return {
|
|
@@ -312,19 +298,6 @@ function normalizeConfig (config) {
|
|
|
312
298
|
}
|
|
313
299
|
}
|
|
314
300
|
|
|
315
|
-
function getStatusValidator (config) {
|
|
316
|
-
if (typeof config.validateStatus === 'function') {
|
|
317
|
-
return config.validateStatus
|
|
318
|
-
} else if (Object.hasOwn(config, 'validateStatus')) {
|
|
319
|
-
log.error('Expected `validateStatus` to be a function.')
|
|
320
|
-
}
|
|
321
|
-
return defaultValidateStatus
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
function defaultValidateStatus (code) {
|
|
325
|
-
return code < 400 || code >= 500
|
|
326
|
-
}
|
|
327
|
-
|
|
328
301
|
function getHooks (config) {
|
|
329
302
|
const request = config.hooks?.request ?? noop
|
|
330
303
|
|
|
@@ -361,13 +361,13 @@ class VitestPlugin extends CiPlugin {
|
|
|
361
361
|
[TEST_SOURCE_START]: testStartLine || 1,
|
|
362
362
|
[TEST_STATUS]: 'skip',
|
|
363
363
|
[TEST_FINAL_STATUS]: 'skip',
|
|
364
|
-
...(isAttemptToFix ? { [TEST_MANAGEMENT_IS_ATTEMPT_TO_FIX]: 'true' } : {}),
|
|
365
|
-
...(isDisabled ? { [TEST_MANAGEMENT_IS_DISABLED]: 'true' } : {}),
|
|
366
|
-
...(isQuarantined ? { [TEST_MANAGEMENT_IS_QUARANTINED]: 'true' } : {}),
|
|
367
|
-
...(isNew ? { [TEST_IS_NEW]: 'true' } : {}),
|
|
368
|
-
...(isRumActive ? { [TEST_IS_RUM_ACTIVE]: 'true' } : {}),
|
|
369
|
-
...(isTestFrameworkWorker ? { [TEST_IS_TEST_FRAMEWORK_WORKER]: 'true' } : {}),
|
|
370
364
|
}
|
|
365
|
+
if (isAttemptToFix) extraTags[TEST_MANAGEMENT_IS_ATTEMPT_TO_FIX] = 'true'
|
|
366
|
+
if (isDisabled) extraTags[TEST_MANAGEMENT_IS_DISABLED] = 'true'
|
|
367
|
+
if (isQuarantined) extraTags[TEST_MANAGEMENT_IS_QUARANTINED] = 'true'
|
|
368
|
+
if (isNew) extraTags[TEST_IS_NEW] = 'true'
|
|
369
|
+
if (isRumActive) extraTags[TEST_IS_RUM_ACTIVE] = 'true'
|
|
370
|
+
if (isTestFrameworkWorker) extraTags[TEST_IS_TEST_FRAMEWORK_WORKER] = 'true'
|
|
371
371
|
setBrowserTags(extraTags, {
|
|
372
372
|
browserDriver,
|
|
373
373
|
browserName,
|
|
@@ -523,7 +523,6 @@ class VitestPlugin extends CiPlugin {
|
|
|
523
523
|
this.telemetry.ciVisEvent(TELEMETRY_CODE_COVERAGE_FINISHED, 'suite', { library: coverageLibrary })
|
|
524
524
|
this.telemetry.distribution(TELEMETRY_CODE_COVERAGE_NUM_FILES, {}, relativeFiles.length)
|
|
525
525
|
}
|
|
526
|
-
this.tracer._exporter.deferTestSuiteSpan?.(testSuiteSpan)
|
|
527
526
|
testSuiteSpan.finish()
|
|
528
527
|
finishAllTraceSpans(testSuiteSpan)
|
|
529
528
|
}
|
|
@@ -567,7 +566,6 @@ class VitestPlugin extends CiPlugin {
|
|
|
567
566
|
this.addSub('ci:vitest:session:finish', ({
|
|
568
567
|
status,
|
|
569
568
|
error,
|
|
570
|
-
isTestSessionFinalizationError,
|
|
571
569
|
testCodeCoverageLinesTotal,
|
|
572
570
|
isEarlyFlakeDetectionEnabled,
|
|
573
571
|
isEarlyFlakeDetectionFaulty,
|
|
@@ -590,9 +588,6 @@ class VitestPlugin extends CiPlugin {
|
|
|
590
588
|
this.testSessionSpan.setTag(TEST_STATUS, status)
|
|
591
589
|
this.testModuleSpan.setTag(TEST_STATUS, status)
|
|
592
590
|
if (error) {
|
|
593
|
-
if (isTestSessionFinalizationError) {
|
|
594
|
-
this.tracer._exporter.setDeferredTestSuiteError?.(error)
|
|
595
|
-
}
|
|
596
591
|
this.testModuleSpan.setTag('error', error)
|
|
597
592
|
this.testSessionSpan.setTag('error', error)
|
|
598
593
|
}
|
|
@@ -622,7 +617,6 @@ class VitestPlugin extends CiPlugin {
|
|
|
622
617
|
if (vitestPool) {
|
|
623
618
|
this.testSessionSpan.setTag(VITEST_POOL, vitestPool)
|
|
624
619
|
}
|
|
625
|
-
this.tracer._exporter.exportDeferredTestSuiteSpans?.()
|
|
626
620
|
this.testModuleSpan.finish()
|
|
627
621
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'module')
|
|
628
622
|
this.testSessionSpan.finish()
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { HTTP_CLIENT_IP, HTTP_USERAGENT, NETWORK_CLIENT_IP } = require('../../../../ext/tags')
|
|
4
|
-
const
|
|
4
|
+
const createRfdc = require('../../../../vendor/dist/rfdc')
|
|
5
|
+
const clone = createRfdc({ proto: false, circles: false })
|
|
5
6
|
const { USER_ID, USER_SESSION_ID } = require('../appsec/addresses')
|
|
6
7
|
const { getActiveRequest } = require('../appsec/store')
|
|
7
8
|
const { keepTrace } = require('../priority_sampler')
|
|
8
9
|
const { extractIp } = require('../plugins/util/ip_extractor')
|
|
9
10
|
const { AI_GUARD } = require('../standalone/product')
|
|
10
11
|
const telemetryMetrics = require('../telemetry/metrics')
|
|
12
|
+
const { normalizeRedactionReplacements, redactMessages } = require('./redaction')
|
|
11
13
|
const TAGS = require('./tags')
|
|
12
14
|
|
|
13
15
|
const ALLOW = 'ALLOW'
|
|
14
16
|
|
|
17
|
+
/** @typedef {import('../../../../index').aiguard.ContentPart} ContentPart */
|
|
15
18
|
/** @typedef {import('../../../../index').aiguard.Message} Message */
|
|
19
|
+
/** @typedef {import('../../../../index').aiguard.RedactionReplacement} RedactionReplacement */
|
|
16
20
|
/** @typedef {import('../opentracing/span')} Span */
|
|
17
21
|
|
|
18
22
|
/**
|
|
@@ -24,19 +28,22 @@ const ALLOW = 'ALLOW'
|
|
|
24
28
|
* @property {Record<string, unknown>} tagProbabilities
|
|
25
29
|
* @property {boolean} hasTagProbabilities
|
|
26
30
|
* @property {boolean} blockingEnabled
|
|
31
|
+
* @property {unknown} redactionReplacements
|
|
27
32
|
*/
|
|
28
33
|
|
|
29
34
|
/**
|
|
30
35
|
* @typedef {object} EvaluationOutcome
|
|
31
36
|
* @property {{ action: string, reason: string|undefined, tags: Array<unknown>,
|
|
32
|
-
* tagProbabilities: Record<string, unknown>, sds: Array<unknown
|
|
37
|
+
* tagProbabilities: Record<string, unknown>, sds: Array<unknown>, messages: Message[],
|
|
38
|
+
* redactionReplacements: RedactionReplacement[] }} result
|
|
33
39
|
* @property {boolean} shouldBlock
|
|
34
40
|
* @property {boolean} hasTagProbabilities
|
|
41
|
+
* @property {{ enabled: boolean, applied: boolean, failures: number }} redaction
|
|
35
42
|
*/
|
|
36
43
|
|
|
37
44
|
/**
|
|
38
45
|
* @typedef {object} EvaluationMetaStruct
|
|
39
|
-
* @property {Message[]} messages
|
|
46
|
+
* @property {Message[]} [messages]
|
|
40
47
|
* @property {Array<unknown>} [attack_categories]
|
|
41
48
|
* @property {Array<unknown>} [sds]
|
|
42
49
|
* @property {Record<string, unknown>} [tag_probs]
|
|
@@ -45,6 +52,7 @@ const ALLOW = 'ALLOW'
|
|
|
45
52
|
/**
|
|
46
53
|
* @typedef {object} EvaluationReport
|
|
47
54
|
* @property {Span} span
|
|
55
|
+
* @property {Message[]} messages
|
|
48
56
|
* @property {EvaluationMetaStruct} metaStruct
|
|
49
57
|
* @property {{ source: string, integration: string }} telemetryTags
|
|
50
58
|
*/
|
|
@@ -79,6 +87,7 @@ function parseEvaluationResponse (body) {
|
|
|
79
87
|
tagProbabilities: isRecord(attributes.tag_probs) ? attributes.tag_probs : {},
|
|
80
88
|
hasTagProbabilities: isRecord(attributes.tag_probs),
|
|
81
89
|
blockingEnabled: attributes.is_blocking_enabled === true,
|
|
90
|
+
redactionReplacements: attributes.redaction_replacements,
|
|
82
91
|
}
|
|
83
92
|
}
|
|
84
93
|
|
|
@@ -96,11 +105,16 @@ function shouldBlockEvaluation (block, evaluation) {
|
|
|
96
105
|
/**
|
|
97
106
|
* Applies local evaluation policy and creates the result returned to the caller.
|
|
98
107
|
*
|
|
108
|
+
* @param {Message[]} messages
|
|
99
109
|
* @param {EvaluationResponse} evaluation
|
|
100
|
-
* @param {boolean}
|
|
110
|
+
* @param {{ block: boolean, redactionEnabled: boolean }} options
|
|
101
111
|
* @returns {EvaluationOutcome}
|
|
102
112
|
*/
|
|
103
|
-
function createEvaluationOutcome (evaluation,
|
|
113
|
+
function createEvaluationOutcome (messages, evaluation, options) {
|
|
114
|
+
const redaction = options.redactionEnabled
|
|
115
|
+
? redactMessages(messages, evaluation.redactionReplacements)
|
|
116
|
+
: { messages, redacted: false, failures: 0 }
|
|
117
|
+
|
|
104
118
|
return {
|
|
105
119
|
result: {
|
|
106
120
|
action: evaluation.action,
|
|
@@ -108,9 +122,16 @@ function createEvaluationOutcome (evaluation, block) {
|
|
|
108
122
|
tags: evaluation.tags,
|
|
109
123
|
tagProbabilities: evaluation.tagProbabilities,
|
|
110
124
|
sds: evaluation.sdsFindings,
|
|
125
|
+
messages: redaction.messages,
|
|
126
|
+
redactionReplacements: normalizeRedactionReplacements(evaluation.redactionReplacements),
|
|
111
127
|
},
|
|
112
|
-
shouldBlock: shouldBlockEvaluation(block, evaluation),
|
|
128
|
+
shouldBlock: shouldBlockEvaluation(options.block, evaluation),
|
|
113
129
|
hasTagProbabilities: evaluation.hasTagProbabilities,
|
|
130
|
+
redaction: {
|
|
131
|
+
enabled: options.redactionEnabled,
|
|
132
|
+
applied: redaction.redacted,
|
|
133
|
+
failures: redaction.failures,
|
|
134
|
+
},
|
|
114
135
|
}
|
|
115
136
|
}
|
|
116
137
|
|
|
@@ -130,6 +151,7 @@ class EvaluationReporter {
|
|
|
130
151
|
#config
|
|
131
152
|
#maxMessagesLength
|
|
132
153
|
#maxContentSize
|
|
154
|
+
#redactionEnabled
|
|
133
155
|
|
|
134
156
|
/**
|
|
135
157
|
* @param {import('../config/config-base')} config
|
|
@@ -138,6 +160,7 @@ class EvaluationReporter {
|
|
|
138
160
|
this.#config = config
|
|
139
161
|
this.#maxMessagesLength = config.experimental.aiguard.maxMessagesLength
|
|
140
162
|
this.#maxContentSize = config.experimental.aiguard.maxContentSize
|
|
163
|
+
this.#redactionEnabled = config.experimental.aiguard.redactionEnabled
|
|
141
164
|
}
|
|
142
165
|
|
|
143
166
|
/**
|
|
@@ -150,19 +173,18 @@ class EvaluationReporter {
|
|
|
150
173
|
*/
|
|
151
174
|
start (span, messages, options) {
|
|
152
175
|
const telemetryTags = { source: options.source, integration: options.integration }
|
|
153
|
-
const
|
|
176
|
+
const evaluatedMessages = this.#redactionEnabled ? clone(messages) : messages
|
|
177
|
+
const last = evaluatedMessages.at(-1)
|
|
154
178
|
const target = this.#isToolCall(last) ? 'tool' : 'prompt'
|
|
155
179
|
span.setTag(TAGS.TARGET_TAG_KEY, target)
|
|
156
180
|
if (target === 'tool') {
|
|
157
|
-
const name = this.#getToolName(last,
|
|
181
|
+
const name = this.#getToolName(last, evaluatedMessages)
|
|
158
182
|
if (name) {
|
|
159
183
|
span.setTag(TAGS.TOOL_NAME_TAG_KEY, name)
|
|
160
184
|
}
|
|
161
185
|
}
|
|
162
186
|
|
|
163
|
-
const metaStruct = {
|
|
164
|
-
messages: this.#buildMessagesForMetaStruct(messages, telemetryTags),
|
|
165
|
-
}
|
|
187
|
+
const metaStruct = {}
|
|
166
188
|
span.meta_struct = {
|
|
167
189
|
[TAGS.META_STRUCT_KEY]: metaStruct,
|
|
168
190
|
}
|
|
@@ -178,6 +200,7 @@ class EvaluationReporter {
|
|
|
178
200
|
|
|
179
201
|
return {
|
|
180
202
|
span,
|
|
203
|
+
messages: evaluatedMessages,
|
|
181
204
|
metaStruct,
|
|
182
205
|
telemetryTags,
|
|
183
206
|
}
|
|
@@ -191,6 +214,7 @@ class EvaluationReporter {
|
|
|
191
214
|
* @returns {void}
|
|
192
215
|
*/
|
|
193
216
|
fail (report, errorType) {
|
|
217
|
+
report.metaStruct.messages = this.#buildMessagesForMetaStruct(report.messages, report.telemetryTags)
|
|
194
218
|
aiguardMetrics.count(TAGS.TELEMETRY_REQUESTS, { error: true, ...report.telemetryTags }).inc(1)
|
|
195
219
|
aiguardMetrics.count(TAGS.TELEMETRY_ERROR, { type: errorType, ...report.telemetryTags }).inc(1)
|
|
196
220
|
}
|
|
@@ -203,18 +227,38 @@ class EvaluationReporter {
|
|
|
203
227
|
* @returns {void}
|
|
204
228
|
*/
|
|
205
229
|
finish (report, outcome) {
|
|
206
|
-
const { result, shouldBlock } = outcome
|
|
230
|
+
const { result, redaction, shouldBlock } = outcome
|
|
207
231
|
|
|
208
232
|
if (result.tags.length > 0) report.metaStruct.attack_categories = result.tags
|
|
209
233
|
if (result.sds.length > 0) report.metaStruct.sds = result.sds
|
|
210
234
|
if (outcome.hasTagProbabilities) report.metaStruct.tag_probs = result.tagProbabilities
|
|
211
235
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
236
|
+
if (redaction.enabled) {
|
|
237
|
+
report.span.setTag(TAGS.REDACTED_TAG_KEY, redaction.applied ? 'true' : 'false')
|
|
238
|
+
if (redaction.failures > 0) {
|
|
239
|
+
aiguardMetrics.count(TAGS.TELEMETRY_ERROR, {
|
|
240
|
+
type: TAGS.ERROR_TYPE_REDACTION,
|
|
241
|
+
...report.telemetryTags,
|
|
242
|
+
}).inc(redaction.failures)
|
|
243
|
+
}
|
|
217
244
|
}
|
|
245
|
+
|
|
246
|
+
report.metaStruct.messages = this.#buildMessagesForMetaStruct(result.messages, report.telemetryTags)
|
|
247
|
+
|
|
248
|
+
const requestTelemetryTags = redaction.enabled
|
|
249
|
+
? {
|
|
250
|
+
action: result.action,
|
|
251
|
+
error: false,
|
|
252
|
+
block: shouldBlock,
|
|
253
|
+
redacted: redaction.applied,
|
|
254
|
+
...report.telemetryTags,
|
|
255
|
+
}
|
|
256
|
+
: {
|
|
257
|
+
action: result.action,
|
|
258
|
+
error: false,
|
|
259
|
+
block: shouldBlock,
|
|
260
|
+
...report.telemetryTags,
|
|
261
|
+
}
|
|
218
262
|
aiguardMetrics.count(TAGS.TELEMETRY_REQUESTS, requestTelemetryTags).inc(1)
|
|
219
263
|
|
|
220
264
|
report.span.setTag(TAGS.ACTION_TAG_KEY, result.action)
|
|
@@ -242,10 +286,7 @@ class EvaluationReporter {
|
|
|
242
286
|
let contentTruncated = false
|
|
243
287
|
for (let i = messages.length - size; i < messages.length; i++) {
|
|
244
288
|
const message = clone(messages[i])
|
|
245
|
-
if (
|
|
246
|
-
contentTruncated = true
|
|
247
|
-
message.content = message.content.slice(0, this.#maxContentSize)
|
|
248
|
-
}
|
|
289
|
+
if (this.#truncateMessageContent(message)) contentTruncated = true
|
|
249
290
|
result.push(message)
|
|
250
291
|
}
|
|
251
292
|
if (contentTruncated) {
|
|
@@ -254,6 +295,40 @@ class EvaluationReporter {
|
|
|
254
295
|
return result
|
|
255
296
|
}
|
|
256
297
|
|
|
298
|
+
/**
|
|
299
|
+
* Truncates text in a cloned message to one shared content-size limit.
|
|
300
|
+
*
|
|
301
|
+
* @param {{ content?: string|ContentPart[] }} message
|
|
302
|
+
* @returns {boolean}
|
|
303
|
+
*/
|
|
304
|
+
#truncateMessageContent (message) {
|
|
305
|
+
const { content } = message
|
|
306
|
+
if (typeof content === 'string') {
|
|
307
|
+
if (content.length <= this.#maxContentSize) return false
|
|
308
|
+
|
|
309
|
+
message.content = content.slice(0, this.#maxContentSize)
|
|
310
|
+
return true
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (!Array.isArray(content)) return false
|
|
314
|
+
|
|
315
|
+
let remainingContentSize = this.#maxContentSize
|
|
316
|
+
let truncated = false
|
|
317
|
+
for (const part of content) {
|
|
318
|
+
const text = part?.text
|
|
319
|
+
if (typeof text !== 'string') continue
|
|
320
|
+
|
|
321
|
+
if (text.length > remainingContentSize) {
|
|
322
|
+
part.text = text.slice(0, remainingContentSize)
|
|
323
|
+
truncated = true
|
|
324
|
+
remainingContentSize = 0
|
|
325
|
+
} else {
|
|
326
|
+
remainingContentSize -= text.length
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return truncated
|
|
330
|
+
}
|
|
331
|
+
|
|
257
332
|
/**
|
|
258
333
|
* Returns whether a message represents a tool call or tool output.
|
|
259
334
|
*
|
|
@@ -74,18 +74,17 @@ function onStreamAfter (ctx) {
|
|
|
74
74
|
*/
|
|
75
75
|
function getStreamContent (chunks) {
|
|
76
76
|
const toolCalls = []
|
|
77
|
-
|
|
77
|
+
let text = ''
|
|
78
78
|
|
|
79
79
|
for (const chunk of chunks) {
|
|
80
80
|
if (chunk?.type === 'tool-call') {
|
|
81
81
|
toolCalls.push(chunk)
|
|
82
82
|
} else if (chunk?.type === 'text-delta') {
|
|
83
|
-
|
|
83
|
+
text += chunk.delta ?? chunk.textDelta ?? ''
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
if (toolCalls.length) return toolCalls
|
|
88
|
-
const text = textParts.join('')
|
|
89
88
|
return text ? [{ type: 'text', text }] : []
|
|
90
89
|
}
|
|
91
90
|
|
|
@@ -208,7 +208,14 @@ function walkContentBlocks (blocks) {
|
|
|
208
208
|
function partsToContent (parts, hasImages) {
|
|
209
209
|
if (!parts.length) return
|
|
210
210
|
if (hasImages) return parts
|
|
211
|
-
|
|
211
|
+
let content = ''
|
|
212
|
+
let isFirstPart = true
|
|
213
|
+
for (const part of parts) {
|
|
214
|
+
if (!isFirstPart) content += '\n'
|
|
215
|
+
content += part.text
|
|
216
|
+
isFirstPart = false
|
|
217
|
+
}
|
|
218
|
+
return content
|
|
212
219
|
}
|
|
213
220
|
|
|
214
221
|
/**
|
|
@@ -269,27 +276,39 @@ function convertServerToolResultContent (content) {
|
|
|
269
276
|
return content.error_message ? `${content.error_code}: ${content.error_message}` : content.error_code
|
|
270
277
|
}
|
|
271
278
|
|
|
272
|
-
|
|
279
|
+
let lines
|
|
273
280
|
if (Array.isArray(content)) {
|
|
274
281
|
for (const item of content) {
|
|
275
282
|
if (!item || typeof item !== 'object') continue
|
|
276
283
|
// text blocks (MCP / generic), then web-search title + url.
|
|
277
|
-
if (typeof item.text === 'string')
|
|
278
|
-
|
|
279
|
-
|
|
284
|
+
if (typeof item.text === 'string') {
|
|
285
|
+
lines = lines === undefined ? item.text : `${lines}\n${item.text}`
|
|
286
|
+
}
|
|
287
|
+
if (typeof item.title === 'string') {
|
|
288
|
+
lines = lines === undefined ? item.title : `${lines}\n${item.title}`
|
|
289
|
+
}
|
|
290
|
+
if (typeof item.url === 'string') {
|
|
291
|
+
lines = lines === undefined ? item.url : `${lines}\n${item.url}`
|
|
292
|
+
}
|
|
280
293
|
}
|
|
281
294
|
} else {
|
|
282
|
-
if (typeof content.stdout === 'string' && content.stdout) lines
|
|
283
|
-
if (typeof content.stderr === 'string' && content.stderr)
|
|
284
|
-
|
|
295
|
+
if (typeof content.stdout === 'string' && content.stdout) lines = content.stdout
|
|
296
|
+
if (typeof content.stderr === 'string' && content.stderr) {
|
|
297
|
+
lines = lines === undefined ? content.stderr : `${lines}\n${content.stderr}`
|
|
298
|
+
}
|
|
299
|
+
if (typeof content.content === 'string' && content.content) {
|
|
300
|
+
lines = lines === undefined ? content.content : `${lines}\n${content.content}`
|
|
301
|
+
}
|
|
285
302
|
if (Array.isArray(content.lines)) {
|
|
286
303
|
for (const line of content.lines) {
|
|
287
|
-
if (typeof line === 'string')
|
|
304
|
+
if (typeof line === 'string') {
|
|
305
|
+
lines = lines === undefined ? line : `${lines}\n${line}`
|
|
306
|
+
}
|
|
288
307
|
}
|
|
289
308
|
}
|
|
290
309
|
}
|
|
291
310
|
|
|
292
|
-
return lines
|
|
311
|
+
return lines || '[tool result]'
|
|
293
312
|
}
|
|
294
313
|
|
|
295
314
|
/**
|
|
@@ -322,7 +322,14 @@ function openAIResponseContentToMessageContent (content) {
|
|
|
322
322
|
|
|
323
323
|
if (!parts.length) return
|
|
324
324
|
if (hasImages) return parts
|
|
325
|
-
|
|
325
|
+
let textContent = ''
|
|
326
|
+
let isFirstPart = true
|
|
327
|
+
for (const part of parts) {
|
|
328
|
+
if (!isFirstPart) textContent += '\n'
|
|
329
|
+
textContent += part.text
|
|
330
|
+
isFirstPart = false
|
|
331
|
+
}
|
|
332
|
+
return textContent
|
|
326
333
|
}
|
|
327
334
|
|
|
328
335
|
/**
|
|
@@ -62,19 +62,26 @@ function convertVercelPromptToMessages (prompt) {
|
|
|
62
62
|
if (hasImages) {
|
|
63
63
|
messages.push({ role: 'user', content: contentParts })
|
|
64
64
|
} else {
|
|
65
|
-
|
|
65
|
+
let content = ''
|
|
66
|
+
let isFirstPart = true
|
|
67
|
+
for (const part of contentParts) {
|
|
68
|
+
if (!isFirstPart) content += '\n'
|
|
69
|
+
content += part.text
|
|
70
|
+
isFirstPart = false
|
|
71
|
+
}
|
|
72
|
+
messages.push({ role: 'user', content })
|
|
66
73
|
}
|
|
67
74
|
break
|
|
68
75
|
}
|
|
69
76
|
|
|
70
77
|
case 'assistant': {
|
|
71
|
-
|
|
78
|
+
let text
|
|
72
79
|
const toolCalls = []
|
|
73
80
|
if (!Array.isArray(msg.content)) break
|
|
74
81
|
|
|
75
82
|
for (const part of msg.content) {
|
|
76
83
|
if (part.type === 'text') {
|
|
77
|
-
|
|
84
|
+
text = text === undefined ? part.text : `${text}\n${part.text}`
|
|
78
85
|
} else if (part.type === 'tool-call') {
|
|
79
86
|
toolCalls.push({
|
|
80
87
|
id: part.toolCallId,
|
|
@@ -88,8 +95,8 @@ function convertVercelPromptToMessages (prompt) {
|
|
|
88
95
|
|
|
89
96
|
if (toolCalls.length > 0) {
|
|
90
97
|
messages.push({ role: 'assistant', tool_calls: toolCalls })
|
|
91
|
-
} else if (
|
|
92
|
-
messages.push({ role: 'assistant', content:
|
|
98
|
+
} else if (text !== undefined) {
|
|
99
|
+
messages.push({ role: 'assistant', content: text })
|
|
93
100
|
}
|
|
94
101
|
break
|
|
95
102
|
}
|
|
@@ -161,7 +168,14 @@ function buildTextOutputMessages (inputMessages, text) {
|
|
|
161
168
|
function buildOutputMessages (inputMessages, content) {
|
|
162
169
|
const toolCalls = content.filter(c => c.type === 'tool-call')
|
|
163
170
|
if (toolCalls.length) return buildToolCallOutputMessages(inputMessages, toolCalls)
|
|
164
|
-
|
|
171
|
+
let text = ''
|
|
172
|
+
let isFirstTextPart = true
|
|
173
|
+
for (const part of content) {
|
|
174
|
+
if (part.type !== 'text') continue
|
|
175
|
+
if (!isFirstTextPart) text += '\n'
|
|
176
|
+
text += part.text
|
|
177
|
+
isFirstTextPart = false
|
|
178
|
+
}
|
|
165
179
|
if (text) return buildTextOutputMessages(inputMessages, text)
|
|
166
180
|
return []
|
|
167
181
|
}
|
|
@@ -2,7 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
class NoopAIGuard {
|
|
4
4
|
evaluate (messages, opts) {
|
|
5
|
-
return Promise.resolve({
|
|
5
|
+
return Promise.resolve({
|
|
6
|
+
action: 'ALLOW',
|
|
7
|
+
reason: 'AI Guard is not enabled',
|
|
8
|
+
tags: [],
|
|
9
|
+
tagProbabilities: {},
|
|
10
|
+
sds: [],
|
|
11
|
+
messages,
|
|
12
|
+
redactionReplacements: [],
|
|
13
|
+
})
|
|
6
14
|
}
|
|
7
15
|
}
|
|
8
16
|
|