dd-trace 6.17.0 → 6.19.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
|
@@ -2025,8 +2025,9 @@ declare namespace tracer {
|
|
|
2025
2025
|
/**
|
|
2026
2026
|
* Whether to capture LLM Observability spans for this integration. When set to `false`,
|
|
2027
2027
|
* the integration keeps emitting APM spans and propagating trace context, but no LLM
|
|
2028
|
-
* Observability spans are produced. Useful when another
|
|
2029
|
-
* same operation and the payloads would otherwise be
|
|
2028
|
+
* Observability spans and no basic `gen_ai.*` APM tags are produced. Useful when another
|
|
2029
|
+
* integration already captures the same operation and the payloads would otherwise be
|
|
2030
|
+
* stored twice.
|
|
2030
2031
|
* @default true
|
|
2031
2032
|
*/
|
|
2032
2033
|
llmobs?: boolean;
|
|
@@ -3886,13 +3887,13 @@ declare namespace tracer {
|
|
|
3886
3887
|
/** Create a text or chat prompt and its first version. */
|
|
3887
3888
|
createPrompt (
|
|
3888
3889
|
promptId: string,
|
|
3889
|
-
template: string |
|
|
3890
|
+
template: string | PromptTemplateItem[],
|
|
3890
3891
|
options?: CreatePromptOptions
|
|
3891
3892
|
): Promise<PromptResponse>
|
|
3892
3893
|
/** Add a text or chat version to an existing prompt. */
|
|
3893
3894
|
createPromptVersion (
|
|
3894
3895
|
promptId: string,
|
|
3895
|
-
template: string |
|
|
3896
|
+
template: string | PromptTemplateItem[],
|
|
3896
3897
|
options?: CreatePromptVersionOptions
|
|
3897
3898
|
): Promise<PromptVersionResponse>
|
|
3898
3899
|
/** Update prompt metadata. */
|
|
@@ -3916,10 +3917,45 @@ declare namespace tracer {
|
|
|
3916
3917
|
content: string
|
|
3917
3918
|
}
|
|
3918
3919
|
|
|
3920
|
+
/** Provider fields on expanded messages; authored templates remain text-only. */
|
|
3921
|
+
interface FormattedPromptMessage extends PromptTemplateMessage {
|
|
3922
|
+
// The inherited content type stays string for compatibility; tool-only payloads can omit it or contain null.
|
|
3923
|
+
tool_calls?: PromptToolCall[] | null,
|
|
3924
|
+
tool_results?: PromptToolResult[] | null,
|
|
3925
|
+
tool_call_id?: string | null
|
|
3926
|
+
}
|
|
3927
|
+
|
|
3928
|
+
interface PromptToolCall {
|
|
3929
|
+
id?: string | null,
|
|
3930
|
+
type?: string | null,
|
|
3931
|
+
tool_id?: string | null,
|
|
3932
|
+
name?: string | null,
|
|
3933
|
+
arguments?: unknown,
|
|
3934
|
+
function?: {
|
|
3935
|
+
name: string,
|
|
3936
|
+
arguments: string
|
|
3937
|
+
} | null
|
|
3938
|
+
}
|
|
3939
|
+
|
|
3940
|
+
interface PromptToolResult {
|
|
3941
|
+
id?: string | null,
|
|
3942
|
+
type?: string | null,
|
|
3943
|
+
tool_id?: string | null,
|
|
3944
|
+
name?: string | null,
|
|
3945
|
+
result?: unknown
|
|
3946
|
+
}
|
|
3947
|
+
|
|
3948
|
+
interface PromptMessagePlaceholder {
|
|
3949
|
+
type: 'placeholder',
|
|
3950
|
+
name: string
|
|
3951
|
+
}
|
|
3952
|
+
|
|
3953
|
+
type PromptTemplateItem = PromptTemplateMessage | PromptMessagePlaceholder
|
|
3954
|
+
|
|
3919
3955
|
type PromptFallbackValue =
|
|
3920
3956
|
| string
|
|
3921
|
-
|
|
|
3922
|
-
| { template: string |
|
|
3957
|
+
| PromptTemplateItem[]
|
|
3958
|
+
| { template: string | PromptTemplateItem[], version?: string, config?: Record<string, JSONType> }
|
|
3923
3959
|
type PromptFallback = PromptFallbackValue | (() => PromptFallbackValue)
|
|
3924
3960
|
|
|
3925
3961
|
interface GetPromptOptions {
|
|
@@ -3938,13 +3974,15 @@ declare namespace tracer {
|
|
|
3938
3974
|
title?: string,
|
|
3939
3975
|
description?: string,
|
|
3940
3976
|
userVersion?: string,
|
|
3941
|
-
envIds?: string[]
|
|
3977
|
+
envIds?: string[],
|
|
3978
|
+
config?: Record<string, JSONType>
|
|
3942
3979
|
}
|
|
3943
3980
|
|
|
3944
3981
|
interface CreatePromptVersionOptions {
|
|
3945
3982
|
description?: string,
|
|
3946
3983
|
userVersion?: string,
|
|
3947
|
-
envIds?: string[]
|
|
3984
|
+
envIds?: string[],
|
|
3985
|
+
config?: Record<string, JSONType>
|
|
3948
3986
|
}
|
|
3949
3987
|
|
|
3950
3988
|
interface UpdatePromptOptions {
|
|
@@ -3957,14 +3995,16 @@ declare namespace tracer {
|
|
|
3957
3995
|
envIds?: string[]
|
|
3958
3996
|
}
|
|
3959
3997
|
|
|
3998
|
+
// Preserve released output types; placeholder entries and null/omitted tool content are not fully described here.
|
|
3960
3999
|
interface ManagedPrompt {
|
|
3961
4000
|
readonly id: string,
|
|
3962
4001
|
readonly version: string,
|
|
3963
4002
|
readonly source: 'registry' | 'cache' | 'fallback' | 'ff' | 'resolve',
|
|
3964
4003
|
readonly template: string | ReadonlyArray<Readonly<PromptTemplateMessage>>,
|
|
4004
|
+
readonly config: Readonly<Record<string, ReadonlyJSONType>>,
|
|
3965
4005
|
readonly promptUuid?: string,
|
|
3966
4006
|
readonly promptVersionUuid?: string,
|
|
3967
|
-
format (variables?: Record<string, unknown>): string |
|
|
4007
|
+
format (variables?: Record<string, unknown>): string | FormattedPromptMessage[]
|
|
3968
4008
|
toAnnotation (variables?: Record<string, unknown>): Prompt
|
|
3969
4009
|
}
|
|
3970
4010
|
|
|
@@ -3982,7 +4022,8 @@ declare namespace tracer {
|
|
|
3982
4022
|
ml_app?: string,
|
|
3983
4023
|
ml_apps?: string[],
|
|
3984
4024
|
last_version_created_at?: string,
|
|
3985
|
-
extracted_from?: string
|
|
4025
|
+
extracted_from?: string,
|
|
4026
|
+
config?: Record<string, JSONType>
|
|
3986
4027
|
}
|
|
3987
4028
|
|
|
3988
4029
|
interface PromptVersionResponse {
|
|
@@ -3996,7 +4037,8 @@ declare namespace tracer {
|
|
|
3996
4037
|
version_created_at?: string,
|
|
3997
4038
|
author?: string,
|
|
3998
4039
|
description?: string,
|
|
3999
|
-
ml_app?: string
|
|
4040
|
+
ml_app?: string,
|
|
4041
|
+
config?: Record<string, JSONType>
|
|
4000
4042
|
}
|
|
4001
4043
|
|
|
4002
4044
|
interface DeletedPromptResponse {
|
|
@@ -4008,6 +4050,8 @@ declare namespace tracer {
|
|
|
4008
4050
|
/** JSON-serializable value accepted by LLMObs Experiments. */
|
|
4009
4051
|
type JSONType = string | number | boolean | null | JSONType[] | { [key: string]: JSONType }
|
|
4010
4052
|
|
|
4053
|
+
type ReadonlyJSONType = string | number | boolean | null | ReadonlyArray<ReadonlyJSONType> | { readonly [key: string]: ReadonlyJSONType }
|
|
4054
|
+
|
|
4011
4055
|
/**
|
|
4012
4056
|
* A task run over each dataset record during an experiment.
|
|
4013
4057
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.19.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,
|