dd-trace 6.10.0 → 6.12.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 +5 -0
- package/README.md +0 -17
- package/index.d.ts +128 -6
- package/initialize.mjs +28 -17
- package/openfeature.js +2 -2
- package/package.json +27 -23
- 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 +30 -15
- 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 +135 -19
- package/packages/datadog-instrumentations/src/playwright-reporter.js +247 -0
- package/packages/datadog-instrumentations/src/playwright.js +182 -35
- package/packages/datadog-instrumentations/src/router.js +2 -0
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +6 -8
- 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 +46 -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/appsec/reporter.js +2 -0
- package/packages/dd-trace/src/appsec/telemetry/index.js +13 -0
- package/packages/dd-trace/src/appsec/telemetry/rasp.js +16 -0
- package/packages/dd-trace/src/appsec/telemetry/waf.js +24 -0
- package/packages/dd-trace/src/carrier.js +107 -48
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +1 -0
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +5 -5
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +29 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +27 -9
- 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 +26 -8
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +365 -32
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +6 -4
- 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 +7 -4
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -2
- 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-coverage-report.js +4 -2
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +10 -4
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +5 -5
- 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/constants.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/index.js +5 -11
- package/packages/dd-trace/src/debugger/index.js +4 -2
- package/packages/dd-trace/src/debugger/inspect-segment.js +154 -0
- package/packages/dd-trace/src/evp_proxy/constants.js +8 -0
- package/packages/dd-trace/src/evp_proxy/direct.js +64 -0
- package/packages/dd-trace/src/evp_proxy/discovery.js +133 -0
- package/packages/dd-trace/src/evp_proxy/path.js +22 -0
- 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/request.js +5 -2
- package/packages/dd-trace/src/exporters/common/writer.js +11 -6
- package/packages/dd-trace/src/llmobs/experiments/client.js +167 -5
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +484 -92
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +302 -29
- package/packages/dd-trace/src/llmobs/experiments/index.js +75 -64
- package/packages/dd-trace/src/llmobs/experiments/noop.js +135 -7
- package/packages/dd-trace/src/llmobs/experiments/result.js +1 -0
- package/packages/dd-trace/src/llmobs/experiments/util.js +101 -9
- 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/constants/constants.js +0 -18
- package/packages/dd-trace/src/openfeature/flagging_provider.js +18 -2
- package/packages/dd-trace/src/openfeature/index.js +7 -4
- package/packages/dd-trace/src/openfeature/remote_config.js +1 -1
- package/packages/dd-trace/src/openfeature/writers/base.js +153 -11
- package/packages/dd-trace/src/openfeature/writers/exposures.js +62 -14
- package/packages/dd-trace/src/openfeature/writers/util.js +97 -15
- 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/propagation/text_map.js +22 -13
- 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/telemetry/metrics.js +62 -8
- package/packages/dd-trace/src/telemetry/send-data.js +1 -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/vendor/dist/@datadog/sketches-js/index.js +1 -1
- package/vendor/dist/https-proxy-agent/LICENSE +22 -0
- package/vendor/dist/https-proxy-agent/index.js +4 -0
- package/vendor/dist/protobufjs/index.js +1 -1
- package/vendor/dist/protobufjs/minimal/index.js +1 -1
- package/vendor/dist/proxy-from-env/LICENSE +20 -0
- package/vendor/dist/proxy-from-env/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
|
@@ -24,23 +24,25 @@ class BufferingExporter {
|
|
|
24
24
|
this._export(trace)
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
_export (payload, writer = this._writer, timerKey = '_timer') {
|
|
27
|
+
_export (payload, writer = this._writer, timerKey = '_timer', deferImmediateFlush = false) {
|
|
28
28
|
if (this._config.isCiVisibility) {
|
|
29
29
|
incrementCountMetric(TELEMETRY_EVENTS_ENQUEUED_FOR_SERIALIZATION, {}, payload.length)
|
|
30
30
|
}
|
|
31
|
-
writer.append(payload)
|
|
31
|
+
const appended = writer.append(payload)
|
|
32
32
|
|
|
33
33
|
const { flushInterval } = this._config
|
|
34
34
|
|
|
35
|
-
if (flushInterval === 0) {
|
|
35
|
+
if (flushInterval === 0 && !deferImmediateFlush) {
|
|
36
36
|
writer.flush()
|
|
37
|
-
} else if (this[timerKey] === undefined) {
|
|
37
|
+
} else if (flushInterval !== 0 && this[timerKey] === undefined) {
|
|
38
38
|
this[timerKey] = setTimeout(() => {
|
|
39
39
|
writer.flush()
|
|
40
40
|
this[timerKey] = undefined
|
|
41
41
|
}, flushInterval)
|
|
42
42
|
this[timerKey].unref?.()
|
|
43
43
|
}
|
|
44
|
+
|
|
45
|
+
return appended
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
getUncodedTraces () {
|
|
@@ -93,7 +93,10 @@ function request (data, options, callback) {
|
|
|
93
93
|
|
|
94
94
|
docker.inject(options.headers)
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
const connectionOptions = {
|
|
97
|
+
...options,
|
|
98
|
+
agent: options.agent ?? (isSecure ? httpsAgent : httpAgent),
|
|
99
|
+
}
|
|
97
100
|
|
|
98
101
|
/**
|
|
99
102
|
* @param {import('node:http').IncomingMessage} res
|
|
@@ -218,7 +221,7 @@ function request (data, options, callback) {
|
|
|
218
221
|
}
|
|
219
222
|
}
|
|
220
223
|
|
|
221
|
-
const req = client.request(
|
|
224
|
+
const req = client.request(connectionOptions, (res) => onResponse(res, complete, handleError))
|
|
222
225
|
|
|
223
226
|
req.once('close', finalize)
|
|
224
227
|
req.once('timeout', finalize)
|
|
@@ -17,10 +17,10 @@ class Writer {
|
|
|
17
17
|
|
|
18
18
|
#isFirstFlush = true
|
|
19
19
|
|
|
20
|
-
flush (done = () => {}) {
|
|
20
|
+
flush (done = () => {}, options) {
|
|
21
21
|
const count = this._encoder.count()
|
|
22
22
|
|
|
23
|
-
if (!request.writable) {
|
|
23
|
+
if (!request.writable && options?.deadline === undefined) {
|
|
24
24
|
this._encoder.reset()
|
|
25
25
|
done()
|
|
26
26
|
} else if (count > 0) {
|
|
@@ -44,23 +44,28 @@ class Writer {
|
|
|
44
44
|
done()
|
|
45
45
|
return
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
if (options === undefined) {
|
|
48
|
+
this._sendPayload(payload, count, done)
|
|
49
|
+
} else {
|
|
50
|
+
this._sendPayload(payload, count, done, options)
|
|
51
|
+
}
|
|
48
52
|
} else {
|
|
49
53
|
done()
|
|
50
54
|
}
|
|
51
55
|
}
|
|
52
56
|
|
|
53
|
-
append (payload) {
|
|
54
|
-
if (!request.writable) {
|
|
57
|
+
append (payload, options) {
|
|
58
|
+
if (!request.writable && options?.deadline === undefined) {
|
|
55
59
|
// eslint-disable-next-line eslint-rules/eslint-log-printf-style
|
|
56
60
|
log.debug(() => `Maximum number of active requests reached. Payload discarded: ${safeJSONStringify(payload)}`)
|
|
57
|
-
return
|
|
61
|
+
return false
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
// eslint-disable-next-line eslint-rules/eslint-log-printf-style
|
|
61
65
|
log.debug(() => `Encoding payload: ${safeJSONStringify(payload)}`)
|
|
62
66
|
|
|
63
67
|
this._encode(payload)
|
|
68
|
+
return true
|
|
64
69
|
}
|
|
65
70
|
|
|
66
71
|
_encode (payload) {
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
// Control-plane HTTP client for LLM Obs Experiments. Uses the global `fetch`,
|
|
4
4
|
// so this module adds no new dependency; credentials and site come from config.
|
|
5
5
|
|
|
6
|
+
const { Dataset, DatasetRecord } = require('./dataset')
|
|
7
|
+
const { ExperimentResult } = require('./result')
|
|
8
|
+
|
|
6
9
|
const API_BASE_PATH = '/api/v2/llm-obs/v1'
|
|
7
10
|
|
|
8
11
|
// Control-plane host for a Datadog site, e.g.
|
|
@@ -22,12 +25,68 @@ function appHost (site) {
|
|
|
22
25
|
return site.split('.').length === 2 ? `app.${site}` : site
|
|
23
26
|
}
|
|
24
27
|
|
|
28
|
+
function datasetRecordFromResource (resource) {
|
|
29
|
+
const attrs = resource?.attributes ?? resource ?? {}
|
|
30
|
+
const id = String(resource?.id ?? attrs.id ?? '')
|
|
31
|
+
if (id === '') throw new Error('Dataset record response is missing an id')
|
|
32
|
+
return new DatasetRecord(
|
|
33
|
+
attrs.input ?? null,
|
|
34
|
+
attrs.expected_output ?? null,
|
|
35
|
+
attrs.metadata ?? {},
|
|
36
|
+
id,
|
|
37
|
+
attrs.tags ?? []
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function datasetVersionFromResource (resource) {
|
|
42
|
+
const attrs = resource?.attributes ?? resource ?? {}
|
|
43
|
+
return attrs.valid_from_version ?? attrs.version ?? null
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function datasetVersionFromResources (resources) {
|
|
47
|
+
const versions = resources
|
|
48
|
+
.map(datasetVersionFromResource)
|
|
49
|
+
.filter(version => version != null)
|
|
50
|
+
.map(Number)
|
|
51
|
+
.filter(Number.isFinite)
|
|
52
|
+
if (versions.length === 0) return null
|
|
53
|
+
return Math.max(...versions)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function datasetMutationResultFromResources (resources) {
|
|
57
|
+
return {
|
|
58
|
+
records: resources.map(datasetRecordFromResource),
|
|
59
|
+
version: datasetVersionFromResources(resources),
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function datasetFromResource (client, projectId, resource) {
|
|
64
|
+
const attrs = resource?.attributes ?? resource ?? {}
|
|
65
|
+
const version = attrs.current_version ?? null
|
|
66
|
+
return Dataset.fromExisting(
|
|
67
|
+
client,
|
|
68
|
+
String(attrs.name ?? ''),
|
|
69
|
+
String(attrs.description ?? ''),
|
|
70
|
+
resource?.id ?? attrs.id ?? null,
|
|
71
|
+
projectId,
|
|
72
|
+
[],
|
|
73
|
+
version,
|
|
74
|
+
version
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function experimentFromResource (client, resource) {
|
|
79
|
+
const id = resource?.id
|
|
80
|
+
return new ExperimentResult(id, [], id == null ? null : `${client.appBase}/llm/experiments/${id}`)
|
|
81
|
+
}
|
|
82
|
+
|
|
25
83
|
class ExperimentsClient {
|
|
26
84
|
#apiKey
|
|
27
85
|
#appKey
|
|
28
86
|
#site
|
|
29
87
|
#projectName
|
|
30
88
|
#timeout
|
|
89
|
+
apiBase
|
|
31
90
|
#cachedProjectId
|
|
32
91
|
|
|
33
92
|
constructor ({ apiKey, appKey, site, projectName, timeout = 30_000 } = {}) {
|
|
@@ -36,6 +95,7 @@ class ExperimentsClient {
|
|
|
36
95
|
this.#site = site
|
|
37
96
|
this.#projectName = projectName
|
|
38
97
|
this.#timeout = timeout
|
|
98
|
+
this.apiBase = `https://${apiHost(this.#site)}`
|
|
39
99
|
this.#cachedProjectId = null
|
|
40
100
|
}
|
|
41
101
|
|
|
@@ -61,7 +121,7 @@ class ExperimentsClient {
|
|
|
61
121
|
// Low-level request. Builds https://api.<site><path>, attaches both keys, and
|
|
62
122
|
// returns the parsed JSON body. Throws with status + body on a non-2xx.
|
|
63
123
|
async request (method, path, body) {
|
|
64
|
-
const url =
|
|
124
|
+
const url = `${this.apiBase}${path}`
|
|
65
125
|
const headers = {
|
|
66
126
|
'DD-API-KEY': this.#apiKey,
|
|
67
127
|
'DD-APPLICATION-KEY': this.#appKey,
|
|
@@ -92,6 +152,110 @@ class ExperimentsClient {
|
|
|
92
152
|
return text ? JSON.parse(text) : {}
|
|
93
153
|
}
|
|
94
154
|
|
|
155
|
+
jsonApiRequest (method, path, type, attributes) {
|
|
156
|
+
return this.request(method, path, {
|
|
157
|
+
data: { type, attributes },
|
|
158
|
+
})
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async createProject (name) {
|
|
162
|
+
const response = await this.jsonApiRequest('POST', `${API_BASE_PATH}/projects`, 'projects', { name })
|
|
163
|
+
return response?.data ?? null
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async createDataset (projectId, attributes) {
|
|
167
|
+
const response = await this.jsonApiRequest('POST', `${API_BASE_PATH}/${projectId}/datasets`, 'datasets', attributes)
|
|
168
|
+
return datasetFromResource(this, projectId, response?.data ?? null)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
deleteDataset (projectId, datasetId) {
|
|
172
|
+
return this.jsonApiRequest('POST', `${API_BASE_PATH}/${projectId}/datasets/delete`, 'datasets', {
|
|
173
|
+
type: 'soft',
|
|
174
|
+
dataset_ids: [datasetId],
|
|
175
|
+
})
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async listDatasets (projectId, options = {}) {
|
|
179
|
+
const query = new URLSearchParams()
|
|
180
|
+
if (options.name !== undefined) query.set('filter[name]', options.name)
|
|
181
|
+
const response = await this.request('GET', `${API_BASE_PATH}/${projectId}/datasets?${query.toString()}`)
|
|
182
|
+
const resources = Array.isArray(response?.data) ? response.data : []
|
|
183
|
+
return resources.map(resource => datasetFromResource(this, projectId, resource))
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
async appendDatasetRecords (projectId, datasetId, records) {
|
|
187
|
+
const response = await this.jsonApiRequest(
|
|
188
|
+
'POST',
|
|
189
|
+
`${API_BASE_PATH}/${projectId}/datasets/${datasetId}/records`,
|
|
190
|
+
'datasets',
|
|
191
|
+
{ records }
|
|
192
|
+
)
|
|
193
|
+
// The append-records response has used both a top-level `records` array
|
|
194
|
+
// and JSON:API `data` resources. Accept either so generated/custom record
|
|
195
|
+
// ids are preserved for experiment row tagging.
|
|
196
|
+
const resources = Array.isArray(response?.records)
|
|
197
|
+
? response.records
|
|
198
|
+
: (Array.isArray(response?.data) ? response.data : [])
|
|
199
|
+
return datasetMutationResultFromResources(resources)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
async batchUpdateDatasetRecords (projectId, datasetId, attributes) {
|
|
203
|
+
const response = await this.request(
|
|
204
|
+
'POST',
|
|
205
|
+
`${API_BASE_PATH}/${projectId}/datasets/${datasetId}/batch_update`,
|
|
206
|
+
{
|
|
207
|
+
data: {
|
|
208
|
+
type: 'datasets',
|
|
209
|
+
id: datasetId,
|
|
210
|
+
attributes: {
|
|
211
|
+
insert_records: attributes.insert_records ?? [],
|
|
212
|
+
update_records: attributes.update_records ?? [],
|
|
213
|
+
delete_records: attributes.delete_records ?? [],
|
|
214
|
+
deduplicate: attributes.deduplicate !== false,
|
|
215
|
+
create_new_version: attributes.create_new_version !== false,
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
}
|
|
219
|
+
)
|
|
220
|
+
const resources = Array.isArray(response?.records)
|
|
221
|
+
? response.records
|
|
222
|
+
: (Array.isArray(response?.data) ? response.data : [])
|
|
223
|
+
return datasetMutationResultFromResources(resources)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async listDatasetRecords (projectId, datasetId, options = {}) {
|
|
227
|
+
const query = new URLSearchParams()
|
|
228
|
+
if (options.cursor) query.set('page[cursor]', options.cursor)
|
|
229
|
+
if (options.version !== undefined && options.version !== null) query.set('filter[version]', String(options.version))
|
|
230
|
+
if (Array.isArray(options.tags)) {
|
|
231
|
+
for (const tag of options.tags) query.append('filter[tags]', tag)
|
|
232
|
+
}
|
|
233
|
+
const response = await this.request(
|
|
234
|
+
'GET',
|
|
235
|
+
`${API_BASE_PATH}/${projectId}/datasets/${datasetId}/records?${query.toString()}`
|
|
236
|
+
)
|
|
237
|
+
const records = Array.isArray(response?.data) ? response.data.map(datasetRecordFromResource) : []
|
|
238
|
+
return { records, after: response?.meta?.after ?? '' }
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
async createExperiment (attributes) {
|
|
242
|
+
const response = await this.jsonApiRequest('POST', `${API_BASE_PATH}/experiments`, 'experiments', attributes)
|
|
243
|
+
return experimentFromResource(this, response?.data ?? null)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
postExperimentEvents (experimentId, attributes) {
|
|
247
|
+
return this.jsonApiRequest(
|
|
248
|
+
'POST',
|
|
249
|
+
`${API_BASE_PATH}/experiments/${experimentId}/events`,
|
|
250
|
+
'experiments',
|
|
251
|
+
attributes
|
|
252
|
+
)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
updateExperiment (experimentId, attributes) {
|
|
256
|
+
return this.jsonApiRequest('PATCH', `${API_BASE_PATH}/experiments/${experimentId}`, 'experiments', attributes)
|
|
257
|
+
}
|
|
258
|
+
|
|
95
259
|
// Resolve the project id for `name`, creating it if absent. The create
|
|
96
260
|
// endpoint is get-or-create on name, so repeated calls return the same id.
|
|
97
261
|
// Cached after the first resolution.
|
|
@@ -100,14 +264,12 @@ class ExperimentsClient {
|
|
|
100
264
|
|
|
101
265
|
let response
|
|
102
266
|
try {
|
|
103
|
-
response = await this.
|
|
104
|
-
data: { type: 'projects', attributes: { name } },
|
|
105
|
-
})
|
|
267
|
+
response = await this.createProject(name)
|
|
106
268
|
} catch (err) {
|
|
107
269
|
throw new Error(`Failed to create or get project '${name}': ${err.message}`)
|
|
108
270
|
}
|
|
109
271
|
|
|
110
|
-
this.#cachedProjectId = response?.
|
|
272
|
+
this.#cachedProjectId = response?.id ?? null
|
|
111
273
|
return this.#cachedProjectId
|
|
112
274
|
}
|
|
113
275
|
}
|