deepline 0.1.63 → 0.1.65
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/dist/cli/index.js +933 -533
- package/dist/cli/index.mjs +837 -421
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +102 -49
- package/dist/index.mjs +98 -45
- package/dist/repo/apps/play-runner-workers/src/coordinator-entry.ts +9 -10
- package/dist/repo/apps/play-runner-workers/src/runtime/dataset-handles.ts +36 -27
- package/dist/repo/apps/play-runner-workers/src/runtime/tool-http-errors.ts +5 -2
- package/dist/repo/sdk/src/client.ts +71 -63
- package/dist/repo/sdk/src/errors.ts +5 -1
- package/dist/repo/sdk/src/http.ts +69 -17
- package/dist/repo/sdk/src/plays/local-file-discovery.ts +93 -24
- package/dist/repo/sdk/src/release.ts +2 -2
- package/dist/repo/sdk/src/tool-output.ts +40 -20
- package/dist/repo/shared_libs/play-runtime/batch-runtime.ts +10 -3
- package/dist/repo/shared_libs/play-runtime/batching-types.ts +15 -4
- package/dist/repo/shared_libs/play-runtime/coordinator-headers.ts +2 -1
- package/dist/repo/shared_libs/play-runtime/dedup-backend.ts +0 -0
- package/dist/repo/shared_libs/play-runtime/default-batch-strategies.ts +3 -4
- package/dist/repo/shared_libs/play-runtime/run-failure.ts +1 -3
- package/dist/repo/shared_libs/play-runtime/step-lifecycle-tracker.ts +4 -1
- package/dist/repo/shared_libs/play-runtime/tool-batch-executor.ts +4 -1
- package/dist/repo/shared_libs/plays/dataset.ts +10 -11
- package/package.json +1 -1
|
@@ -35,7 +35,10 @@ export type WorkerDatasetCapabilities = {
|
|
|
35
35
|
materialization: 'bounded' | 'in_memory';
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
const datasetChunkReaders = new WeakMap<
|
|
38
|
+
const datasetChunkReaders = new WeakMap<
|
|
39
|
+
object,
|
|
40
|
+
DatasetChunkReader<DatasetRow>
|
|
41
|
+
>();
|
|
39
42
|
const datasetCountHints = new WeakMap<object, number | null>();
|
|
40
43
|
const datasetCapabilities = new WeakMap<object, WorkerDatasetCapabilities>();
|
|
41
44
|
|
|
@@ -154,11 +157,7 @@ export function createPersistedDatasetHandle<T extends DatasetRow>(input: {
|
|
|
154
157
|
sourceLabel?: string | null;
|
|
155
158
|
workProgress?: PlayDatasetWorkProgressSummary;
|
|
156
159
|
readRows: (input: { limit: number; offset: number }) => Promise<readonly T[]>;
|
|
157
|
-
trace?: (
|
|
158
|
-
phase: string,
|
|
159
|
-
ms: number,
|
|
160
|
-
extra?: Record<string, unknown>,
|
|
161
|
-
) => void;
|
|
160
|
+
trace?: (phase: string, ms: number, extra?: Record<string, unknown>) => void;
|
|
162
161
|
nowMs: () => number;
|
|
163
162
|
}): WorkerDatasetHandle<T> {
|
|
164
163
|
const datasetKind = input.datasetKind ?? 'map';
|
|
@@ -202,7 +201,9 @@ export function createPersistedDatasetHandle<T extends DatasetRow>(input: {
|
|
|
202
201
|
return rows.map(internalDatasetRow);
|
|
203
202
|
}
|
|
204
203
|
|
|
205
|
-
async function* readChunks(
|
|
204
|
+
async function* readChunks(
|
|
205
|
+
chunkSize: number,
|
|
206
|
+
): AsyncGenerator<T[], void, void> {
|
|
206
207
|
const size = normalizedChunkSize(chunkSize);
|
|
207
208
|
let offset = 0;
|
|
208
209
|
while (offset < count) {
|
|
@@ -255,13 +256,18 @@ export function createPersistedDatasetHandle<T extends DatasetRow>(input: {
|
|
|
255
256
|
}) as AsyncIterable<T>,
|
|
256
257
|
},
|
|
257
258
|
});
|
|
258
|
-
return registerChunkReader(
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
259
|
+
return registerChunkReader(
|
|
260
|
+
dataset,
|
|
261
|
+
(chunkSize) => readChunks(chunkSize),
|
|
262
|
+
count,
|
|
263
|
+
{
|
|
264
|
+
storage: 'runtime_sheet',
|
|
265
|
+
chunkReadable: true,
|
|
266
|
+
pageBacked: true,
|
|
267
|
+
replayable: true,
|
|
268
|
+
materialization: 'bounded',
|
|
269
|
+
},
|
|
270
|
+
);
|
|
265
271
|
}
|
|
266
272
|
|
|
267
273
|
export function createCsvDatasetHandle<T extends DatasetRow>(input: {
|
|
@@ -274,17 +280,15 @@ export function createCsvDatasetHandle<T extends DatasetRow>(input: {
|
|
|
274
280
|
byteChunks: AsyncIterable<Uint8Array>,
|
|
275
281
|
chunkSize: number,
|
|
276
282
|
) => AsyncIterable<T[]>;
|
|
277
|
-
trace?: (
|
|
278
|
-
phase: string,
|
|
279
|
-
ms: number,
|
|
280
|
-
extra?: Record<string, unknown>,
|
|
281
|
-
) => void;
|
|
283
|
+
trace?: (phase: string, ms: number, extra?: Record<string, unknown>) => void;
|
|
282
284
|
nowMs: () => number;
|
|
283
285
|
}): WorkerDatasetHandle<T> {
|
|
284
286
|
const datasetId = `csv:${input.name}`;
|
|
285
287
|
let cachedCount: number | null = null;
|
|
286
288
|
|
|
287
|
-
async function* readChunks(
|
|
289
|
+
async function* readChunks(
|
|
290
|
+
chunkSize: number,
|
|
291
|
+
): AsyncGenerator<T[], void, void> {
|
|
288
292
|
const startedAt = input.nowMs();
|
|
289
293
|
let yieldedRows = 0;
|
|
290
294
|
let yieldedChunks = 0;
|
|
@@ -386,13 +390,18 @@ export function createCsvDatasetHandle<T extends DatasetRow>(input: {
|
|
|
386
390
|
}) as AsyncIterable<T>,
|
|
387
391
|
},
|
|
388
392
|
});
|
|
389
|
-
return registerChunkReader(
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
393
|
+
return registerChunkReader(
|
|
394
|
+
dataset,
|
|
395
|
+
(chunkSize) => readChunks(chunkSize),
|
|
396
|
+
null,
|
|
397
|
+
{
|
|
398
|
+
storage: 'csv_stream',
|
|
399
|
+
chunkReadable: true,
|
|
400
|
+
pageBacked: false,
|
|
401
|
+
replayable: true,
|
|
402
|
+
materialization: 'bounded',
|
|
403
|
+
},
|
|
404
|
+
);
|
|
396
405
|
}
|
|
397
406
|
|
|
398
407
|
export function createInlineDatasetHandle<T extends DatasetRow>(
|
|
@@ -79,7 +79,8 @@ function normalizeHardBillingPayload(
|
|
|
79
79
|
: 'MONTHLY_BILLING_LIMIT_EXCEEDED',
|
|
80
80
|
error_category: 'billing',
|
|
81
81
|
failure_origin:
|
|
82
|
-
typeof payload.failure_origin === 'string' &&
|
|
82
|
+
typeof payload.failure_origin === 'string' &&
|
|
83
|
+
payload.failure_origin.trim()
|
|
83
84
|
? payload.failure_origin
|
|
84
85
|
: 'deepline_billing',
|
|
85
86
|
message:
|
|
@@ -194,5 +195,7 @@ export function extractErrorBilling(
|
|
|
194
195
|
}
|
|
195
196
|
|
|
196
197
|
export function isHardBillingToolHttpError(error: unknown): boolean {
|
|
197
|
-
return
|
|
198
|
+
return (
|
|
199
|
+
error instanceof ToolHttpError && isHardBillingFailurePayload(error.billing)
|
|
200
|
+
);
|
|
198
201
|
}
|
|
@@ -183,11 +183,11 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|
|
183
183
|
function isPlayRunPackage(value: unknown): value is PlayRunPackage {
|
|
184
184
|
return Boolean(
|
|
185
185
|
value &&
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
186
|
+
typeof value === 'object' &&
|
|
187
|
+
!Array.isArray(value) &&
|
|
188
|
+
(value as Record<string, unknown>).kind === 'play_run' &&
|
|
189
|
+
(value as Record<string, unknown>).run &&
|
|
190
|
+
typeof (value as { run?: { id?: unknown } }).run?.id === 'string',
|
|
191
191
|
);
|
|
192
192
|
}
|
|
193
193
|
|
|
@@ -209,7 +209,7 @@ function normalizePlayStatus(raw: Record<string, unknown>): PlayStatus {
|
|
|
209
209
|
? raw.runId
|
|
210
210
|
: typeof raw.workflowId === 'string'
|
|
211
211
|
? raw.workflowId
|
|
212
|
-
: packageRun?.id ?? '';
|
|
212
|
+
: (packageRun?.id ?? '');
|
|
213
213
|
return {
|
|
214
214
|
...(raw as unknown as Omit<PlayStatus, 'runId' | 'status'>),
|
|
215
215
|
runId,
|
|
@@ -228,7 +228,9 @@ function normalizePlayRunStart(raw: Record<string, unknown>): PlayRunStart {
|
|
|
228
228
|
return raw as unknown as PlayRunStart;
|
|
229
229
|
}
|
|
230
230
|
const status =
|
|
231
|
-
typeof runPackage.run.status === 'string'
|
|
231
|
+
typeof runPackage.run.status === 'string'
|
|
232
|
+
? runPackage.run.status
|
|
233
|
+
: 'running';
|
|
232
234
|
return {
|
|
233
235
|
workflowId: runPackage.run.id,
|
|
234
236
|
name: runPackage.run.playName,
|
|
@@ -236,9 +238,7 @@ function normalizePlayRunStart(raw: Record<string, unknown>): PlayRunStart {
|
|
|
236
238
|
...(runPackage.run.dashboardUrl
|
|
237
239
|
? { dashboardUrl: runPackage.run.dashboardUrl }
|
|
238
240
|
: {}),
|
|
239
|
-
...(TERMINAL_PLAY_STATUSES.has(status)
|
|
240
|
-
? { finalStatus: runPackage }
|
|
241
|
-
: {}),
|
|
241
|
+
...(TERMINAL_PLAY_STATUSES.has(status) ? { finalStatus: runPackage } : {}),
|
|
242
242
|
package: runPackage,
|
|
243
243
|
};
|
|
244
244
|
}
|
|
@@ -267,7 +267,9 @@ type PlayLiveStatusState = {
|
|
|
267
267
|
latest: PlayStatus | null;
|
|
268
268
|
};
|
|
269
269
|
|
|
270
|
-
function getPlayLiveEventPayload(
|
|
270
|
+
function getPlayLiveEventPayload(
|
|
271
|
+
event: PlayLiveEvent,
|
|
272
|
+
): Record<string, unknown> {
|
|
271
273
|
return event.payload && typeof event.payload === 'object'
|
|
272
274
|
? (event.payload as Record<string, unknown>)
|
|
273
275
|
: {};
|
|
@@ -309,16 +311,14 @@ function updatePlayLiveStatusState(
|
|
|
309
311
|
? payload.runId
|
|
310
312
|
: isPlayRunPackage(payload)
|
|
311
313
|
? payload.run.id
|
|
312
|
-
|
|
314
|
+
: state.runId;
|
|
313
315
|
const status =
|
|
314
316
|
normalizeLiveStatus(payload.status) ??
|
|
315
317
|
(isPlayRunPackage(payload)
|
|
316
318
|
? normalizeLiveStatus(payload.run.status)
|
|
317
319
|
: null) ??
|
|
318
320
|
state.status;
|
|
319
|
-
const progressPayload = isRecord(payload.progress)
|
|
320
|
-
? payload.progress
|
|
321
|
-
: {};
|
|
321
|
+
const progressPayload = isRecord(payload.progress) ? payload.progress : {};
|
|
322
322
|
const payloadLogs = readStringArray(payload.logs);
|
|
323
323
|
const progressLogs = readStringArray(progressPayload.logs);
|
|
324
324
|
const logs = payloadLogs.length > 0 ? payloadLogs : progressLogs;
|
|
@@ -342,7 +342,10 @@ function updatePlayLiveStatusState(
|
|
|
342
342
|
|
|
343
343
|
const progressRecord = progressPayload;
|
|
344
344
|
const next: PlayStatus = {
|
|
345
|
-
...(payload as unknown as Omit<
|
|
345
|
+
...(payload as unknown as Omit<
|
|
346
|
+
PlayStatus,
|
|
347
|
+
'runId' | 'status' | 'progress'
|
|
348
|
+
>),
|
|
346
349
|
runId,
|
|
347
350
|
status,
|
|
348
351
|
...(isPlayRunPackage(payload)
|
|
@@ -485,7 +488,9 @@ export class DeeplineClient {
|
|
|
485
488
|
return `deepline plays run ${target} --input '{...}' --watch`;
|
|
486
489
|
}
|
|
487
490
|
|
|
488
|
-
private starterPlayPath(
|
|
491
|
+
private starterPlayPath(
|
|
492
|
+
play: Pick<PlayListItem, 'name' | 'reference'>,
|
|
493
|
+
): string {
|
|
489
494
|
const target = play.reference || play.name;
|
|
490
495
|
const unqualifiedName = target.split('/').pop() || play.name;
|
|
491
496
|
const safeName = unqualifiedName
|
|
@@ -741,47 +746,50 @@ export class DeeplineClient {
|
|
|
741
746
|
* artifactStorageKey: 'plays/v1/orgs/acme/plays/my-play/artifacts/playgraph_abc123.json',
|
|
742
747
|
* });
|
|
743
748
|
* ```
|
|
744
|
-
|
|
749
|
+
*/
|
|
745
750
|
async startPlayRun(request: StartPlayRunRequest): Promise<PlayRunStart> {
|
|
746
|
-
const response = await this.http.post<Record<string, unknown>>(
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
? {
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
? {
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
? {
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
? {
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
? {
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
751
|
+
const response = await this.http.post<Record<string, unknown>>(
|
|
752
|
+
'/api/v2/plays/run',
|
|
753
|
+
{
|
|
754
|
+
...(request.name ? { name: request.name } : {}),
|
|
755
|
+
...(request.revisionId ? { revisionId: request.revisionId } : {}),
|
|
756
|
+
...(request.artifactStorageKey
|
|
757
|
+
? { artifactStorageKey: request.artifactStorageKey }
|
|
758
|
+
: {}),
|
|
759
|
+
...(request.sourceCode ? { sourceCode: request.sourceCode } : {}),
|
|
760
|
+
...(request.sourceFiles ? { sourceFiles: request.sourceFiles } : {}),
|
|
761
|
+
...('staticPipeline' in request
|
|
762
|
+
? { staticPipeline: request.staticPipeline }
|
|
763
|
+
: {}),
|
|
764
|
+
...(request.artifactHash ? { artifactHash: request.artifactHash } : {}),
|
|
765
|
+
...(request.graphHash ? { graphHash: request.graphHash } : {}),
|
|
766
|
+
...(request.runtimeArtifact
|
|
767
|
+
? { runtimeArtifact: request.runtimeArtifact }
|
|
768
|
+
: {}),
|
|
769
|
+
...(request.compilerManifest
|
|
770
|
+
? { compilerManifest: request.compilerManifest }
|
|
771
|
+
: {}),
|
|
772
|
+
...(request.inputFileUpload
|
|
773
|
+
? { inputFileUpload: request.inputFileUpload }
|
|
774
|
+
: {}),
|
|
775
|
+
...(request.packagedFileUploads?.length
|
|
776
|
+
? { packagedFileUploads: request.packagedFileUploads }
|
|
777
|
+
: {}),
|
|
778
|
+
...(request.input ? { input: request.input } : {}),
|
|
779
|
+
...(request.inputFile ? { inputFile: request.inputFile } : {}),
|
|
780
|
+
...(request.packagedFiles?.length
|
|
781
|
+
? { packagedFiles: request.packagedFiles }
|
|
782
|
+
: {}),
|
|
783
|
+
...(request.force ? { force: true } : {}),
|
|
784
|
+
...(typeof request.waitForCompletionMs === 'number'
|
|
785
|
+
? { waitForCompletionMs: request.waitForCompletionMs }
|
|
786
|
+
: {}),
|
|
787
|
+
// Profile selection is the API's job, not the CLI's. The server
|
|
788
|
+
// hardcodes workers_edge as the default; tests that want a
|
|
789
|
+
// different profile pass `request.profile` explicitly.
|
|
790
|
+
...(request.profile ? { profile: request.profile } : {}),
|
|
791
|
+
},
|
|
792
|
+
);
|
|
785
793
|
return normalizePlayRunStart(response);
|
|
786
794
|
}
|
|
787
795
|
|
|
@@ -1173,10 +1181,9 @@ export class DeeplineClient {
|
|
|
1173
1181
|
}
|
|
1174
1182
|
return formData;
|
|
1175
1183
|
};
|
|
1176
|
-
const response = await this.http.postFormData<{
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
);
|
|
1184
|
+
const response = await this.http.postFormData<{
|
|
1185
|
+
files: PlayStagedFileRef[];
|
|
1186
|
+
}>('/api/v2/plays/files/stage', buildFormData);
|
|
1180
1187
|
return response.files;
|
|
1181
1188
|
}
|
|
1182
1189
|
|
|
@@ -1733,8 +1740,9 @@ export class DeeplineClient {
|
|
|
1733
1740
|
options?.onProgress?.(status);
|
|
1734
1741
|
|
|
1735
1742
|
if (TERMINAL_PLAY_STATUSES.has(status.status)) {
|
|
1736
|
-
const finalStatus = await this.getPlayStatus(
|
|
1737
|
-
.
|
|
1743
|
+
const finalStatus = await this.getPlayStatus(
|
|
1744
|
+
status.runId || workflowId,
|
|
1745
|
+
).catch(() => status);
|
|
1738
1746
|
return playRunResultFromStatus(finalStatus, start, workflowId);
|
|
1739
1747
|
}
|
|
1740
1748
|
}
|
|
@@ -92,7 +92,11 @@ export class RateLimitError extends DeeplineError {
|
|
|
92
92
|
public retryAfterMs: number;
|
|
93
93
|
|
|
94
94
|
constructor(retryAfterMs = 5000, message?: string) {
|
|
95
|
-
super(
|
|
95
|
+
super(
|
|
96
|
+
message ?? `Rate limited. Retry after ${retryAfterMs}ms.`,
|
|
97
|
+
429,
|
|
98
|
+
'RATE_LIMIT',
|
|
99
|
+
);
|
|
96
100
|
this.name = 'RateLimitError';
|
|
97
101
|
this.retryAfterMs = retryAfterMs;
|
|
98
102
|
}
|
|
@@ -18,16 +18,22 @@
|
|
|
18
18
|
*
|
|
19
19
|
* @module
|
|
20
20
|
*/
|
|
21
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
22
|
+
import { homedir } from 'node:os';
|
|
23
|
+
import { join } from 'node:path';
|
|
21
24
|
import type { ResolvedConfig } from './types.js';
|
|
22
25
|
import { AuthError, DeeplineError, RateLimitError } from './errors.js';
|
|
23
26
|
import { SDK_API_CONTRACT, SDK_VERSION } from './version.js';
|
|
24
27
|
import type { LiveEventEnvelope } from './types.js';
|
|
28
|
+
import { baseUrlSlug } from './config.js';
|
|
25
29
|
import {
|
|
26
30
|
COORDINATOR_INTERNAL_TOKEN_HEADER,
|
|
27
31
|
COORDINATOR_URL_OVERRIDE_HEADER,
|
|
28
32
|
WORKER_CALLBACK_URL_OVERRIDE_HEADER,
|
|
29
33
|
} from '../../shared_libs/play-runtime/coordinator-headers.js';
|
|
30
34
|
|
|
35
|
+
const MAX_DIAGNOSTIC_HEADER_LENGTH = 120;
|
|
36
|
+
|
|
31
37
|
interface RequestOptions {
|
|
32
38
|
method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
33
39
|
body?: unknown;
|
|
@@ -61,42 +67,85 @@ interface StreamOptions {
|
|
|
61
67
|
export class HttpClient {
|
|
62
68
|
constructor(private config: ResolvedConfig) {}
|
|
63
69
|
|
|
70
|
+
private cleanDiagnosticHeader(
|
|
71
|
+
value: string | null | undefined,
|
|
72
|
+
): string | null {
|
|
73
|
+
const normalized = String(value ?? '')
|
|
74
|
+
.replace(/[\u0000-\u001f\u007f]/g, ' ')
|
|
75
|
+
.trim()
|
|
76
|
+
.slice(0, MAX_DIAGNOSTIC_HEADER_LENGTH);
|
|
77
|
+
return normalized || null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private readSkillsVersionHeader(): string | null {
|
|
81
|
+
const explicit = this.cleanDiagnosticHeader(
|
|
82
|
+
process.env.DEEPLINE_SKILLS_VERSION,
|
|
83
|
+
);
|
|
84
|
+
if (explicit) return explicit;
|
|
85
|
+
try {
|
|
86
|
+
const versionPath = join(
|
|
87
|
+
process.env.HOME?.trim() || homedir(),
|
|
88
|
+
'.local',
|
|
89
|
+
'deepline',
|
|
90
|
+
baseUrlSlug(this.config.baseUrl),
|
|
91
|
+
'sdk-skills',
|
|
92
|
+
'.version',
|
|
93
|
+
);
|
|
94
|
+
if (!existsSync(versionPath)) return null;
|
|
95
|
+
return this.cleanDiagnosticHeader(readFileSync(versionPath, 'utf-8'));
|
|
96
|
+
} catch {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
64
101
|
private authHeaders(extra?: Record<string, string>): Record<string, string> {
|
|
65
102
|
const headers: Record<string, string> = {
|
|
66
|
-
|
|
103
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
67
104
|
'User-Agent': `deepline-ts-sdk/${SDK_VERSION}`,
|
|
105
|
+
'X-Deepline-Client-Family': 'sdk',
|
|
106
|
+
'X-Deepline-CLI-Family': 'sdk',
|
|
107
|
+
'X-Deepline-CLI-Version': SDK_VERSION,
|
|
68
108
|
'X-Deepline-SDK-Version': SDK_VERSION,
|
|
69
109
|
'X-Deepline-API-Contract': SDK_API_CONTRACT,
|
|
70
110
|
...extra,
|
|
71
111
|
};
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
112
|
+
const skillsVersion = this.readSkillsVersionHeader();
|
|
113
|
+
if (skillsVersion) {
|
|
114
|
+
headers['X-Deepline-Skills-Version'] = skillsVersion;
|
|
115
|
+
}
|
|
116
|
+
const bypassToken =
|
|
117
|
+
typeof process !== 'undefined'
|
|
118
|
+
? process.env?.VERCEL_PROTECTION_BYPASS_TOKEN
|
|
119
|
+
: undefined;
|
|
75
120
|
if (bypassToken) {
|
|
76
121
|
headers['x-vercel-protection-bypass'] = bypassToken;
|
|
77
122
|
}
|
|
78
|
-
const playArtifactR2Prefix =
|
|
79
|
-
|
|
80
|
-
|
|
123
|
+
const playArtifactR2Prefix =
|
|
124
|
+
typeof process !== 'undefined'
|
|
125
|
+
? process.env?.DEEPLINE_PLAY_ARTIFACT_R2_PREFIX
|
|
126
|
+
: undefined;
|
|
81
127
|
if (playArtifactR2Prefix) {
|
|
82
128
|
headers['x-deepline-play-artifact-r2-prefix'] = playArtifactR2Prefix;
|
|
83
129
|
}
|
|
84
|
-
const coordinatorUrl =
|
|
85
|
-
|
|
86
|
-
|
|
130
|
+
const coordinatorUrl =
|
|
131
|
+
typeof process !== 'undefined'
|
|
132
|
+
? process.env?.DEEPLINE_COORDINATOR_URL
|
|
133
|
+
: undefined;
|
|
87
134
|
if (coordinatorUrl?.trim()) {
|
|
88
135
|
headers[COORDINATOR_URL_OVERRIDE_HEADER] = coordinatorUrl.trim();
|
|
89
|
-
const coordinatorInternalToken =
|
|
90
|
-
|
|
91
|
-
|
|
136
|
+
const coordinatorInternalToken =
|
|
137
|
+
typeof process !== 'undefined'
|
|
138
|
+
? process.env?.DEEPLINE_INTERNAL_TOKEN
|
|
139
|
+
: undefined;
|
|
92
140
|
if (coordinatorInternalToken?.trim()) {
|
|
93
141
|
headers[COORDINATOR_INTERNAL_TOKEN_HEADER] =
|
|
94
142
|
coordinatorInternalToken.trim();
|
|
95
143
|
}
|
|
96
144
|
}
|
|
97
|
-
const workerCallbackUrl =
|
|
98
|
-
|
|
99
|
-
|
|
145
|
+
const workerCallbackUrl =
|
|
146
|
+
typeof process !== 'undefined'
|
|
147
|
+
? process.env?.DEEPLINE_WORKER_CALLBACK_URL
|
|
148
|
+
: undefined;
|
|
100
149
|
if (workerCallbackUrl?.trim()) {
|
|
101
150
|
headers[WORKER_CALLBACK_URL_OVERRIDE_HEADER] = workerCallbackUrl.trim();
|
|
102
151
|
}
|
|
@@ -114,7 +163,10 @@ export class HttpClient {
|
|
|
114
163
|
* @throws {@link RateLimitError} on HTTP 429 after all retries exhausted
|
|
115
164
|
* @throws {@link DeeplineError} on other API errors or connection failures
|
|
116
165
|
*/
|
|
117
|
-
async request<T = unknown>(
|
|
166
|
+
async request<T = unknown>(
|
|
167
|
+
path: string,
|
|
168
|
+
options?: RequestOptions,
|
|
169
|
+
): Promise<T> {
|
|
118
170
|
const baseUrl = this.config.baseUrl;
|
|
119
171
|
const url = `${baseUrl}${path}`;
|
|
120
172
|
const method = options?.method ?? 'GET';
|