dd-trace 5.128.0 → 5.130.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 +1 -0
- package/ci/vitest-no-worker-init-setup.mjs +22 -12
- package/index.d.ts +55 -11
- package/package.json +6 -6
- package/packages/datadog-instrumentations/src/anthropic.js +111 -9
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +5 -1
- package/packages/datadog-instrumentations/src/cucumber.js +50 -9
- package/packages/datadog-instrumentations/src/cypress-config.js +27 -15
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +6 -0
- package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +0 -6
- package/packages/datadog-instrumentations/src/helpers/register.js +20 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +41 -4
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentation-registry.js +15 -13
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +51 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +13 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.js +28 -3
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +6 -0
- package/packages/datadog-instrumentations/src/jest/session-error.js +102 -0
- package/packages/datadog-instrumentations/src/jest.js +30 -13
- package/packages/datadog-instrumentations/src/mocha/main.js +7 -5
- package/packages/datadog-instrumentations/src/mocha/utils.js +8 -8
- package/packages/datadog-instrumentations/src/playwright-reporter.js +3 -4
- package/packages/datadog-instrumentations/src/playwright.js +73 -6
- package/packages/datadog-instrumentations/src/undici.js +7 -3
- package/packages/datadog-instrumentations/src/vitest-main.js +95 -21
- package/packages/datadog-instrumentations/src/vitest-worker.js +34 -3
- package/packages/datadog-instrumentations/src/webdriverio.js +28 -12
- package/packages/datadog-instrumentations/src/ws.js +41 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +83 -29
- package/packages/datadog-plugin-cucumber/src/index.js +22 -8
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +51 -14
- package/packages/datadog-plugin-cypress/src/index.js +3 -1
- package/packages/datadog-plugin-fetch/src/index.js +3 -0
- package/packages/datadog-plugin-jest/src/index.js +3 -4
- package/packages/datadog-plugin-mocha/src/index.js +3 -4
- package/packages/datadog-plugin-oracledb/src/connection-parser.js +3 -1
- package/packages/datadog-plugin-playwright/src/index.js +11 -6
- package/packages/datadog-plugin-undici/src/index.js +5 -0
- package/packages/datadog-plugin-vitest/src/index.js +3 -4
- package/packages/datadog-plugin-ws/src/producer.js +1 -1
- package/packages/datadog-shimmer/src/shimmer.js +14 -10
- package/packages/datadog-turbopack/index.js +4 -1
- package/packages/datadog-turbopack/src/loader.js +6 -2
- package/packages/dd-trace/src/agent/info.js +5 -4
- package/packages/dd-trace/src/aiguard/client.js +38 -19
- package/packages/dd-trace/src/aiguard/integrations/anthropic.js +29 -4
- package/packages/dd-trace/src/aiguard/integrations/index.js +1 -1
- package/packages/dd-trace/src/aiguard/integrations/openai.js +20 -56
- package/packages/dd-trace/src/aiguard/integrations/stream.js +60 -0
- package/packages/dd-trace/src/aiguard/messages/anthropic.js +64 -0
- package/packages/dd-trace/src/config/generated-config-types.d.ts +19 -19
- package/packages/dd-trace/src/config/index.js +7 -6
- package/packages/dd-trace/src/config/supported-configurations.json +16 -5
- package/packages/dd-trace/src/constants.js +2 -0
- package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -1
- package/packages/dd-trace/src/debugger/devtools_client/send.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +5 -3
- package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -1
- package/packages/dd-trace/src/debugger/index.js +1 -1
- package/packages/dd-trace/src/evp_proxy/constants.js +2 -0
- package/packages/dd-trace/src/evp_proxy/direct.js +17 -13
- package/packages/dd-trace/src/evp_proxy/discovery.js +14 -10
- package/packages/dd-trace/src/evp_proxy/path.js +21 -7
- package/packages/dd-trace/src/exporters/common/url.js +33 -2
- package/packages/dd-trace/src/llmobs/constants/tags.js +31 -8
- package/packages/dd-trace/src/llmobs/gen-ai-tags.js +127 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/ddTelemetry.js +18 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/vercelTelemetry.js +33 -8
- package/packages/dd-trace/src/llmobs/plugins/anthropic/index.js +77 -41
- package/packages/dd-trace/src/llmobs/plugins/base.js +154 -15
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +162 -10
- package/packages/dd-trace/src/llmobs/plugins/claude-agent-sdk/index.js +65 -16
- package/packages/dd-trace/src/llmobs/plugins/genai/index.js +14 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +34 -35
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +10 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +25 -2
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +8 -7
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +13 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/realtime.js +5 -0
- package/packages/dd-trace/src/llmobs/plugins/vertexai.js +7 -0
- package/packages/dd-trace/src/llmobs/prompts/manager.js +10 -2
- package/packages/dd-trace/src/llmobs/prompts/prompt.js +79 -12
- package/packages/dd-trace/src/llmobs/span_processor.js +10 -65
- package/packages/dd-trace/src/llmobs/tagger.js +11 -40
- package/packages/dd-trace/src/openfeature/configuration_source.js +4 -1
- package/packages/dd-trace/src/openfeature/flagging_provider.js +3 -3
- package/packages/dd-trace/src/openfeature/index.js +6 -2
- package/packages/dd-trace/src/openfeature/writers/base.js +90 -17
- package/packages/dd-trace/src/openfeature/writers/exposures.js +4 -0
- package/packages/dd-trace/src/openfeature/writers/util.js +104 -33
- package/packages/dd-trace/src/opentelemetry/trace/index.js +5 -0
- package/packages/dd-trace/src/opentracing/tracer.js +3 -3
- package/packages/dd-trace/src/plugin_manager.js +27 -8
- package/packages/dd-trace/src/plugins/ci_plugin.js +1 -1
- package/packages/dd-trace/src/plugins/util/test.js +13 -4
- package/packages/dd-trace/src/profiler.js +51 -5
- package/packages/dd-trace/src/profiling/profiler.js +24 -20
- package/packages/dd-trace/src/proxy.js +2 -2
- package/packages/dd-trace/src/ritm.js +12 -9
- package/packages/dd-trace/src/span_processor.js +6 -1
- package/packages/dd-trace/src/telemetry/send-data.js +2 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +1 -1
- package/packages/dd-trace/src/tracer.js +5 -4
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
- package/packages/datadog-instrumentations/src/azure-cosmos.js +0 -7
- package/packages/datadog-instrumentations/src/bullmq.js +0 -11
- package/packages/datadog-instrumentations/src/langchain.js +0 -7
- package/packages/datadog-instrumentations/src/langgraph.js +0 -7
- package/packages/datadog-instrumentations/src/mercurius.js +0 -11
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"component","origin","license","copyright"
|
|
2
2
|
"@apm-js-collab/code-transformer","https://github.com/nodejs/orchestrion-js","['Apache-2.0']","['nodejs']"
|
|
3
|
+
"@bufbuild/protobuf","https://github.com/bufbuild/protobuf-es","['(Apache-2.0 AND BSD-3-Clause)']","['bufbuild']"
|
|
3
4
|
"@datadog/flagging-core","https://github.com/DataDog/openfeature-js-client","['Apache-2.0']","['DataDog']"
|
|
4
5
|
"@datadog/libdatadog","https://github.com/DataDog/libdatadog-nodejs","['Apache-2.0']","['DataDog']"
|
|
5
6
|
"@datadog/libdatadog-extras","https://github.com/DataDog/libdatadog-nodejs","['Apache-2.0']","['Datadog Inc.']"
|
|
@@ -114,14 +114,12 @@ if (isNoWorkerInitActive) {
|
|
|
114
114
|
onTestFinished(() => {
|
|
115
115
|
recordTestAttemptTiming(task, attemptIndex, attemptStart)
|
|
116
116
|
recordRetryErrorCount(task)
|
|
117
|
-
if (
|
|
118
|
-
(isAttemptToFixTest
|
|
119
|
-
attemptIndex === getFinalAttemptIndex(task)
|
|
120
|
-
) {
|
|
117
|
+
if (isEarlyFlakeDetectionTestAttempt || isQuarantinedTest ||
|
|
118
|
+
(isAttemptToFixTest && attemptIndex === getFinalAttemptIndex(task))) {
|
|
121
119
|
if (isAttemptToFixTest || isEarlyFlakeDetectionTestAttempt) {
|
|
122
|
-
recordTestOptimizationStatus(task, attemptIndex,
|
|
120
|
+
recordTestOptimizationStatus(task, attemptIndex, attemptIndex === getFinalAttemptIndex(task))
|
|
123
121
|
}
|
|
124
|
-
switchQuarantinedFinalFailure(task
|
|
122
|
+
switchQuarantinedFinalFailure(task)
|
|
125
123
|
}
|
|
126
124
|
finishRumCorrelation(task, attemptIndex)
|
|
127
125
|
})
|
|
@@ -134,7 +132,7 @@ if (isNoWorkerInitActive) {
|
|
|
134
132
|
recordTestOptimizationStatus(task, attemptIndex)
|
|
135
133
|
}
|
|
136
134
|
if (!restoredEarlyFlakeDetectionResult) {
|
|
137
|
-
switchQuarantinedFinalFailure(task
|
|
135
|
+
switchQuarantinedFinalFailure(task)
|
|
138
136
|
}
|
|
139
137
|
})
|
|
140
138
|
}
|
|
@@ -433,7 +431,10 @@ function recordEarlyFlakeDetectionStatus (task, attemptIndex, onlyIfNewErrors) {
|
|
|
433
431
|
return
|
|
434
432
|
}
|
|
435
433
|
|
|
436
|
-
|
|
434
|
+
// onTestFinished runs before aroundEach fixture teardown. Select the budget
|
|
435
|
+
// when the next attempt records the completed attempt instead.
|
|
436
|
+
const isCompletedAttempt = attemptIndex < task.meta.__ddTestOptCurrentAttemptIndex
|
|
437
|
+
if (isCompletedAttempt && !earlyFlakeDetectionRetriesByTask.has(task)) {
|
|
437
438
|
const retryCount = getEarlyFlakeDetectionRetryCount(task)
|
|
438
439
|
earlyFlakeDetectionRetriesByTask.set(task, retryCount)
|
|
439
440
|
task.repeats = retryCount
|
|
@@ -452,9 +453,15 @@ function recordEarlyFlakeDetectionStatus (task, attemptIndex, onlyIfNewErrors) {
|
|
|
452
453
|
)
|
|
453
454
|
task.meta.__ddTestOptEfdErrorCounts[attemptIndex] = task.result?.errors?.length || 0
|
|
454
455
|
|
|
455
|
-
|
|
456
|
+
// Vitest 5.0.3 retains failures across repeats. Defer EFD's overall failure until
|
|
457
|
+
// the last attempt, while keeping each attempt's actual outcome in the metadata.
|
|
458
|
+
if (attemptIndex < getEarlyFlakeDetectionRetryCountForTask(task) ||
|
|
456
459
|
task.meta.__ddTestOptEfdStatuses.includes('pass')) {
|
|
457
460
|
task.result.state = 'pass'
|
|
461
|
+
} else if (isCompletedAttempt) {
|
|
462
|
+
// A zero retry budget cancels repeats after we suppressed the initial failure.
|
|
463
|
+
task.result.state = 'fail'
|
|
464
|
+
markQuarantinedFailure(task)
|
|
458
465
|
}
|
|
459
466
|
}
|
|
460
467
|
|
|
@@ -525,7 +532,7 @@ function wrapRetryCondition (task) {
|
|
|
525
532
|
shouldRetry = condition(error)
|
|
526
533
|
}
|
|
527
534
|
|
|
528
|
-
if (!shouldRetry
|
|
535
|
+
if (!shouldRetry) {
|
|
529
536
|
const attemptIndex = task.meta.__ddTestOptCurrentAttemptIndex
|
|
530
537
|
recordTestOptimizationStatus(task, attemptIndex)
|
|
531
538
|
markQuarantinedFailure(task)
|
|
@@ -579,7 +586,7 @@ function getFinalAttemptIndex (task) {
|
|
|
579
586
|
return attemptIndex + retriesRemaining + (repeatsRemaining * (retryLimit + 1))
|
|
580
587
|
}
|
|
581
588
|
|
|
582
|
-
function switchQuarantinedFinalFailure (task
|
|
589
|
+
function switchQuarantinedFinalFailure (task) {
|
|
583
590
|
const testSuite = getTestSuite(task)
|
|
584
591
|
const testName = getTestName(task)
|
|
585
592
|
if (
|
|
@@ -590,7 +597,10 @@ function switchQuarantinedFinalFailure (task, attemptIndex) {
|
|
|
590
597
|
return
|
|
591
598
|
}
|
|
592
599
|
|
|
593
|
-
|
|
600
|
+
// Finish the retries in this repetition before suppressing its failure. A later
|
|
601
|
+
// repetition cannot undo a failure that Vitest has already aggregated.
|
|
602
|
+
const retryAttemptIndex = retryAttemptIndexByTask.get(task)?.index || 0
|
|
603
|
+
if (retryAttemptIndex < getRetryLimit(task)) {
|
|
594
604
|
return
|
|
595
605
|
}
|
|
596
606
|
|
package/index.d.ts
CHANGED
|
@@ -2137,8 +2137,9 @@ declare namespace tracer {
|
|
|
2137
2137
|
/**
|
|
2138
2138
|
* Whether to capture LLM Observability spans for this integration. When set to `false`,
|
|
2139
2139
|
* the integration keeps emitting APM spans and propagating trace context, but no LLM
|
|
2140
|
-
* Observability spans are produced. Useful when another
|
|
2141
|
-
* same operation and the payloads would otherwise be
|
|
2140
|
+
* Observability spans and no basic `gen_ai.*` APM tags are produced. Useful when another
|
|
2141
|
+
* integration already captures the same operation and the payloads would otherwise be
|
|
2142
|
+
* stored twice.
|
|
2142
2143
|
* @default true
|
|
2143
2144
|
*/
|
|
2144
2145
|
llmobs?: boolean;
|
|
@@ -4083,13 +4084,13 @@ declare namespace tracer {
|
|
|
4083
4084
|
/** Create a text or chat prompt and its first version. */
|
|
4084
4085
|
createPrompt (
|
|
4085
4086
|
promptId: string,
|
|
4086
|
-
template: string |
|
|
4087
|
+
template: string | PromptTemplateItem[],
|
|
4087
4088
|
options?: CreatePromptOptions
|
|
4088
4089
|
): Promise<PromptResponse>
|
|
4089
4090
|
/** Add a text or chat version to an existing prompt. */
|
|
4090
4091
|
createPromptVersion (
|
|
4091
4092
|
promptId: string,
|
|
4092
|
-
template: string |
|
|
4093
|
+
template: string | PromptTemplateItem[],
|
|
4093
4094
|
options?: CreatePromptVersionOptions
|
|
4094
4095
|
): Promise<PromptVersionResponse>
|
|
4095
4096
|
/** Update prompt metadata. */
|
|
@@ -4113,10 +4114,45 @@ declare namespace tracer {
|
|
|
4113
4114
|
content: string
|
|
4114
4115
|
}
|
|
4115
4116
|
|
|
4117
|
+
/** Provider fields on expanded messages; authored templates remain text-only. */
|
|
4118
|
+
interface FormattedPromptMessage extends PromptTemplateMessage {
|
|
4119
|
+
// The inherited content type stays string for compatibility; tool-only payloads can omit it or contain null.
|
|
4120
|
+
tool_calls?: PromptToolCall[] | null,
|
|
4121
|
+
tool_results?: PromptToolResult[] | null,
|
|
4122
|
+
tool_call_id?: string | null
|
|
4123
|
+
}
|
|
4124
|
+
|
|
4125
|
+
interface PromptToolCall {
|
|
4126
|
+
id?: string | null,
|
|
4127
|
+
type?: string | null,
|
|
4128
|
+
tool_id?: string | null,
|
|
4129
|
+
name?: string | null,
|
|
4130
|
+
arguments?: unknown,
|
|
4131
|
+
function?: {
|
|
4132
|
+
name: string,
|
|
4133
|
+
arguments: string
|
|
4134
|
+
} | null
|
|
4135
|
+
}
|
|
4136
|
+
|
|
4137
|
+
interface PromptToolResult {
|
|
4138
|
+
id?: string | null,
|
|
4139
|
+
type?: string | null,
|
|
4140
|
+
tool_id?: string | null,
|
|
4141
|
+
name?: string | null,
|
|
4142
|
+
result?: unknown
|
|
4143
|
+
}
|
|
4144
|
+
|
|
4145
|
+
interface PromptMessagePlaceholder {
|
|
4146
|
+
type: 'placeholder',
|
|
4147
|
+
name: string
|
|
4148
|
+
}
|
|
4149
|
+
|
|
4150
|
+
type PromptTemplateItem = PromptTemplateMessage | PromptMessagePlaceholder
|
|
4151
|
+
|
|
4116
4152
|
type PromptFallbackValue =
|
|
4117
4153
|
| string
|
|
4118
|
-
|
|
|
4119
|
-
| { template: string |
|
|
4154
|
+
| PromptTemplateItem[]
|
|
4155
|
+
| { template: string | PromptTemplateItem[], version?: string, config?: Record<string, JSONType> }
|
|
4120
4156
|
type PromptFallback = PromptFallbackValue | (() => PromptFallbackValue)
|
|
4121
4157
|
|
|
4122
4158
|
interface GetPromptOptions {
|
|
@@ -4135,13 +4171,15 @@ declare namespace tracer {
|
|
|
4135
4171
|
title?: string,
|
|
4136
4172
|
description?: string,
|
|
4137
4173
|
userVersion?: string,
|
|
4138
|
-
envIds?: string[]
|
|
4174
|
+
envIds?: string[],
|
|
4175
|
+
config?: Record<string, JSONType>
|
|
4139
4176
|
}
|
|
4140
4177
|
|
|
4141
4178
|
interface CreatePromptVersionOptions {
|
|
4142
4179
|
description?: string,
|
|
4143
4180
|
userVersion?: string,
|
|
4144
|
-
envIds?: string[]
|
|
4181
|
+
envIds?: string[],
|
|
4182
|
+
config?: Record<string, JSONType>
|
|
4145
4183
|
}
|
|
4146
4184
|
|
|
4147
4185
|
interface UpdatePromptOptions {
|
|
@@ -4154,14 +4192,16 @@ declare namespace tracer {
|
|
|
4154
4192
|
envIds?: string[]
|
|
4155
4193
|
}
|
|
4156
4194
|
|
|
4195
|
+
// Preserve released output types; placeholder entries and null/omitted tool content are not fully described here.
|
|
4157
4196
|
interface ManagedPrompt {
|
|
4158
4197
|
readonly id: string,
|
|
4159
4198
|
readonly version: string,
|
|
4160
4199
|
readonly source: 'registry' | 'cache' | 'fallback' | 'ff' | 'resolve',
|
|
4161
4200
|
readonly template: string | ReadonlyArray<Readonly<PromptTemplateMessage>>,
|
|
4201
|
+
readonly config: Readonly<Record<string, ReadonlyJSONType>>,
|
|
4162
4202
|
readonly promptUuid?: string,
|
|
4163
4203
|
readonly promptVersionUuid?: string,
|
|
4164
|
-
format (variables?: Record<string, unknown>): string |
|
|
4204
|
+
format (variables?: Record<string, unknown>): string | FormattedPromptMessage[]
|
|
4165
4205
|
toAnnotation (variables?: Record<string, unknown>): Prompt
|
|
4166
4206
|
}
|
|
4167
4207
|
|
|
@@ -4179,7 +4219,8 @@ declare namespace tracer {
|
|
|
4179
4219
|
ml_app?: string,
|
|
4180
4220
|
ml_apps?: string[],
|
|
4181
4221
|
last_version_created_at?: string,
|
|
4182
|
-
extracted_from?: string
|
|
4222
|
+
extracted_from?: string,
|
|
4223
|
+
config?: Record<string, JSONType>
|
|
4183
4224
|
}
|
|
4184
4225
|
|
|
4185
4226
|
interface PromptVersionResponse {
|
|
@@ -4193,7 +4234,8 @@ declare namespace tracer {
|
|
|
4193
4234
|
version_created_at?: string,
|
|
4194
4235
|
author?: string,
|
|
4195
4236
|
description?: string,
|
|
4196
|
-
ml_app?: string
|
|
4237
|
+
ml_app?: string,
|
|
4238
|
+
config?: Record<string, JSONType>
|
|
4197
4239
|
}
|
|
4198
4240
|
|
|
4199
4241
|
interface DeletedPromptResponse {
|
|
@@ -4205,6 +4247,8 @@ declare namespace tracer {
|
|
|
4205
4247
|
/** JSON-serializable value accepted by LLMObs Experiments. */
|
|
4206
4248
|
type JSONType = string | number | boolean | null | JSONType[] | { [key: string]: JSONType }
|
|
4207
4249
|
|
|
4250
|
+
type ReadonlyJSONType = string | number | boolean | null | ReadonlyArray<ReadonlyJSONType> | { readonly [key: string]: ReadonlyJSONType }
|
|
4251
|
+
|
|
4208
4252
|
/**
|
|
4209
4253
|
* A task run over each dataset record during an experiment.
|
|
4210
4254
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.130.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -206,7 +206,7 @@
|
|
|
206
206
|
"@eslint/eslintrc": "^3.3.7",
|
|
207
207
|
"@eslint/js": "^10.0.1",
|
|
208
208
|
"@eslint/plugin-kit": "^0.7.3",
|
|
209
|
-
"@datadog/openfeature-node-server": "2.
|
|
209
|
+
"@datadog/openfeature-node-server": "2.4.0",
|
|
210
210
|
"@msgpack/msgpack": "^3.1.3",
|
|
211
211
|
"@openfeature/core": "^1.12.0",
|
|
212
212
|
"@openfeature/server-sdk": "~1.23.0",
|
|
@@ -222,14 +222,14 @@
|
|
|
222
222
|
"bun": "1.4.2",
|
|
223
223
|
"c8": "^12.0.0",
|
|
224
224
|
"codeowners-audit": "^2.9.0",
|
|
225
|
-
"eslint": "^10.
|
|
225
|
+
"eslint": "^10.11.0",
|
|
226
226
|
"eslint-plugin-cypress": "^7.0.2",
|
|
227
227
|
"eslint-plugin-import-x": "^4.16.2",
|
|
228
|
-
"eslint-plugin-jsdoc": "^64.5.
|
|
228
|
+
"eslint-plugin-jsdoc": "^64.5.4",
|
|
229
229
|
"eslint-plugin-mocha": "^12.0.2",
|
|
230
230
|
"eslint-plugin-n": "^18.3.0",
|
|
231
231
|
"eslint-plugin-promise": "^7.3.0",
|
|
232
|
-
"eslint-plugin-regexp": "^3.3.
|
|
232
|
+
"eslint-plugin-regexp": "^3.3.1",
|
|
233
233
|
"eslint-plugin-sonarjs": "^4.2.1",
|
|
234
234
|
"eslint-plugin-unicorn": "^74.0.0",
|
|
235
235
|
"express": "^5.1.0",
|
|
@@ -251,7 +251,7 @@
|
|
|
251
251
|
"node-preload": "^0.2.1",
|
|
252
252
|
"nyc": "^18.0.0",
|
|
253
253
|
"octokit": "^5.0.3",
|
|
254
|
-
"p-limit": "^7.3.
|
|
254
|
+
"p-limit": "^7.3.3",
|
|
255
255
|
"proxyquire": "^2.1.3",
|
|
256
256
|
"retry": "^0.13.1",
|
|
257
257
|
"semifies": "^1.0.0",
|
|
@@ -124,13 +124,48 @@ function wrapStreamIterator (iterator, ctx) {
|
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Gives the SDK a detached copy of the response to decode, leaving the body the caller can still
|
|
129
|
+
* read through `asResponse()` untouched. The bytes are buffered instead of streamed from a live
|
|
130
|
+
* clone, and the controller is replaced, because the SDK cancels its reader and aborts its
|
|
131
|
+
* controller whenever a stream ends early: that abort would kill the caller's request, and on a
|
|
132
|
+
* cloned body that cancel blocks until the other branch is read, which the caller cannot do while
|
|
133
|
+
* it is still waiting for this parse.
|
|
134
|
+
*
|
|
135
|
+
* Any failure falls back to the original props and tells the wrapper to skip inspection, leaving
|
|
136
|
+
* the SDK to behave as it does untraced.
|
|
137
|
+
*
|
|
138
|
+
* @param {{response: Response}} props
|
|
139
|
+
* @param {() => void} onFailure
|
|
140
|
+
* @returns {object|Promise<object>}
|
|
141
|
+
*/
|
|
142
|
+
function detachResponse (props, onFailure) {
|
|
143
|
+
const { status, statusText, headers } = props.response
|
|
144
|
+
try {
|
|
145
|
+
return props.response.clone().arrayBuffer()
|
|
146
|
+
.then(body => ({
|
|
147
|
+
...props,
|
|
148
|
+
response: new Response(body, { status, statusText, headers }),
|
|
149
|
+
controller: new AbortController(),
|
|
150
|
+
}))
|
|
151
|
+
.catch(() => {
|
|
152
|
+
onFailure()
|
|
153
|
+
return props
|
|
154
|
+
})
|
|
155
|
+
} catch {
|
|
156
|
+
onFailure()
|
|
157
|
+
return props
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
127
161
|
function wrapCreate (create) {
|
|
128
162
|
return function (...args) {
|
|
129
163
|
const stream = args[0]?.stream
|
|
130
|
-
const
|
|
131
|
-
const
|
|
164
|
+
const tracing = anthropicTracingChannel.start.hasSubscribers
|
|
165
|
+
const preparing = messagesPrepareChannel.hasSubscribers
|
|
166
|
+
const intercepting = messagesInterceptChannel.hasSubscribers
|
|
132
167
|
|
|
133
|
-
if (!
|
|
168
|
+
if (!tracing && !preparing && !intercepting) {
|
|
134
169
|
return create.apply(this, args)
|
|
135
170
|
}
|
|
136
171
|
|
|
@@ -160,23 +195,60 @@ function wrapCreate (create) {
|
|
|
160
195
|
|
|
161
196
|
let parseResult
|
|
162
197
|
let wrappedResponse
|
|
198
|
+
// Set around a `parse()` whose body a raw-response reader also holds, so the SDK decodes a
|
|
199
|
+
// copy and leaves that body to the caller. Plain streaming has no second reader and copies
|
|
200
|
+
// nothing.
|
|
201
|
+
let detach = false
|
|
163
202
|
|
|
203
|
+
// These helpers live on each returned APIPromise, so there is no module export for
|
|
204
|
+
// Orchestrion to replace; wrap this instance instead.
|
|
164
205
|
shimmer.wrap(apiPromise, 'parse', parse => function (...parseArgs) {
|
|
165
206
|
if (parseResult) return parseResult
|
|
166
207
|
|
|
167
|
-
|
|
208
|
+
let detachmentFailed = false
|
|
209
|
+
const responsePromise = detach ? this.responsePromise : undefined
|
|
210
|
+
if (responsePromise) {
|
|
211
|
+
this.responsePromise = responsePromise.then(props => detachResponse(props, () => {
|
|
212
|
+
detachmentFailed = true
|
|
213
|
+
}))
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
let result
|
|
217
|
+
try {
|
|
218
|
+
result = parse.apply(this, parseArgs)
|
|
219
|
+
} finally {
|
|
220
|
+
if (responsePromise) this.responsePromise = responsePromise
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const onResult = interceptCtx?.onResult
|
|
224
|
+
parseResult = heldUntil(result, interceptCtx?.beforeResult?.())
|
|
168
225
|
.then(response => {
|
|
169
226
|
if (stream) {
|
|
170
|
-
|
|
171
|
-
|
|
227
|
+
if (!onResult || detachmentFailed) {
|
|
228
|
+
if (tracing) {
|
|
229
|
+
shimmer.wrap(response, Symbol.asyncIterator, iterator => wrapStreamIterator(iterator, ctx))
|
|
230
|
+
}
|
|
231
|
+
return response
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return Promise.resolve(onResult(response)).then(deliveredResponse => {
|
|
235
|
+
if (tracing) {
|
|
236
|
+
shimmer.wrap(
|
|
237
|
+
deliveredResponse,
|
|
238
|
+
Symbol.asyncIterator,
|
|
239
|
+
iterator => wrapStreamIterator(iterator, ctx)
|
|
240
|
+
)
|
|
241
|
+
}
|
|
242
|
+
return deliveredResponse
|
|
243
|
+
})
|
|
172
244
|
}
|
|
173
245
|
|
|
174
|
-
if (!
|
|
246
|
+
if (!onResult) {
|
|
175
247
|
finish(ctx, response)
|
|
176
248
|
return response
|
|
177
249
|
}
|
|
178
250
|
|
|
179
|
-
return Promise.resolve(
|
|
251
|
+
return Promise.resolve(onResult(response)).then(deliveredResponse => {
|
|
180
252
|
finish(ctx, response)
|
|
181
253
|
return deliveredResponse
|
|
182
254
|
})
|
|
@@ -190,9 +262,26 @@ function wrapCreate (create) {
|
|
|
190
262
|
shimmer.wrap(apiPromise, 'asResponse', origAsResponse => function (...asResponseArgs) {
|
|
191
263
|
return heldUntil(origAsResponse.apply(this, asResponseArgs), interceptCtx?.beforeResult?.())
|
|
192
264
|
.then(response => {
|
|
265
|
+
if (stream) {
|
|
266
|
+
// A caller holding the parsed stream closes the span as it drains it. When only
|
|
267
|
+
// the raw body is read, decode the stream here so it is still evaluated.
|
|
268
|
+
if (!interceptCtx?.onResult) return response
|
|
269
|
+
if (parseResult) return parseResult.then(() => response)
|
|
270
|
+
|
|
271
|
+
detach = true
|
|
272
|
+
try {
|
|
273
|
+
return apiPromise.parse().then(() => {
|
|
274
|
+
finish(ctx)
|
|
275
|
+
return response
|
|
276
|
+
})
|
|
277
|
+
} finally {
|
|
278
|
+
detach = false
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
193
282
|
// Wrap json()/text()/clone() so the span still closes on the raw-response path,
|
|
194
283
|
// and not twice for the same response.
|
|
195
|
-
if (
|
|
284
|
+
if (wrappedResponse !== response) {
|
|
196
285
|
wrappedResponse = response
|
|
197
286
|
wrapRawResponse(response, ctx, interceptCtx)
|
|
198
287
|
}
|
|
@@ -202,6 +291,19 @@ function wrapCreate (create) {
|
|
|
202
291
|
})
|
|
203
292
|
}
|
|
204
293
|
|
|
294
|
+
// `withResponse()` is the one SDK call that hands out the raw response *and* the parsed
|
|
295
|
+
// stream; it invokes `parse()` synchronously, so the flag only has to outlive that call.
|
|
296
|
+
if (stream && interceptCtx?.onResult && typeof apiPromise.withResponse === 'function') {
|
|
297
|
+
shimmer.wrap(apiPromise, 'withResponse', withResponse => function (...withResponseArgs) {
|
|
298
|
+
detach = true
|
|
299
|
+
try {
|
|
300
|
+
return withResponse.apply(this, withResponseArgs)
|
|
301
|
+
} finally {
|
|
302
|
+
detach = false
|
|
303
|
+
}
|
|
304
|
+
})
|
|
305
|
+
}
|
|
306
|
+
|
|
205
307
|
anthropicTracingChannel.end.publish(ctx)
|
|
206
308
|
|
|
207
309
|
return apiPromise
|
|
@@ -44,6 +44,7 @@ const chunkEmitTimes = new WeakMap()
|
|
|
44
44
|
* tools: Map<string, ToolState>,
|
|
45
45
|
* subagents: Map<string, Record<string, unknown>>,
|
|
46
46
|
* prompt?: string,
|
|
47
|
+
* systemPrompt?: string | string[] | { type: string, prompt?: string | string[], append?: string },
|
|
47
48
|
* model?: string,
|
|
48
49
|
* resume?: string,
|
|
49
50
|
* maxTurns?: number,
|
|
@@ -235,6 +236,7 @@ function onQueryStart (ctx) {
|
|
|
235
236
|
const prompt = queryArg.prompt
|
|
236
237
|
const sessionCtx = {
|
|
237
238
|
prompt: typeof prompt === 'string' ? prompt : undefined,
|
|
239
|
+
systemPrompt: options.systemPrompt,
|
|
238
240
|
model: options.model,
|
|
239
241
|
resume: options.resume,
|
|
240
242
|
maxTurns: options.maxTurns,
|
|
@@ -451,6 +453,7 @@ function processStep (
|
|
|
451
453
|
llmCh.traceSync(() => {}, {
|
|
452
454
|
model,
|
|
453
455
|
usage,
|
|
456
|
+
systemPrompt: parentToolUseId ? undefined : sessionCtx?.systemPrompt,
|
|
454
457
|
startTime: stepStartTime,
|
|
455
458
|
finishTime: chunkEmitTimes.get(chunks[messageEndIdx - 1]),
|
|
456
459
|
chunks,
|
|
@@ -529,7 +532,8 @@ function processChunks (chunks, agentCtx) {
|
|
|
529
532
|
const sessionCtx = agentCtx.sessionCtx
|
|
530
533
|
const getLifecycle = createStreamLookup(chunks)
|
|
531
534
|
|
|
532
|
-
const
|
|
535
|
+
const initChunk = chunks.find(chunk => chunk.type === 'system' && chunk.subtype === 'init') || chunks[0]
|
|
536
|
+
const { type, subtype, ...rest } = initChunk
|
|
533
537
|
Object.assign(agentCtx, rest)
|
|
534
538
|
if (sessionCtx) {
|
|
535
539
|
if (sessionCtx.sessionId) agentCtx.session_id = sessionCtx.sessionId
|
|
@@ -142,7 +142,6 @@ let knownTests = {}
|
|
|
142
142
|
let skippedSuites = []
|
|
143
143
|
let isSuitesSkipped = false
|
|
144
144
|
let areAllSuitesSkipped = false
|
|
145
|
-
let hasTestsToRun = false
|
|
146
145
|
let repositoryRoot
|
|
147
146
|
|
|
148
147
|
function shouldRunEarlyFlakeDetection () {
|
|
@@ -1218,7 +1217,6 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
1218
1217
|
}
|
|
1219
1218
|
}
|
|
1220
1219
|
|
|
1221
|
-
hasTestsToRun = isCoordinator ? this.sourcedPickles.length > 0 : this.pickleIds.length > 0
|
|
1222
1220
|
pickleByFile = isCoordinator ? getPickleByFileNew(this) : getPickleByFile(this)
|
|
1223
1221
|
|
|
1224
1222
|
if (isKnownTestsEnabled) {
|
|
@@ -1330,10 +1328,17 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
1330
1328
|
global.__coverage__ = fromCoverageMapToCoverage(originalCoverageMap)
|
|
1331
1329
|
}
|
|
1332
1330
|
|
|
1333
|
-
const
|
|
1331
|
+
const testCaseAttempts = (this.eventDataCollector || eventDataCollector).getTestCaseAttempts()
|
|
1332
|
+
const getStatus = satisfies(frameworkVersion, '>=7.3.0') ? getStatusFromResultLatest : getStatusFromResult
|
|
1333
|
+
const hasExecutedTests = testCaseAttempts.some(({ worstTestStepResult }) =>
|
|
1334
|
+
getStatus(worstTestStepResult).status !== 'skip'
|
|
1335
|
+
)
|
|
1336
|
+
const testSessionEmptyReason = success && !hasExecutedTests
|
|
1337
|
+
? (testCaseAttempts.length > 0 || skippedSuites.length > 0 ? 'all_tests_skipped' : 'zero_tests')
|
|
1338
|
+
: undefined
|
|
1334
1339
|
const flushPromise = getChannelPromise(sessionFinishCh, {
|
|
1335
|
-
status:
|
|
1336
|
-
|
|
1340
|
+
status: testSessionEmptyReason ? 'skip' : (success ? 'pass' : 'fail'),
|
|
1341
|
+
testSessionEmptyReason,
|
|
1337
1342
|
isSuitesSkipped,
|
|
1338
1343
|
testCodeCoverageLinesTotal,
|
|
1339
1344
|
testSessionCoverageFiles,
|
|
@@ -1413,13 +1418,49 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
|
|
|
1413
1418
|
|
|
1414
1419
|
if (isImpactedTestsEnabled) {
|
|
1415
1420
|
const setIsModified = (receivedIsModified) => { isModified = receivedIsModified }
|
|
1416
|
-
const
|
|
1417
|
-
|
|
1418
|
-
|
|
1421
|
+
const gherkinNodes = []
|
|
1422
|
+
// Prefix ranges catch removed Backgrounds, which have no AST node in the target document.
|
|
1423
|
+
const gherkinScopeRanges = []
|
|
1424
|
+
const feature = gherkinDocument.feature
|
|
1425
|
+
const featureChildren = feature?.children
|
|
1426
|
+
if (featureChildren?.length) {
|
|
1427
|
+
const firstFeatureChild = featureChildren[0]
|
|
1428
|
+
const firstFeatureNode = firstFeatureChild.background ?? firstFeatureChild.rule ?? firstFeatureChild.scenario
|
|
1429
|
+
const firstFeatureLine = firstFeatureNode.tags?.[0]?.location.line ?? firstFeatureNode.location.line
|
|
1430
|
+
const featurePrefix = [feature.location.line, firstFeatureLine - 1]
|
|
1431
|
+
let featureBackground
|
|
1432
|
+
for (const child of featureChildren) {
|
|
1433
|
+
if (child.background) {
|
|
1434
|
+
featureBackground = child.background
|
|
1435
|
+
continue
|
|
1436
|
+
}
|
|
1437
|
+
const rule = child.rule
|
|
1438
|
+
const children = rule?.children ?? [child]
|
|
1439
|
+
let ruleBackground
|
|
1440
|
+
for (const { background } of children) {
|
|
1441
|
+
if (background) ruleBackground = background
|
|
1442
|
+
}
|
|
1443
|
+
for (const { scenario } of children) {
|
|
1444
|
+
if (scenario && pickle.astNodeIds.includes(scenario.id)) {
|
|
1445
|
+
if (!featureBackground) gherkinScopeRanges.push(featurePrefix)
|
|
1446
|
+
if (rule?.children?.length && !ruleBackground) {
|
|
1447
|
+
const firstRuleChild = rule.children.at(0)
|
|
1448
|
+
const firstRuleNode = firstRuleChild.background ?? firstRuleChild.scenario
|
|
1449
|
+
const firstRuleLine = firstRuleNode.tags?.[0]?.location.line ?? firstRuleNode.location.line
|
|
1450
|
+
gherkinScopeRanges.push([rule.location.line, firstRuleLine - 1])
|
|
1451
|
+
}
|
|
1452
|
+
if (featureBackground) gherkinNodes.push(featureBackground)
|
|
1453
|
+
if (ruleBackground) gherkinNodes.push(ruleBackground)
|
|
1454
|
+
gherkinNodes.push(scenario)
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1419
1459
|
const stepIds = testCase?.testSteps?.flatMap(testStep => testStep.stepDefinitionIds)
|
|
1420
1460
|
|
|
1421
1461
|
isModifiedCh.publish({
|
|
1422
|
-
|
|
1462
|
+
gherkinNodes,
|
|
1463
|
+
gherkinScopeRanges,
|
|
1423
1464
|
testFileAbsolutePath: gherkinDocument.uri,
|
|
1424
1465
|
modifiedFiles,
|
|
1425
1466
|
stepIds,
|