dd-trace 6.10.0 → 6.11.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/README.md +0 -17
- package/index.d.ts +108 -3
- package/initialize.mjs +28 -17
- package/openfeature.js +2 -2
- package/package.json +11 -8
- package/packages/datadog-esbuild/index.js +0 -34
- package/packages/datadog-instrumentations/src/anthropic.js +210 -15
- package/packages/datadog-instrumentations/src/aws-sdk.js +9 -1
- package/packages/datadog-instrumentations/src/browser-bunyan.js +11 -0
- package/packages/datadog-instrumentations/src/bunyan.js +3 -16
- package/packages/datadog-instrumentations/src/cucumber.js +26 -11
- package/packages/datadog-instrumentations/src/cypress-config.js +182 -16
- package/packages/datadog-instrumentations/src/cypress-legacy-finalizers.js +30 -0
- package/packages/datadog-instrumentations/src/cypress.js +2 -0
- package/packages/datadog-instrumentations/src/fastify.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/bunyan.js +22 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +9 -4
- package/packages/datadog-instrumentations/src/helpers/register.js +10 -8
- package/packages/datadog-instrumentations/src/jest.js +25 -17
- package/packages/datadog-instrumentations/src/mariadb.js +278 -21
- package/packages/datadog-instrumentations/src/mocha/main.js +539 -55
- package/packages/datadog-instrumentations/src/mocha/utils.js +130 -17
- package/packages/datadog-instrumentations/src/playwright-reporter.js +99 -0
- package/packages/datadog-instrumentations/src/playwright.js +149 -2
- package/packages/datadog-instrumentations/src/router.js +2 -0
- package/packages/datadog-instrumentations/src/vitest-main.js +11 -3
- package/packages/datadog-plugin-aws-sdk/src/base.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +163 -44
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -8
- package/packages/datadog-plugin-azure-functions/src/index.js +1 -1
- package/packages/datadog-plugin-browser-bunyan/src/index.js +9 -0
- package/packages/datadog-plugin-bunyan/src/index.js +5 -8
- package/packages/datadog-plugin-cucumber/src/index.js +11 -0
- package/packages/datadog-plugin-cypress/src/after-run.js +5 -1
- package/packages/datadog-plugin-cypress/src/after-spec.js +5 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +81 -29
- package/packages/datadog-plugin-cypress/src/finalization.js +76 -0
- package/packages/datadog-plugin-cypress/src/index.js +12 -6
- package/packages/datadog-plugin-cypress/src/plugin.js +16 -3
- package/packages/datadog-plugin-dd-trace-api/src/index.js +4 -0
- package/packages/datadog-plugin-electron/src/index.js +2 -0
- package/packages/datadog-plugin-fs/src/index.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +6 -0
- package/packages/datadog-plugin-mocha/src/index.js +56 -1
- package/packages/datadog-plugin-nats/src/index.js +1 -1
- package/packages/datadog-plugin-openai/src/tracing.js +41 -30
- package/packages/datadog-plugin-openai-agents/src/integration.js +1 -0
- package/packages/datadog-plugin-playwright/src/index.js +42 -13
- package/packages/datadog-plugin-vitest/src/index.js +6 -0
- package/packages/datadog-webpack/index.js +0 -11
- package/packages/dd-trace/index.js +0 -1
- package/packages/dd-trace/src/agent/info.js +6 -5
- package/packages/dd-trace/src/aiguard/client.js +100 -1
- package/packages/dd-trace/src/aiguard/errors.js +41 -0
- package/packages/dd-trace/src/aiguard/evaluation.js +357 -0
- package/packages/dd-trace/src/aiguard/integrations/anthropic.js +70 -0
- package/packages/dd-trace/src/aiguard/integrations/index.js +4 -0
- package/packages/dd-trace/src/aiguard/messages/anthropic.js +423 -0
- package/packages/dd-trace/src/aiguard/messages/openai.js +1 -24
- package/packages/dd-trace/src/aiguard/messages/utils.js +28 -0
- package/packages/dd-trace/src/aiguard/messages/vercel-ai.js +1 -11
- package/packages/dd-trace/src/aiguard/sdk.js +22 -278
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +9 -12
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +1 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +27 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +22 -6
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +21 -5
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/request-tracker.js +164 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +22 -6
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +365 -32
- package/packages/dd-trace/src/ci-visibility/exporters/request.js +201 -0
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +5 -3
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +9 -5
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -1
- package/packages/dd-trace/src/ci-visibility/requests/rate-limit.js +39 -0
- package/packages/dd-trace/src/ci-visibility/requests/request.js +3 -6
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +6 -2
- package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -0
- package/packages/dd-trace/src/config/index.js +13 -2
- package/packages/dd-trace/src/config/major-overrides.js +7 -0
- package/packages/dd-trace/src/config/supported-configurations.json +14 -0
- package/packages/dd-trace/src/datastreams/index.js +2 -0
- package/packages/dd-trace/src/datastreams/manager.js +9 -2
- package/packages/dd-trace/src/datastreams/processor.js +15 -13
- package/packages/dd-trace/src/datastreams/size.js +5 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +3 -2
- package/packages/dd-trace/src/exporters/agent/writer.js +49 -9
- package/packages/dd-trace/src/exporters/common/buffering-exporter.js +6 -4
- package/packages/dd-trace/src/exporters/common/writer.js +11 -6
- package/packages/dd-trace/src/llmobs/experiments/client.js +163 -5
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +241 -87
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +280 -20
- package/packages/dd-trace/src/llmobs/experiments/index.js +58 -59
- package/packages/dd-trace/src/llmobs/experiments/noop.js +71 -3
- package/packages/dd-trace/src/llmobs/experiments/result.js +1 -0
- package/packages/dd-trace/src/llmobs/experiments/util.js +41 -5
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +12 -3
- package/packages/dd-trace/src/llmobs/plugins/base.js +4 -2
- package/packages/dd-trace/src/noop/proxy.js +3 -4
- package/packages/dd-trace/src/openfeature/flagging_provider.js +18 -2
- package/packages/dd-trace/src/openfeature/remote_config.js +1 -1
- package/packages/dd-trace/src/opentelemetry/context_manager.js +7 -7
- package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +2 -1
- package/packages/dd-trace/src/opentelemetry/logs/logger.js +67 -11
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +14 -3
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +25 -12
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +2 -5
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +96 -43
- package/packages/dd-trace/src/opentracing/tracer.js +5 -2
- package/packages/dd-trace/src/otel-thread-ctx.js +387 -0
- package/packages/dd-trace/src/plugin_manager.js +3 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +6 -1
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/jest.js +4 -3
- package/packages/dd-trace/src/plugins/util/test.js +9 -9
- package/packages/dd-trace/src/plugins/util/web.js +3 -0
- package/packages/dd-trace/src/profiling/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/space.js +1 -3
- package/packages/dd-trace/src/profiling/profilers/wall.js +37 -90
- package/packages/dd-trace/src/profiling/webspan-utils.js +45 -0
- package/packages/dd-trace/src/proxy.js +38 -29
- package/packages/dd-trace/src/ritm.js +9 -2
- package/packages/dd-trace/src/serverless.js +37 -0
- package/packages/dd-trace/src/span_format.js +1 -0
- package/packages/dd-trace/src/span_stats.js +30 -3
- package/packages/dd-trace/src/storage-channels.js +86 -0
- package/packages/dd-trace/src/tracer.js +9 -2
- package/packages/dd-trace/src/tracer_metadata.js +14 -1
- package/packages/dd-trace/src/web-tags-cache.js +132 -0
- package/vendor/dist/@datadog/openfeature-node-server/LICENSE +201 -0
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/optional-peer-bundler.js +0 -65
- package/packages/datadog-webpack/src/optional-peer-loader.js +0 -17
- package/packages/dd-trace/src/feature-registry.js +0 -29
- package/packages/dd-trace/src/openfeature/register.js +0 -35
- package/packages/dd-trace/src/openfeature/require-provider.js +0 -18
package/README.md
CHANGED
|
@@ -93,23 +93,6 @@ Regardless of where you open the issue, someone at Datadog will try to help.
|
|
|
93
93
|
|
|
94
94
|
If you would like to trace your bundled application then please read this page on [bundling and dd-trace](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/nodejs/#bundling). It includes information on how to use our ESBuild plugin and includes caveats for other bundlers.
|
|
95
95
|
|
|
96
|
-
When using the experimental OpenFeature provider, file-traced deployments can force the optional provider and
|
|
97
|
-
its dependencies into the output with a side-effect import before accessing `tracer.openfeature`:
|
|
98
|
-
|
|
99
|
-
CommonJS:
|
|
100
|
-
|
|
101
|
-
```js
|
|
102
|
-
require('dd-trace/openfeature')
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
ES modules:
|
|
106
|
-
|
|
107
|
-
```js
|
|
108
|
-
import 'dd-trace/openfeature.js'
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
This is a fallback for build tools that do not recognize the provider's optional-require wrapper.
|
|
112
|
-
|
|
113
96
|
|
|
114
97
|
## Security Vulnerabilities
|
|
115
98
|
|
package/index.d.ts
CHANGED
|
@@ -243,6 +243,7 @@ interface Plugins {
|
|
|
243
243
|
"azure-functions": tracer.plugins.azure_functions;
|
|
244
244
|
"azure-service-bus": tracer.plugins.azure_service_bus;
|
|
245
245
|
"azure-durable-functions": tracer.plugins.azure_durable_functions
|
|
246
|
+
"browser-bunyan": tracer.plugins.browser_bunyan;
|
|
246
247
|
"bullmq": tracer.plugins.bullmq;
|
|
247
248
|
"bunyan": tracer.plugins.bunyan;
|
|
248
249
|
"cassandra-driver": tracer.plugins.cassandra_driver;
|
|
@@ -1940,6 +1941,18 @@ declare namespace tracer {
|
|
|
1940
1941
|
/** @hidden */
|
|
1941
1942
|
interface Instrumentation extends Integration, Analyzable {}
|
|
1942
1943
|
|
|
1944
|
+
/** @hidden */
|
|
1945
|
+
interface LLMObsIntegration extends Integration {
|
|
1946
|
+
/**
|
|
1947
|
+
* Whether to capture LLM Observability spans for this integration. When set to `false`,
|
|
1948
|
+
* the integration keeps emitting APM spans and propagating trace context, but no LLM
|
|
1949
|
+
* Observability spans are produced. Useful when another integration already captures the
|
|
1950
|
+
* same operation and the payloads would otherwise be stored twice.
|
|
1951
|
+
* @default true
|
|
1952
|
+
*/
|
|
1953
|
+
llmobs?: boolean;
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1943
1956
|
/** @hidden */
|
|
1944
1957
|
interface DatabaseInstrumentation extends Instrumentation {
|
|
1945
1958
|
/**
|
|
@@ -2333,11 +2346,13 @@ declare namespace tracer {
|
|
|
2333
2346
|
interface azure_durable_functions extends Integration {}
|
|
2334
2347
|
|
|
2335
2348
|
/**
|
|
2336
|
-
* This plugin patches the [bunyan](https://github.com/
|
|
2349
|
+
* This plugin patches the [browser-bunyan](https://github.com/philmander/browser-bunyan)
|
|
2337
2350
|
* to automatically inject trace identifiers in log records when the
|
|
2338
2351
|
* [logInjection](interfaces/traceroptions.html#logInjection) option is enabled
|
|
2339
2352
|
* on the tracer.
|
|
2340
2353
|
*/
|
|
2354
|
+
interface browser_bunyan extends Integration {}
|
|
2355
|
+
|
|
2341
2356
|
/**
|
|
2342
2357
|
* This plugin automatically instruments the
|
|
2343
2358
|
* [bullmq](https://github.com/npmjs/package/bullmq) message queue library.
|
|
@@ -2358,6 +2373,12 @@ declare namespace tracer {
|
|
|
2358
2373
|
producerFilter?: (job: { name?: string; data?: unknown; opts?: unknown; queueName?: string }) => boolean;
|
|
2359
2374
|
}
|
|
2360
2375
|
|
|
2376
|
+
/**
|
|
2377
|
+
* This plugin patches the [bunyan](https://github.com/trentm/node-bunyan)
|
|
2378
|
+
* to automatically inject trace identifiers in log records when the
|
|
2379
|
+
* [logInjection](interfaces/traceroptions.html#logInjection) option is enabled
|
|
2380
|
+
* on the tracer.
|
|
2381
|
+
*/
|
|
2361
2382
|
interface bunyan extends Integration {}
|
|
2362
2383
|
|
|
2363
2384
|
/**
|
|
@@ -2804,7 +2825,7 @@ declare namespace tracer {
|
|
|
2804
2825
|
* This plugin automatically instruments the
|
|
2805
2826
|
* [langchain](https://js.langchain.com/) module
|
|
2806
2827
|
*/
|
|
2807
|
-
interface langchain extends Instrumentation {}
|
|
2828
|
+
interface langchain extends Instrumentation, LLMObsIntegration {}
|
|
2808
2829
|
|
|
2809
2830
|
/**
|
|
2810
2831
|
* This plugin automatically instruments the
|
|
@@ -2846,7 +2867,7 @@ declare namespace tracer {
|
|
|
2846
2867
|
* This plugin automatically instruments the
|
|
2847
2868
|
* [modelcontextprotocol-sdk](https://github.com/npmjs/package/@modelcontextprotocol/sdk) library.
|
|
2848
2869
|
*/
|
|
2849
|
-
interface modelcontextprotocol_sdk extends Instrumentation {}
|
|
2870
|
+
interface modelcontextprotocol_sdk extends Instrumentation, LLMObsIntegration {}
|
|
2850
2871
|
|
|
2851
2872
|
/**
|
|
2852
2873
|
* This plugin automatically instruments the
|
|
@@ -3852,6 +3873,79 @@ declare namespace tracer {
|
|
|
3852
3873
|
url: string
|
|
3853
3874
|
}
|
|
3854
3875
|
|
|
3876
|
+
type ExternalExperimentTimestamp = number | string | Date
|
|
3877
|
+
|
|
3878
|
+
interface StartExperimentDatasetOptions {
|
|
3879
|
+
/** Existing dataset id. When omitted, a placeholder dataset is created. */
|
|
3880
|
+
id?: string
|
|
3881
|
+
/** Dataset version to associate with the experiment. */
|
|
3882
|
+
version?: number
|
|
3883
|
+
/** Placeholder dataset name. Defaults to `<experiment name> dataset`. */
|
|
3884
|
+
name?: string
|
|
3885
|
+
/** Placeholder dataset description. */
|
|
3886
|
+
description?: string
|
|
3887
|
+
}
|
|
3888
|
+
|
|
3889
|
+
interface StartExperimentOptions {
|
|
3890
|
+
name: string
|
|
3891
|
+
description?: string
|
|
3892
|
+
/** Override the configured project name for this external experiment. */
|
|
3893
|
+
projectName?: string
|
|
3894
|
+
dataset?: StartExperimentDatasetOptions
|
|
3895
|
+
config?: Record<string, JSONType>
|
|
3896
|
+
metadata?: Record<string, JSONType>
|
|
3897
|
+
tags?: Record<string, string>
|
|
3898
|
+
}
|
|
3899
|
+
|
|
3900
|
+
interface ExternalExperimentSpanInput {
|
|
3901
|
+
name?: string
|
|
3902
|
+
input?: JSONType
|
|
3903
|
+
output?: JSONType
|
|
3904
|
+
expectedOutput?: JSONType
|
|
3905
|
+
metadata?: Record<string, JSONType>
|
|
3906
|
+
tags?: Record<string, string>
|
|
3907
|
+
startedAt?: ExternalExperimentTimestamp
|
|
3908
|
+
completedAt?: ExternalExperimentTimestamp
|
|
3909
|
+
durationMs?: number
|
|
3910
|
+
error?: string | Error | { type?: string, name?: string, message?: string, stack?: string }
|
|
3911
|
+
datasetRecordId?: string
|
|
3912
|
+
runId?: string
|
|
3913
|
+
runIteration?: number
|
|
3914
|
+
}
|
|
3915
|
+
|
|
3916
|
+
interface ExternalExperimentSpan {
|
|
3917
|
+
experimentId: string
|
|
3918
|
+
spanId: string
|
|
3919
|
+
traceId: string
|
|
3920
|
+
url: string | null
|
|
3921
|
+
}
|
|
3922
|
+
|
|
3923
|
+
interface ExternalExperimentMetric {
|
|
3924
|
+
label: string
|
|
3925
|
+
value?: JSONType
|
|
3926
|
+
error?: string | Error
|
|
3927
|
+
timestamp?: ExternalExperimentTimestamp
|
|
3928
|
+
tags?: Record<string, string>
|
|
3929
|
+
source?: string
|
|
3930
|
+
}
|
|
3931
|
+
|
|
3932
|
+
interface ExternalExperimentCloseOptions {
|
|
3933
|
+
status?: string
|
|
3934
|
+
error?: string | Error
|
|
3935
|
+
}
|
|
3936
|
+
|
|
3937
|
+
interface ExternalExperiment {
|
|
3938
|
+
experimentId (): string
|
|
3939
|
+
name (): string
|
|
3940
|
+
url (): string | null
|
|
3941
|
+
submitSpan (input?: ExternalExperimentSpanInput): Promise<ExternalExperimentSpan>
|
|
3942
|
+
submitEvaluationMetrics (
|
|
3943
|
+
span: { experimentId?: string, spanId: string, traceId: string },
|
|
3944
|
+
metrics: ExternalExperimentMetric[]
|
|
3945
|
+
): Promise<void>
|
|
3946
|
+
close (options?: ExternalExperimentCloseOptions): Promise<void>
|
|
3947
|
+
}
|
|
3948
|
+
|
|
3855
3949
|
interface DatasetPushResult {
|
|
3856
3950
|
/** Number of records from this push that were confirmed with a record id. */
|
|
3857
3951
|
pushedCount: number
|
|
@@ -3861,9 +3955,18 @@ declare namespace tracer {
|
|
|
3861
3955
|
|
|
3862
3956
|
interface Dataset {
|
|
3863
3957
|
addRecord (input: JSONType, expectedOutput?: JSONType, metadata?: Record<string, JSONType>): Dataset
|
|
3958
|
+
/** Update fields on an existing dataset record. */
|
|
3959
|
+
update (index: number, fields: {
|
|
3960
|
+
input?: JSONType
|
|
3961
|
+
expectedOutput?: JSONType
|
|
3962
|
+
metadata?: Record<string, JSONType>
|
|
3963
|
+
}): Dataset
|
|
3964
|
+
/** Delete an existing dataset record. */
|
|
3965
|
+
delete (index: number): Dataset
|
|
3864
3966
|
/** Creates the dataset remotely if needed and pushes any unpushed records. */
|
|
3865
3967
|
push (): Promise<DatasetPushResult>
|
|
3866
3968
|
name (): string
|
|
3969
|
+
description (): string
|
|
3867
3970
|
id (): string | null
|
|
3868
3971
|
projectId (): string | null
|
|
3869
3972
|
version (): number | null
|
|
@@ -3893,6 +3996,8 @@ declare namespace tracer {
|
|
|
3893
3996
|
pullDataset (name: string, options?: PullDatasetOptions): Promise<Dataset>
|
|
3894
3997
|
/** Build an experiment to run over a dataset. */
|
|
3895
3998
|
experiment (options: ExperimentOptions): Experiment
|
|
3999
|
+
/** Start an externally-driven experiment. */
|
|
4000
|
+
startExperiment (options: StartExperimentOptions): Promise<ExternalExperiment>
|
|
3896
4001
|
}
|
|
3897
4002
|
|
|
3898
4003
|
interface LLMObservabilitySpan {
|
package/initialize.mjs
CHANGED
|
@@ -16,19 +16,28 @@ import * as Module from 'module'
|
|
|
16
16
|
import { types } from 'util'
|
|
17
17
|
import { isMainThread } from 'worker_threads'
|
|
18
18
|
|
|
19
|
-
// This file must support Node.js
|
|
19
|
+
// This file must support Node.js 14.13.1 syntax
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
const NODE_VERSION = process.versions.node
|
|
22
|
+
|
|
23
|
+
const brokenLoaders = NODE_VERSION.startsWith('18.0')
|
|
24
|
+
const isNode20LoaderWorker = !isMainThread && NODE_VERSION.startsWith('20.0')
|
|
25
|
+
const useDefaultLoader = brokenLoaders || isNode20LoaderWorker
|
|
26
|
+
// Avoid CommonJS in the loader worker on Node 20.0: https://github.com/nodejs/node/issues/47566
|
|
27
|
+
const loaderHook = useDefaultLoader ? undefined : await import('./loader-hook.mjs?initialize')
|
|
27
28
|
|
|
28
29
|
let hasInsertedInit = false
|
|
29
30
|
const initJsUrl = new URL('init.js', import.meta.url).href
|
|
30
31
|
// `--loader` only reliably influences ESM entrypoints; for CJS apps use `--import`/`--require`.
|
|
31
32
|
|
|
33
|
+
// `globalPreload` is deprecated in favor of the `initialize` hook, but `initialize` only exists
|
|
34
|
+
// from Node 20.6 on, so it is the only way to run code in the application realm on Node 20.0.
|
|
35
|
+
export const globalPreload = isNode20LoaderWorker
|
|
36
|
+
? () => `if (getBuiltin('module').createRequire(${JSON.stringify(import.meta.url)})('./init.js')) {
|
|
37
|
+
process.emitWarning('dd-trace cannot instrument ES modules on Node.js 20.0.0. Upgrade to Node.js 20.1.0 or newer.')
|
|
38
|
+
}`
|
|
39
|
+
: undefined
|
|
40
|
+
|
|
32
41
|
/**
|
|
33
42
|
* @param {{ source?: string|Buffer|Uint8Array, format?: string }} result
|
|
34
43
|
* @param {unknown} _url_
|
|
@@ -63,26 +72,28 @@ function insertInit (result, _url_, context) {
|
|
|
63
72
|
return result
|
|
64
73
|
}
|
|
65
74
|
|
|
66
|
-
const [NODE_MAJOR, NODE_MINOR] = process.versions.node.split('.').map(Number)
|
|
67
|
-
|
|
68
|
-
const brokenLoaders = NODE_MAJOR === 18 && NODE_MINOR === 0
|
|
69
|
-
|
|
70
75
|
// Node calls `initialize` only through `module.register`, never for `--loader`; without it
|
|
71
76
|
// import-in-the-middle keeps its default matcher and proxies every application module. Loaders
|
|
72
77
|
// before Node 18.19 share the application thread, where `loader-hook.mjs` builds no matcher.
|
|
73
|
-
let needsHookInitialize = !isMainThread && !
|
|
78
|
+
let needsHookInitialize = !isMainThread && !useDefaultLoader
|
|
74
79
|
|
|
75
|
-
|
|
80
|
+
/**
|
|
81
|
+
* @param {string} url
|
|
82
|
+
* @param {import('node:module').LoadHookContext & { isMain?: boolean }} context
|
|
83
|
+
* @param {Parameters<import('node:module').LoadHook>[2]} nextLoad
|
|
84
|
+
*/
|
|
85
|
+
async function loadWithInit (url, context, nextLoad) {
|
|
76
86
|
if (needsHookInitialize) {
|
|
77
87
|
needsHookInitialize = false
|
|
78
|
-
|
|
88
|
+
loaderHook.initialize()
|
|
79
89
|
}
|
|
80
90
|
|
|
81
|
-
const
|
|
82
|
-
return insertInit(await
|
|
91
|
+
const load = (useDefaultLoader || loaderHook.iitmExclusionRegExp.test(url)) ? nextLoad : loaderHook.load
|
|
92
|
+
return insertInit(await load(url, context, nextLoad), url, context)
|
|
83
93
|
}
|
|
84
94
|
|
|
85
|
-
export const
|
|
95
|
+
export const load = isNode20LoaderWorker ? undefined : loadWithInit
|
|
96
|
+
export const resolve = useDefaultLoader ? undefined : loaderHook.resolve
|
|
86
97
|
|
|
87
98
|
if (isMainThread) {
|
|
88
99
|
const require = Module.createRequire(import.meta.url)
|
package/openfeature.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
// Static fallback for file tracers that do not recognize the
|
|
4
|
-
require('
|
|
3
|
+
// Static fallback for file tracers that do not recognize the vendored provider's lazy require.
|
|
4
|
+
require('./vendor/dist/@datadog/openfeature-node-server')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.11.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"test:esbuild:ci": "node scripts/c8-ci.js test:esbuild",
|
|
50
50
|
"test:webpack": "mocha \"packages/datadog-webpack/test/**/*.spec.js\"",
|
|
51
51
|
"test:webpack:ci": "node scripts/c8-ci.js test:webpack",
|
|
52
|
-
"test:instrumentations": "mocha \"packages/datadog-instrumentations/test/@(${PLUGINS}).spec.js\"",
|
|
52
|
+
"test:instrumentations": "mocha --fail-zero \"packages/datadog-instrumentations/test/@(${PLUGINS}).spec.js\"",
|
|
53
53
|
"test:instrumentations:ci": "yarn services && node scripts/c8-ci.js test:instrumentations",
|
|
54
54
|
"test:instrumentations:misc": "mocha \"packages/datadog-instrumentations/test/*/**/*.spec.{js,mjs}\"",
|
|
55
55
|
"test:instrumentations:misc:ci": "node scripts/c8-ci.js test:instrumentations:misc",
|
|
@@ -65,12 +65,14 @@
|
|
|
65
65
|
"test:llmobs:plugins:ci": "yarn services && node scripts/c8-ci.js test:llmobs:plugins",
|
|
66
66
|
"test:openfeature": "mocha \"packages/dd-trace/test/openfeature/**/*.spec.js\"",
|
|
67
67
|
"test:openfeature:ci": "node scripts/c8-ci.js test:openfeature",
|
|
68
|
-
"test:plugins": "node --expose-gc ./node_modules/mocha/bin/mocha.js \"packages/datadog-plugin-@(${PLUGINS})/test/**/${SPEC:-*}*.spec.js\"",
|
|
68
|
+
"test:plugins": "node --expose-gc ./node_modules/mocha/bin/mocha.js --fail-zero \"packages/datadog-plugin-@(${PLUGINS})/test/**/${SPEC:-*}*.spec.js\"",
|
|
69
69
|
"test:plugins:ci": "yarn services && node scripts/c8-ci.js test:plugins",
|
|
70
70
|
"test:plugins:ci:flaky": "yarn services && node scripts/c8-ci.js test:plugins --bail --retries 2",
|
|
71
71
|
"test:plugins:upstream": "node ./packages/dd-trace/test/plugins/suite.js",
|
|
72
72
|
"test:profiler": "node scripts/mocha-parallel-files.js --expose-gc --timeout 30000 -- \"packages/dd-trace/test/profiling/**/*.spec.js\"",
|
|
73
73
|
"test:profiler:ci": "node scripts/c8-ci.js test:profiler",
|
|
74
|
+
"test:otel-thread-ctx": "mocha --timeout 60000 packages/dd-trace/test/otel-thread-ctx.spec.js",
|
|
75
|
+
"test:docker:otel-thread-ctx": "./scripts/docker/run-otel-thread-ctx-spec.sh",
|
|
74
76
|
"test:integration": "mocha --timeout 60000 \"integration-tests/*.spec.js\"",
|
|
75
77
|
"test:integration:coverage": "node ./integration-tests/coverage/run-suite.js --timeout 60000 \"integration-tests/*.spec.js\"",
|
|
76
78
|
"test:integration:aiguard": "mocha --timeout 60000 \"integration-tests/aiguard/*.spec.js\"",
|
|
@@ -112,7 +114,7 @@
|
|
|
112
114
|
"test:integration:plugins:coverage": "yarn services && node ./integration-tests/coverage/run-suite.js \"packages/datadog-plugin-@(${PLUGINS})/test/integration-test/**/${SPEC:-*}*.spec.js\"",
|
|
113
115
|
"test:unit:plugins": "mocha \"packages/datadog-instrumentations/test/@(${PLUGINS}).spec.js\" \"packages/datadog-plugin-@(${PLUGINS})/test/**/*.spec.js\" --exclude \"packages/datadog-plugin-@(${PLUGINS})/test/integration-test/**/*.spec.js\"",
|
|
114
116
|
"test:release": "mocha \"scripts/release/**/*.spec.js\"",
|
|
115
|
-
"test:scripts": "mocha \"scripts/helpers/**/*.spec.js\" \"scripts/*.spec.mjs\"",
|
|
117
|
+
"test:scripts": "mocha \"benchmark/sirun/*.spec.js\" \"scripts/helpers/**/*.spec.js\" \"scripts/*.spec.mjs\"",
|
|
116
118
|
"test:shimmer": "mocha \"packages/datadog-shimmer/test/**/*.spec.js\"",
|
|
117
119
|
"test:shimmer:ci": "node scripts/c8-ci.js test:shimmer",
|
|
118
120
|
"verify:workflow-job-names": "node scripts/verify-workflow-job-names.js",
|
|
@@ -180,13 +182,12 @@
|
|
|
180
182
|
"opentracing": ">=0.14.7"
|
|
181
183
|
},
|
|
182
184
|
"optionalDependencies": {
|
|
183
|
-
"@datadog/libdatadog": "0.
|
|
185
|
+
"@datadog/libdatadog": "0.12.1",
|
|
184
186
|
"@datadog/native-appsec": "11.0.1",
|
|
185
187
|
"@datadog/native-iast-taint-tracking": "4.2.0",
|
|
186
188
|
"@datadog/native-metrics": "3.1.2",
|
|
187
|
-
"@datadog/
|
|
188
|
-
"@datadog/
|
|
189
|
-
"@datadog/wasm-js-rewriter": "5.0.1",
|
|
189
|
+
"@datadog/pprof": "5.18.0",
|
|
190
|
+
"@datadog/wasm-js-rewriter": "5.0.3",
|
|
190
191
|
"@opentelemetry/api": ">=1.0.0 <1.10.0",
|
|
191
192
|
"@opentelemetry/api-logs": "<1.0.0",
|
|
192
193
|
"oxc-parser": "^0.132.0"
|
|
@@ -197,6 +198,8 @@
|
|
|
197
198
|
"@babel/helpers": "^8.0.0",
|
|
198
199
|
"@eslint/eslintrc": "^3.3.5",
|
|
199
200
|
"@eslint/js": "^10.0.1",
|
|
201
|
+
"@eslint/plugin-kit": "^0.7.2",
|
|
202
|
+
"@datadog/openfeature-node-server": "2.1.0",
|
|
200
203
|
"@msgpack/msgpack": "^3.1.3",
|
|
201
204
|
"@openfeature/core": "^1.11.0",
|
|
202
205
|
"@openfeature/server-sdk": "~1.22.0",
|
|
@@ -8,11 +8,6 @@ const { pathToFileURL, fileURLToPath } = require('node:url')
|
|
|
8
8
|
const instrumentations = require('../datadog-instrumentations/src/helpers/instrumentations')
|
|
9
9
|
const extractPackageAndModulePath = require('../datadog-instrumentations/src/helpers/extract-package-and-module-path')
|
|
10
10
|
const hooks = require('../datadog-instrumentations/src/helpers/hooks')
|
|
11
|
-
const {
|
|
12
|
-
OPTIONAL_PEER_FILTER,
|
|
13
|
-
matchesOptionalPeerFile,
|
|
14
|
-
rewriteOptionalPeerLoads,
|
|
15
|
-
} = require('../datadog-instrumentations/src/helpers/optional-peer-bundler')
|
|
16
11
|
const { processModule, isESMFile } = require('./src/utils')
|
|
17
12
|
const log = require('./src/log')
|
|
18
13
|
|
|
@@ -133,19 +128,6 @@ module.exports.setup = function (build) {
|
|
|
133
128
|
${build.initialOptions.banner.js}`
|
|
134
129
|
}
|
|
135
130
|
|
|
136
|
-
// Keep the build from failing on the optional `@openfeature/core` peer of
|
|
137
|
-
// `@openfeature/server-sdk` when it is not installed (#8635). esbuild follows the chain
|
|
138
|
-
// whenever `@openfeature/server-sdk` is reachable -- the app importing it directly, or the
|
|
139
|
-
// bundled provider when the optional peer is present -- so mark `@openfeature/core` external
|
|
140
|
-
// when it is absent rather than erroring at bundle time.
|
|
141
|
-
try {
|
|
142
|
-
// eslint-disable-next-line n/no-unpublished-require
|
|
143
|
-
require.resolve('@openfeature/core')
|
|
144
|
-
} catch {
|
|
145
|
-
build.initialOptions.external ??= []
|
|
146
|
-
build.initialOptions.external.push('@openfeature/core')
|
|
147
|
-
}
|
|
148
|
-
|
|
149
131
|
const esmBuild = isESMBuild(build)
|
|
150
132
|
if (
|
|
151
133
|
esmBuild &&
|
|
@@ -182,22 +164,6 @@ ${build.initialOptions.banner.js}`
|
|
|
182
164
|
log.warn('No git metadata available - skipping injection')
|
|
183
165
|
}
|
|
184
166
|
|
|
185
|
-
// Rewrite optional-peer loads so installed peers get bundled and survive the bundle being
|
|
186
|
-
// relocated without them on disk (#8980). Registered before the generic onLoad so it wins for
|
|
187
|
-
// these files. Absent peers stay opaque, so a build that does not opt into the feature does not
|
|
188
|
-
// follow their dependency chain (#8635).
|
|
189
|
-
build.onLoad({ filter: OPTIONAL_PEER_FILTER }, args => {
|
|
190
|
-
const normalizedPath = args.path.replaceAll('\\', '/')
|
|
191
|
-
if (!matchesOptionalPeerFile(normalizedPath)) return
|
|
192
|
-
|
|
193
|
-
log.debug('INLINE: optional-peer loader applied to %s', normalizedPath)
|
|
194
|
-
return {
|
|
195
|
-
contents: rewriteOptionalPeerLoads(fs.readFileSync(args.path, 'utf8'), path.dirname(args.path)),
|
|
196
|
-
loader: 'js',
|
|
197
|
-
resolveDir: path.dirname(args.path),
|
|
198
|
-
}
|
|
199
|
-
})
|
|
200
|
-
|
|
201
167
|
// first time is intercepted, proxy should be created, next time the original should be loaded
|
|
202
168
|
const interceptedESMModules = new Set()
|
|
203
169
|
|
|
@@ -6,6 +6,144 @@ const { addHook } = require('./helpers/instrument')
|
|
|
6
6
|
|
|
7
7
|
const anthropicTracingChannel = tracingChannel('apm:anthropic:request')
|
|
8
8
|
const onStreamedChunkCh = channel('apm:anthropic:request:chunk')
|
|
9
|
+
const messagesBeforeChannel = channel('dd-trace:anthropic:messages:before')
|
|
10
|
+
const messagesAfterChannel = channel('dd-trace:anthropic:messages:after')
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Publishes a provider-native lifecycle payload to a cancelable lifecycle channel.
|
|
14
|
+
*
|
|
15
|
+
* Subscribers push async work into `pending` synchronously during publication and
|
|
16
|
+
* abort `abortController` with an error before the pushed promise resolves to block.
|
|
17
|
+
*
|
|
18
|
+
* @param {object} channel
|
|
19
|
+
* @param {object} payload
|
|
20
|
+
* @returns {Promise<void>}
|
|
21
|
+
*/
|
|
22
|
+
function publishLifecycle (channel, payload) {
|
|
23
|
+
const abortController = new AbortController()
|
|
24
|
+
const ctx = { ...payload, abortController, pending: [] }
|
|
25
|
+
|
|
26
|
+
channel.publish(ctx)
|
|
27
|
+
|
|
28
|
+
return Promise.all(ctx.pending).then(() => {
|
|
29
|
+
if (abortController.signal.aborted) {
|
|
30
|
+
throw abortController.signal.reason
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @template T
|
|
37
|
+
* @param {Promise<T>} promise
|
|
38
|
+
* @param {Promise<void>|undefined} verdict
|
|
39
|
+
* @returns {Promise<T>}
|
|
40
|
+
*/
|
|
41
|
+
function waitForVerdict (promise, verdict) {
|
|
42
|
+
if (!verdict) return promise
|
|
43
|
+
|
|
44
|
+
// The lifecycle verdict takes precedence over an earlier SDK rejection.
|
|
45
|
+
promise.catch(() => {})
|
|
46
|
+
return verdict.then(() => promise)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @param {Array<unknown>} args
|
|
51
|
+
* @returns {Array<unknown>|undefined}
|
|
52
|
+
*/
|
|
53
|
+
function snapshotLifecycleArgs (args) {
|
|
54
|
+
const options = args[0]
|
|
55
|
+
if (!options || typeof options !== 'object') return
|
|
56
|
+
|
|
57
|
+
const input = { messages: options.messages }
|
|
58
|
+
if (options.system !== undefined) input.system = options.system
|
|
59
|
+
|
|
60
|
+
// Snapshot via JSON so AI Guard evaluates exactly what the SDK serializes and sends, immune to
|
|
61
|
+
// later caller mutation. If it can't serialize (e.g. circular), the SDK's own serialization would
|
|
62
|
+
// fail too, so skipping evaluation is safe — nothing reaches the model.
|
|
63
|
+
try {
|
|
64
|
+
const snapshot = [...args]
|
|
65
|
+
// eslint-disable-next-line unicorn/prefer-structured-clone
|
|
66
|
+
snapshot[0] = { ...options, ...JSON.parse(JSON.stringify(input)) }
|
|
67
|
+
return snapshot
|
|
68
|
+
} catch {
|
|
69
|
+
// Unserializable input — leave AI Guard inactive for this call (the SDK send would fail too).
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Finishes after output evaluation so a block propagates to the caller and span.
|
|
75
|
+
*
|
|
76
|
+
* @param {object} ctx
|
|
77
|
+
* @param {object} result
|
|
78
|
+
* @param {(body: object) => Promise<void>|undefined} getVerdict
|
|
79
|
+
* @param {object|string} [returnedResult]
|
|
80
|
+
* @returns {object|string|Promise<object|string>}
|
|
81
|
+
*/
|
|
82
|
+
function finishResult (ctx, result, getVerdict, returnedResult = result) {
|
|
83
|
+
const verdict = getVerdict(result)
|
|
84
|
+
if (!verdict) {
|
|
85
|
+
finish(ctx, result)
|
|
86
|
+
return returnedResult
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return verdict.then(() => {
|
|
90
|
+
finish(ctx, result)
|
|
91
|
+
return returnedResult
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @param {object} ctx
|
|
97
|
+
* @param {Error} error
|
|
98
|
+
* @throws {Error} Always rethrows the supplied error.
|
|
99
|
+
*/
|
|
100
|
+
function finishAndThrow (ctx, error) {
|
|
101
|
+
finish(ctx, null, error)
|
|
102
|
+
throw error
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @param {object} response
|
|
107
|
+
* @param {'json'|'text'} method
|
|
108
|
+
* @param {object} ctx
|
|
109
|
+
* @param {(body: object) => Promise<void>|undefined} getVerdict
|
|
110
|
+
*/
|
|
111
|
+
function wrapResponseReader (response, method, ctx, getVerdict) {
|
|
112
|
+
if (typeof response[method] !== 'function') return
|
|
113
|
+
|
|
114
|
+
shimmer.wrap(response, method, original => function (...args) {
|
|
115
|
+
return original.apply(this, args)
|
|
116
|
+
.then(body => {
|
|
117
|
+
if (method === 'json') return finishResult(ctx, body, getVerdict)
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
return finishResult(ctx, JSON.parse(body), getVerdict, body)
|
|
121
|
+
} catch {
|
|
122
|
+
finish(ctx)
|
|
123
|
+
return body
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
.catch(error => finishAndThrow(ctx, error))
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @param {object} response
|
|
132
|
+
* @param {object} ctx
|
|
133
|
+
* @param {(body: object) => Promise<void>|undefined} getVerdict
|
|
134
|
+
*/
|
|
135
|
+
function wrapRawResponse (response, ctx, getVerdict) {
|
|
136
|
+
wrapResponseReader(response, 'json', ctx, getVerdict)
|
|
137
|
+
wrapResponseReader(response, 'text', ctx, getVerdict)
|
|
138
|
+
|
|
139
|
+
if (typeof response.clone !== 'function') return
|
|
140
|
+
|
|
141
|
+
shimmer.wrap(response, 'clone', clone => function (...args) {
|
|
142
|
+
const clonedResponse = clone.apply(this, args)
|
|
143
|
+
wrapRawResponse(clonedResponse, ctx, getVerdict)
|
|
144
|
+
return clonedResponse
|
|
145
|
+
})
|
|
146
|
+
}
|
|
9
147
|
|
|
10
148
|
function wrapStreamIterator (iterator, ctx) {
|
|
11
149
|
return function (...args) {
|
|
@@ -34,40 +172,94 @@ function wrapStreamIterator (iterator, ctx) {
|
|
|
34
172
|
|
|
35
173
|
function wrapCreate (create) {
|
|
36
174
|
return function (...args) {
|
|
37
|
-
|
|
175
|
+
const options = args[0]
|
|
176
|
+
const stream = options?.stream
|
|
177
|
+
|
|
178
|
+
// Streaming is out of scope for lifecycle evaluation.
|
|
179
|
+
const lifecycleArgs = !stream &&
|
|
180
|
+
(messagesBeforeChannel.hasSubscribers || messagesAfterChannel.hasSubscribers)
|
|
181
|
+
? snapshotLifecycleArgs(args)
|
|
182
|
+
: undefined
|
|
183
|
+
|
|
184
|
+
if (!anthropicTracingChannel.start.hasSubscribers && !lifecycleArgs) {
|
|
38
185
|
return create.apply(this, args)
|
|
39
186
|
}
|
|
40
187
|
|
|
41
|
-
const
|
|
42
|
-
const stream = options.stream
|
|
43
|
-
|
|
44
|
-
const ctx = { options, resource: 'create', baseUrl: this._client?.baseURL }
|
|
188
|
+
const ctx = { options: lifecycleArgs?.[0] ?? options, resource: 'create', baseUrl: this._client?.baseURL }
|
|
45
189
|
|
|
46
190
|
return anthropicTracingChannel.start.runStores(ctx, () => {
|
|
191
|
+
const parentSpan = lifecycleArgs ? ctx.currentStore?.span : undefined
|
|
192
|
+
|
|
47
193
|
let apiPromise
|
|
48
194
|
try {
|
|
49
|
-
|
|
195
|
+
// Anthropic starts the request eagerly; the input verdict only gates result delivery.
|
|
196
|
+
apiPromise = create.apply(this, lifecycleArgs ?? args)
|
|
50
197
|
} catch (error) {
|
|
51
198
|
finish(ctx, null, error)
|
|
52
199
|
throw error
|
|
53
200
|
}
|
|
54
201
|
|
|
55
|
-
|
|
56
|
-
|
|
202
|
+
let beforeVerdict
|
|
203
|
+
let afterVerdict
|
|
204
|
+
let parseResult
|
|
205
|
+
let wrappedResponse
|
|
206
|
+
|
|
207
|
+
function getBeforeVerdict () {
|
|
208
|
+
if (!lifecycleArgs || beforeVerdict) return beforeVerdict
|
|
209
|
+
if (!messagesBeforeChannel.hasSubscribers) return
|
|
210
|
+
|
|
211
|
+
beforeVerdict = publishLifecycle(messagesBeforeChannel, { args: lifecycleArgs, parentSpan })
|
|
212
|
+
return beforeVerdict
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* @param {object|string} body
|
|
217
|
+
*/
|
|
218
|
+
function getAfterVerdict (body) {
|
|
219
|
+
if (!lifecycleArgs || afterVerdict) return afterVerdict
|
|
220
|
+
if (!messagesAfterChannel.hasSubscribers) return
|
|
221
|
+
|
|
222
|
+
afterVerdict = publishLifecycle(messagesAfterChannel, { args: lifecycleArgs, body, parentSpan })
|
|
223
|
+
return afterVerdict
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
shimmer.wrap(apiPromise, 'parse', parse => function (...parseArgs) {
|
|
227
|
+
if (parseResult) return parseResult
|
|
228
|
+
|
|
229
|
+
const parsed = parse.apply(this, parseArgs)
|
|
230
|
+
parseResult = waitForVerdict(parsed, getBeforeVerdict())
|
|
57
231
|
.then(response => {
|
|
58
232
|
if (stream) {
|
|
59
233
|
shimmer.wrap(response, Symbol.asyncIterator, iterator => wrapStreamIterator(iterator, ctx))
|
|
60
|
-
|
|
61
|
-
finish(ctx, response, null)
|
|
234
|
+
return response
|
|
62
235
|
}
|
|
63
|
-
|
|
64
|
-
return response
|
|
65
|
-
}).catch(error => {
|
|
66
|
-
finish(ctx, null, error)
|
|
67
|
-
throw error
|
|
236
|
+
return finishResult(ctx, response, getAfterVerdict)
|
|
68
237
|
})
|
|
238
|
+
.catch(error => finishAndThrow(ctx, error))
|
|
239
|
+
|
|
240
|
+
return parseResult
|
|
69
241
|
})
|
|
70
242
|
|
|
243
|
+
if (typeof apiPromise.asResponse === 'function') {
|
|
244
|
+
shimmer.wrap(apiPromise, 'asResponse', origAsResponse => function (...asResponseArgs) {
|
|
245
|
+
return waitForVerdict(origAsResponse.apply(this, asResponseArgs), getBeforeVerdict())
|
|
246
|
+
.then(response => {
|
|
247
|
+
// Wrap the raw response's json()/text()/clone() readers to evaluate output on read,
|
|
248
|
+
// but only while someone still consumes the result and not twice for the same response.
|
|
249
|
+
const outputObserved = anthropicTracingChannel.start.hasSubscribers ||
|
|
250
|
+
afterVerdict || messagesAfterChannel.hasSubscribers
|
|
251
|
+
if (!stream && outputObserved && wrappedResponse !== response) {
|
|
252
|
+
wrappedResponse = response
|
|
253
|
+
wrapRawResponse(response, ctx, getAfterVerdict)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (afterVerdict) return afterVerdict.then(() => response)
|
|
257
|
+
return response
|
|
258
|
+
})
|
|
259
|
+
.catch(error => finishAndThrow(ctx, error))
|
|
260
|
+
})
|
|
261
|
+
}
|
|
262
|
+
|
|
71
263
|
anthropicTracingChannel.end.publish(ctx)
|
|
72
264
|
|
|
73
265
|
return apiPromise
|
|
@@ -76,6 +268,8 @@ function wrapCreate (create) {
|
|
|
76
268
|
}
|
|
77
269
|
|
|
78
270
|
function finish (ctx, result, error) {
|
|
271
|
+
if (ctx.finished) return
|
|
272
|
+
|
|
79
273
|
if (error) {
|
|
80
274
|
ctx.error = error
|
|
81
275
|
anthropicTracingChannel.error.publish(ctx)
|
|
@@ -83,6 +277,7 @@ function finish (ctx, result, error) {
|
|
|
83
277
|
|
|
84
278
|
// streamed responses are handled and set separately
|
|
85
279
|
ctx.result ??= result
|
|
280
|
+
ctx.finished = true
|
|
86
281
|
|
|
87
282
|
anthropicTracingChannel.asyncEnd.publish(ctx)
|
|
88
283
|
}
|