deepline 0.3.258 → 0.3.260
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/bundling-sources/sdk/src/api-error.ts +45 -0
- package/dist/bundling-sources/sdk/src/client.ts +98 -459
- package/dist/bundling-sources/sdk/src/http.ts +1 -34
- package/dist/bundling-sources/sdk/src/index.ts +8 -0
- package/dist/bundling-sources/sdk/src/plays/csv-data-input.ts +139 -0
- package/dist/bundling-sources/sdk/src/plays/run-request.ts +855 -0
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/runs/overview.ts +45 -2
- package/dist/bundling-sources/sdk/src/types.ts +5 -0
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +8 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +42 -10
- package/dist/bundling-sources/shared_libs/play-runtime/launch-identity.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/launch-source-policy.ts +23 -0
- package/dist/bundling-sources/shared_libs/play-runtime/live-state-contract.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-admission-outcome.ts +23 -5
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/gateway-adapter.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/run-execution-state.ts +845 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +106 -6
- package/dist/bundling-sources/shared_libs/play-runtime/run-observation.ts +440 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-snapshot-stream.ts +35 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +66 -7
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-crash-details.ts +95 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +13 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +0 -29
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-row-transition.ts +47 -2
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +475 -36
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-progress.ts +78 -11
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +550 -42
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +181 -8
- package/dist/bundling-sources/shared_libs/play-runtime/step-lifecycle-tracker.ts +0 -18
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +80 -7
- package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +37 -2
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +148 -18
- package/dist/bundling-sources/shared_libs/plays/cascade-falloff.ts +86 -0
- package/dist/bundling-sources/shared_libs/plays/docflow-unreached-reason.ts +611 -0
- package/dist/bundling-sources/shared_libs/plays/docflow.ts +21 -0
- package/dist/bundling-sources/shared_libs/plays/play-exports.ts +28 -5
- package/dist/bundling-sources/shared_libs/plays/settings-contract.ts +92 -10
- package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +5 -0
- package/dist/bundling-sources/shared_libs/plays/trigger-config-contract.ts +222 -0
- package/dist/bundling-sources/shared_libs/plays/trigger-config-route.ts +15 -0
- package/dist/cli/index.js +4957 -771
- package/dist/cli/index.mjs +4957 -771
- package/dist/client-B5XbKrrs.d.mts +6564 -0
- package/dist/client-C9Y49yya.d.ts +6564 -0
- package/dist/{compiler-manifest-C4mdRJOP.d.mts → compiler-manifest-CUuh8C3b.d.mts} +14 -1
- package/dist/{compiler-manifest-C4mdRJOP.d.ts → compiler-manifest-CUuh8C3b.d.ts} +14 -1
- package/dist/index.d.mts +7 -6275
- package/dist/index.d.ts +7 -6275
- package/dist/index.js +360 -326
- package/dist/index.mjs +360 -326
- package/dist/install-integrity.json +22 -2
- package/dist/plays/bundle-play-file.d.mts +2 -2
- package/dist/plays/bundle-play-file.d.ts +2 -2
- package/dist/plays/bundle-play-file.mjs +117 -18
- package/dist/plays/csv-data-input.d.mts +37 -0
- package/dist/plays/csv-data-input.d.ts +37 -0
- package/dist/plays/csv-data-input.js +3135 -0
- package/dist/plays/csv-data-input.mjs +3108 -0
- package/dist/plays/run-request.d.mts +6 -0
- package/dist/plays/run-request.d.ts +6 -0
- package/dist/plays/run-request.js +664 -0
- package/dist/plays/run-request.mjs +614 -0
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +1 -1
- package/dist/release.mjs +1 -1
- package/package.json +12 -1
package/dist/index.js
CHANGED
|
@@ -102,6 +102,11 @@ __export(src_exports, {
|
|
|
102
102
|
});
|
|
103
103
|
module.exports = __toCommonJS(src_exports);
|
|
104
104
|
|
|
105
|
+
// ../plays/trigger-config-route.ts
|
|
106
|
+
function playTriggerConfigPath(playName) {
|
|
107
|
+
return `/api/v2/plays/${encodeURIComponent(playName)}/triggers`;
|
|
108
|
+
}
|
|
109
|
+
|
|
105
110
|
// src/pagination.ts
|
|
106
111
|
async function* iterateCursorPages(fetchPage) {
|
|
107
112
|
let cursor = null;
|
|
@@ -1320,7 +1325,7 @@ var SDK_RELEASE = {
|
|
|
1320
1325
|
// getters keep their established compatibility behavior.
|
|
1321
1326
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
1322
1327
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
1323
|
-
version: "0.3.
|
|
1328
|
+
version: "0.3.260",
|
|
1324
1329
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
1325
1330
|
packageCapabilities: {
|
|
1326
1331
|
updatePreferences: 1
|
|
@@ -1456,6 +1461,30 @@ var SDK_VERSION = SDK_RELEASE.version;
|
|
|
1456
1461
|
var SDK_API_MAJOR = SDK_RELEASE.contracts.api.currentMajor;
|
|
1457
1462
|
var SDK_API_CONTRACT = SDK_RELEASE.contracts.api.legacyWireIds[0] ?? `api-v${SDK_API_MAJOR}`;
|
|
1458
1463
|
|
|
1464
|
+
// src/api-error.ts
|
|
1465
|
+
function asRecord(value) {
|
|
1466
|
+
return typeof value === "object" && value !== null ? value : null;
|
|
1467
|
+
}
|
|
1468
|
+
function apiErrorCodeFromResponse(parsed) {
|
|
1469
|
+
const response = asRecord(parsed);
|
|
1470
|
+
const error = asRecord(response?.error);
|
|
1471
|
+
const code = error?.code ?? response?.code;
|
|
1472
|
+
return typeof code === "string" ? code : "API_ERROR";
|
|
1473
|
+
}
|
|
1474
|
+
function apiErrorMessage(parsed, status) {
|
|
1475
|
+
const errorValue = typeof parsed === "object" && parsed && "error" in parsed ? parsed.error : void 0;
|
|
1476
|
+
if (typeof errorValue === "string") {
|
|
1477
|
+
return errorValue;
|
|
1478
|
+
}
|
|
1479
|
+
if (errorValue && typeof errorValue === "object" && "message" in errorValue && typeof errorValue.message === "string") {
|
|
1480
|
+
return errorValue.message;
|
|
1481
|
+
}
|
|
1482
|
+
if (typeof parsed === "object" && parsed && "message" in parsed && typeof parsed.message === "string") {
|
|
1483
|
+
return parsed.message;
|
|
1484
|
+
}
|
|
1485
|
+
return `HTTP ${status}`;
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1459
1488
|
// src/agent-runtime.ts
|
|
1460
1489
|
var import_node_os2 = require("os");
|
|
1461
1490
|
var EXPLICIT_AGENT_RUNTIMES = /* @__PURE__ */ new Set([
|
|
@@ -2475,24 +2504,18 @@ function parseResponseBody(body) {
|
|
|
2475
2504
|
}
|
|
2476
2505
|
}
|
|
2477
2506
|
function isProviderOriginatedHttpError(parsed) {
|
|
2478
|
-
const response =
|
|
2479
|
-
const error =
|
|
2507
|
+
const response = asRecord2(parsed);
|
|
2508
|
+
const error = asRecord2(response?.error);
|
|
2480
2509
|
const failureOrigin = error?.failure_origin ?? response?.failure_origin;
|
|
2481
2510
|
const code = error?.code ?? response?.code;
|
|
2482
2511
|
return failureOrigin === "provider" || code === "UPSTREAM_BLOCKED";
|
|
2483
2512
|
}
|
|
2484
2513
|
function isMonitorRateLimitEnvelope(parsed) {
|
|
2485
|
-
const response =
|
|
2486
|
-
const error =
|
|
2514
|
+
const response = asRecord2(parsed);
|
|
2515
|
+
const error = asRecord2(response?.error);
|
|
2487
2516
|
return error?.code === "monitor_upstream_rate_limited" && typeof error.message === "string";
|
|
2488
2517
|
}
|
|
2489
|
-
function
|
|
2490
|
-
const response = asRecord(parsed);
|
|
2491
|
-
const error = asRecord(response?.error);
|
|
2492
|
-
const code = error?.code ?? response?.code;
|
|
2493
|
-
return typeof code === "string" ? code : "API_ERROR";
|
|
2494
|
-
}
|
|
2495
|
-
function asRecord(value) {
|
|
2518
|
+
function asRecord2(value) {
|
|
2496
2519
|
return typeof value === "object" && value !== null ? value : null;
|
|
2497
2520
|
}
|
|
2498
2521
|
function isRetryableApiErrorResponse(status) {
|
|
@@ -2523,19 +2546,6 @@ function detectHtmlErrorBody(body, contentType) {
|
|
|
2523
2546
|
}
|
|
2524
2547
|
};
|
|
2525
2548
|
}
|
|
2526
|
-
function apiErrorMessage(parsed, status) {
|
|
2527
|
-
const errorValue = typeof parsed === "object" && parsed && "error" in parsed ? parsed.error : void 0;
|
|
2528
|
-
if (typeof errorValue === "string") {
|
|
2529
|
-
return errorValue;
|
|
2530
|
-
}
|
|
2531
|
-
if (errorValue && typeof errorValue === "object" && "message" in errorValue && typeof errorValue.message === "string") {
|
|
2532
|
-
return errorValue.message;
|
|
2533
|
-
}
|
|
2534
|
-
if (typeof parsed === "object" && parsed && "message" in parsed && typeof parsed.message === "string") {
|
|
2535
|
-
return parsed.message;
|
|
2536
|
-
}
|
|
2537
|
-
return `HTTP ${status}`;
|
|
2538
|
-
}
|
|
2539
2549
|
function parseRetryAfter(response) {
|
|
2540
2550
|
return parseOptionalRetryAfter(response) ?? 5e3;
|
|
2541
2551
|
}
|
|
@@ -3422,6 +3432,278 @@ function isStopAllPlayRunsDryRunResult(result) {
|
|
|
3422
3432
|
return "dryRun" in result && result.dryRun === true;
|
|
3423
3433
|
}
|
|
3424
3434
|
|
|
3435
|
+
// src/plays/run-request.ts
|
|
3436
|
+
var PLAY_RUN_START_PATH = "/api/v2/plays/run";
|
|
3437
|
+
var PLAY_RUN_START_STREAM_PATH = `${PLAY_RUN_START_PATH}?stream=true`;
|
|
3438
|
+
var PLAY_FILES_STAGE_PATH = "/api/v2/plays/files/stage";
|
|
3439
|
+
var PLAY_FILES_STAGE_MINT_PATH = `${PLAY_FILES_STAGE_PATH}/mint`;
|
|
3440
|
+
function buildPlayRunStartBody(request) {
|
|
3441
|
+
return {
|
|
3442
|
+
...request.name ? { name: request.name } : {},
|
|
3443
|
+
...request.revisionId ? { revisionId: request.revisionId } : {},
|
|
3444
|
+
...request.artifactStorageKey ? { artifactStorageKey: request.artifactStorageKey } : {},
|
|
3445
|
+
...request.sourceCode ? { sourceCode: request.sourceCode } : {},
|
|
3446
|
+
...request.sourceFiles ? { sourceFiles: request.sourceFiles } : {},
|
|
3447
|
+
...request.description ? { description: request.description } : {},
|
|
3448
|
+
..."staticPipeline" in request ? { staticPipeline: request.staticPipeline } : {},
|
|
3449
|
+
...request.artifactHash ? { artifactHash: request.artifactHash } : {},
|
|
3450
|
+
...request.graphHash ? { graphHash: request.graphHash } : {},
|
|
3451
|
+
...request.runtimeArtifact ? { runtimeArtifact: request.runtimeArtifact } : {},
|
|
3452
|
+
...request.compilerManifest ? { compilerManifest: request.compilerManifest } : {},
|
|
3453
|
+
...request.inputFileUpload ? { inputFileUpload: request.inputFileUpload } : {},
|
|
3454
|
+
...request.packagedFileUploads?.length ? { packagedFileUploads: request.packagedFileUploads } : {},
|
|
3455
|
+
...request.input ? { input: request.input } : {},
|
|
3456
|
+
...request.inputFile ? { inputFile: request.inputFile } : {},
|
|
3457
|
+
...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
|
|
3458
|
+
...request.force ? { force: true } : {},
|
|
3459
|
+
...request.forceToolRefresh === true ? { forceToolRefresh: true } : {},
|
|
3460
|
+
...typeof request.maxConcurrentExternalCalls === "number" ? { maxConcurrentExternalCalls: request.maxConcurrentExternalCalls } : {},
|
|
3461
|
+
...typeof request.maxConcurrentRows === "number" ? { maxConcurrentRows: request.maxConcurrentRows } : {},
|
|
3462
|
+
...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
|
|
3463
|
+
// Profile selection is the API's job, not the caller's. The server
|
|
3464
|
+
// defaults to absurd; callers normally omit this field.
|
|
3465
|
+
...request.profile ? { profile: request.profile } : {},
|
|
3466
|
+
...request.integrationMode ? { integrationMode: request.integrationMode } : {},
|
|
3467
|
+
...request.fixtureBehavior ? { fixtureBehavior: request.fixtureBehavior } : {},
|
|
3468
|
+
...request.runtime ? { runtime: request.runtime } : {},
|
|
3469
|
+
...request.testPolicyOverrides ? { testPolicyOverrides: request.testPolicyOverrides } : {}
|
|
3470
|
+
};
|
|
3471
|
+
}
|
|
3472
|
+
async function startPlayRun(http, request, headers) {
|
|
3473
|
+
const response = await http.post(
|
|
3474
|
+
PLAY_RUN_START_PATH,
|
|
3475
|
+
buildPlayRunStartBody(request),
|
|
3476
|
+
headers,
|
|
3477
|
+
{ maxRetries: 0, exactUrlOnly: true }
|
|
3478
|
+
);
|
|
3479
|
+
return normalizePlayRunStart(response);
|
|
3480
|
+
}
|
|
3481
|
+
function isPlayRunPackage(value) {
|
|
3482
|
+
return Boolean(
|
|
3483
|
+
value && typeof value === "object" && !Array.isArray(value) && value.kind === "play_run" && value.run && typeof value.run?.id === "string"
|
|
3484
|
+
);
|
|
3485
|
+
}
|
|
3486
|
+
function normalizePlayRunStart(raw) {
|
|
3487
|
+
const runPackage = isPlayRunPackage(raw) ? raw : isPlayRunPackage(raw.package) ? raw.package : null;
|
|
3488
|
+
if (!runPackage) {
|
|
3489
|
+
const workflowId = typeof raw.workflowId === "string" && raw.workflowId ? raw.workflowId : typeof raw.runId === "string" ? raw.runId : "";
|
|
3490
|
+
return {
|
|
3491
|
+
...raw,
|
|
3492
|
+
workflowId
|
|
3493
|
+
};
|
|
3494
|
+
}
|
|
3495
|
+
const status = typeof runPackage.run.status === "string" ? runPackage.run.status : "running";
|
|
3496
|
+
return {
|
|
3497
|
+
workflowId: runPackage.run.id,
|
|
3498
|
+
name: runPackage.run.playName,
|
|
3499
|
+
status,
|
|
3500
|
+
...runPackage.run.dashboardUrl ? { dashboardUrl: runPackage.run.dashboardUrl } : {},
|
|
3501
|
+
...isTerminalPlayRunLifecycleStatus(status) ? { finalStatus: runPackage } : {},
|
|
3502
|
+
package: runPackage
|
|
3503
|
+
};
|
|
3504
|
+
}
|
|
3505
|
+
var STAGE_LEGACY_MULTIPART_MAX_BYTES = 4e6;
|
|
3506
|
+
var STAGE_DIRECT_UPLOAD_MAX_ATTEMPTS = 3;
|
|
3507
|
+
function sleep2(ms) {
|
|
3508
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
3509
|
+
}
|
|
3510
|
+
function stagedUploadIdentity(logicalPath, contentHash) {
|
|
3511
|
+
return `${contentHash}:${logicalPath}`;
|
|
3512
|
+
}
|
|
3513
|
+
function isStagedUploadMintUnsupported(error) {
|
|
3514
|
+
return error instanceof DeeplineError && error.statusCode === 404;
|
|
3515
|
+
}
|
|
3516
|
+
function isStagedUploadDirectEgressDenied(error) {
|
|
3517
|
+
return error instanceof DeeplineError && error.code === "STAGED_FILE_UPLOAD_EGRESS_DENIED";
|
|
3518
|
+
}
|
|
3519
|
+
function formatMegabytes(bytes) {
|
|
3520
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
3521
|
+
}
|
|
3522
|
+
function decodeBase64Bytes(value) {
|
|
3523
|
+
const binary = atob(value);
|
|
3524
|
+
const bytes = new Uint8Array(binary.length);
|
|
3525
|
+
for (let index = 0; index < binary.length; index += 1) {
|
|
3526
|
+
bytes[index] = binary.charCodeAt(index);
|
|
3527
|
+
}
|
|
3528
|
+
return bytes;
|
|
3529
|
+
}
|
|
3530
|
+
async function uploadStagedFileToPresignedUrl(input) {
|
|
3531
|
+
const arrayBuffer = input.body.buffer.slice(
|
|
3532
|
+
input.body.byteOffset,
|
|
3533
|
+
input.body.byteOffset + input.body.byteLength
|
|
3534
|
+
);
|
|
3535
|
+
let lastError;
|
|
3536
|
+
for (let attempt = 1; attempt <= STAGE_DIRECT_UPLOAD_MAX_ATTEMPTS; attempt += 1) {
|
|
3537
|
+
try {
|
|
3538
|
+
const response = await fetch(input.url, {
|
|
3539
|
+
method: "PUT",
|
|
3540
|
+
headers: input.headers,
|
|
3541
|
+
body: new Blob([arrayBuffer])
|
|
3542
|
+
});
|
|
3543
|
+
if (response.ok) {
|
|
3544
|
+
return;
|
|
3545
|
+
}
|
|
3546
|
+
const text = await response.text().catch(() => "");
|
|
3547
|
+
const egressDenied = response.status === 403 && response.headers.get("x-deny-reason")?.trim().toLowerCase() === "host_not_allowed";
|
|
3548
|
+
lastError = new DeeplineError(
|
|
3549
|
+
`Direct storage upload of ${input.logicalPath} failed: ${response.status} ${text.slice(0, 200)}`,
|
|
3550
|
+
response.status,
|
|
3551
|
+
egressDenied ? "STAGED_FILE_UPLOAD_EGRESS_DENIED" : "STAGED_FILE_UPLOAD_FAILED",
|
|
3552
|
+
{ logicalPath: input.logicalPath }
|
|
3553
|
+
);
|
|
3554
|
+
if (response.status < 500 && response.status !== 429) {
|
|
3555
|
+
break;
|
|
3556
|
+
}
|
|
3557
|
+
} catch (error) {
|
|
3558
|
+
lastError = error instanceof TypeError ? new DeeplineError(
|
|
3559
|
+
`Direct storage upload of ${input.logicalPath} could not reach the storage endpoint: ${error.message}`,
|
|
3560
|
+
void 0,
|
|
3561
|
+
"STAGED_FILE_UPLOAD_EGRESS_DENIED",
|
|
3562
|
+
{ logicalPath: input.logicalPath }
|
|
3563
|
+
) : error;
|
|
3564
|
+
}
|
|
3565
|
+
if (attempt < STAGE_DIRECT_UPLOAD_MAX_ATTEMPTS) {
|
|
3566
|
+
await sleep2(250 * attempt);
|
|
3567
|
+
}
|
|
3568
|
+
}
|
|
3569
|
+
throw lastError instanceof Error ? lastError : new DeeplineError(
|
|
3570
|
+
`Direct storage upload of ${input.logicalPath} failed.`,
|
|
3571
|
+
void 0,
|
|
3572
|
+
"STAGED_FILE_UPLOAD_FAILED",
|
|
3573
|
+
{ logicalPath: input.logicalPath }
|
|
3574
|
+
);
|
|
3575
|
+
}
|
|
3576
|
+
async function mintStagedPlayFileUploads(http, files) {
|
|
3577
|
+
const response = await http.post(PLAY_FILES_STAGE_MINT_PATH, { files });
|
|
3578
|
+
return response.uploads ?? [];
|
|
3579
|
+
}
|
|
3580
|
+
async function stagePlayFilesViaMultipart(http, files, reason = "mint-unsupported") {
|
|
3581
|
+
for (const file of files) {
|
|
3582
|
+
if (file.bytes > STAGE_LEGACY_MULTIPART_MAX_BYTES) {
|
|
3583
|
+
const reasonMessage = reason === "direct-egress-denied" ? "direct storage is blocked by this environment's network egress policy" : "the connected Deepline server does not support direct-to-storage uploads";
|
|
3584
|
+
throw new DeeplineError(
|
|
3585
|
+
`Cannot stage ${file.logicalPath} (${formatMegabytes(file.bytes)}): ${reasonMessage}, and this file exceeds the ~4.5MB request-body limit the legacy upload path is subject to.`,
|
|
3586
|
+
413,
|
|
3587
|
+
"STAGED_FILE_TOO_LARGE_FOR_LEGACY_UPLOAD",
|
|
3588
|
+
{
|
|
3589
|
+
logicalPath: file.logicalPath,
|
|
3590
|
+
bytes: file.bytes,
|
|
3591
|
+
maxBytes: STAGE_LEGACY_MULTIPART_MAX_BYTES
|
|
3592
|
+
}
|
|
3593
|
+
);
|
|
3594
|
+
}
|
|
3595
|
+
}
|
|
3596
|
+
const buildFormData = () => {
|
|
3597
|
+
const formData = new FormData();
|
|
3598
|
+
formData.set(
|
|
3599
|
+
"metadata",
|
|
3600
|
+
JSON.stringify({
|
|
3601
|
+
files: files.map((file, index) => ({
|
|
3602
|
+
index,
|
|
3603
|
+
logicalPath: file.logicalPath,
|
|
3604
|
+
contentHash: file.contentHash,
|
|
3605
|
+
contentType: file.contentType,
|
|
3606
|
+
bytes: file.bytes
|
|
3607
|
+
}))
|
|
3608
|
+
})
|
|
3609
|
+
);
|
|
3610
|
+
for (const [index, file] of files.entries()) {
|
|
3611
|
+
const bytes = decodeBase64Bytes(file.contentBase64);
|
|
3612
|
+
const body = bytes.buffer.slice(
|
|
3613
|
+
bytes.byteOffset,
|
|
3614
|
+
bytes.byteOffset + bytes.byteLength
|
|
3615
|
+
);
|
|
3616
|
+
formData.set(
|
|
3617
|
+
`file:${index}`,
|
|
3618
|
+
new Blob([body], { type: file.contentType }),
|
|
3619
|
+
file.logicalPath
|
|
3620
|
+
);
|
|
3621
|
+
}
|
|
3622
|
+
return formData;
|
|
3623
|
+
};
|
|
3624
|
+
const response = await http.postFormData(PLAY_FILES_STAGE_PATH, buildFormData);
|
|
3625
|
+
return response.files;
|
|
3626
|
+
}
|
|
3627
|
+
async function stagePlayFiles(http, files) {
|
|
3628
|
+
let uploads;
|
|
3629
|
+
try {
|
|
3630
|
+
uploads = await mintStagedPlayFileUploads(
|
|
3631
|
+
http,
|
|
3632
|
+
files.map((file) => ({
|
|
3633
|
+
logicalPath: file.logicalPath,
|
|
3634
|
+
contentHash: file.contentHash,
|
|
3635
|
+
contentType: file.contentType,
|
|
3636
|
+
bytes: file.bytes
|
|
3637
|
+
}))
|
|
3638
|
+
);
|
|
3639
|
+
} catch (error) {
|
|
3640
|
+
if (isStagedUploadMintUnsupported(error)) {
|
|
3641
|
+
return stagePlayFilesViaMultipart(http, files);
|
|
3642
|
+
}
|
|
3643
|
+
throw error;
|
|
3644
|
+
}
|
|
3645
|
+
const uploadByIdentity = /* @__PURE__ */ new Map();
|
|
3646
|
+
for (const upload of uploads) {
|
|
3647
|
+
uploadByIdentity.set(
|
|
3648
|
+
stagedUploadIdentity(upload.logicalPath, upload.contentHash),
|
|
3649
|
+
upload
|
|
3650
|
+
);
|
|
3651
|
+
}
|
|
3652
|
+
const directResults = await Promise.all(
|
|
3653
|
+
files.map(async (file) => {
|
|
3654
|
+
const upload = uploadByIdentity.get(
|
|
3655
|
+
stagedUploadIdentity(file.logicalPath, file.contentHash)
|
|
3656
|
+
);
|
|
3657
|
+
if (!upload) {
|
|
3658
|
+
throw new DeeplineError(
|
|
3659
|
+
`The staging server did not return an upload target for ${file.logicalPath}.`,
|
|
3660
|
+
void 0,
|
|
3661
|
+
"STAGED_FILE_MINT_INCOMPLETE"
|
|
3662
|
+
);
|
|
3663
|
+
}
|
|
3664
|
+
if (upload.alreadyStaged || !upload.uploadUrl) {
|
|
3665
|
+
return { ref: upload.ref };
|
|
3666
|
+
}
|
|
3667
|
+
try {
|
|
3668
|
+
await uploadStagedFileToPresignedUrl({
|
|
3669
|
+
url: upload.uploadUrl,
|
|
3670
|
+
headers: upload.uploadHeaders ?? {
|
|
3671
|
+
"content-type": file.contentType
|
|
3672
|
+
},
|
|
3673
|
+
body: decodeBase64Bytes(file.contentBase64),
|
|
3674
|
+
logicalPath: file.logicalPath
|
|
3675
|
+
});
|
|
3676
|
+
return { ref: upload.ref };
|
|
3677
|
+
} catch (error) {
|
|
3678
|
+
if (isStagedUploadDirectEgressDenied(error)) {
|
|
3679
|
+
return { fallbackFile: file };
|
|
3680
|
+
}
|
|
3681
|
+
throw error;
|
|
3682
|
+
}
|
|
3683
|
+
})
|
|
3684
|
+
);
|
|
3685
|
+
return await Promise.all(
|
|
3686
|
+
directResults.map(async (result) => {
|
|
3687
|
+
if ("fallbackFile" in result) {
|
|
3688
|
+
const [ref] = await stagePlayFilesViaMultipart(
|
|
3689
|
+
http,
|
|
3690
|
+
[result.fallbackFile],
|
|
3691
|
+
"direct-egress-denied"
|
|
3692
|
+
);
|
|
3693
|
+
if (!ref) {
|
|
3694
|
+
throw new DeeplineError(
|
|
3695
|
+
`The staging server did not return an upload target for ${result.fallbackFile.logicalPath}.`,
|
|
3696
|
+
void 0,
|
|
3697
|
+
"STAGED_FILE_MINT_INCOMPLETE"
|
|
3698
|
+
);
|
|
3699
|
+
}
|
|
3700
|
+
return ref;
|
|
3701
|
+
}
|
|
3702
|
+
return result.ref;
|
|
3703
|
+
})
|
|
3704
|
+
);
|
|
3705
|
+
}
|
|
3706
|
+
|
|
3425
3707
|
// ../plays/artifact-types.ts
|
|
3426
3708
|
var PLAY_ARTIFACT_KINDS = {
|
|
3427
3709
|
cjsNode20: "cjs_node20"
|
|
@@ -3628,6 +3910,19 @@ function resolvePlayRunRuntimeSelection(request) {
|
|
|
3628
3910
|
...configuredPlacementPolicy ? { sandboxPlacementPolicy: configuredPlacementPolicy } : {}
|
|
3629
3911
|
};
|
|
3630
3912
|
}
|
|
3913
|
+
function resolveStartPlayRunRequest(request) {
|
|
3914
|
+
const integrationMode = resolvePlayRunIntegrationMode(request);
|
|
3915
|
+
const testPolicyOverrides = request.testPolicyOverrides ?? parseEnvTestPolicyOverrides();
|
|
3916
|
+
const runtime = resolvePlayRunRuntimeSelection(request);
|
|
3917
|
+
const resolved = { ...request };
|
|
3918
|
+
delete resolved.integrationMode;
|
|
3919
|
+
delete resolved.runtime;
|
|
3920
|
+
delete resolved.testPolicyOverrides;
|
|
3921
|
+
if (integrationMode) resolved.integrationMode = integrationMode;
|
|
3922
|
+
if (runtime) resolved.runtime = runtime;
|
|
3923
|
+
if (testPolicyOverrides) resolved.testPolicyOverrides = testPolicyOverrides;
|
|
3924
|
+
return { request: resolved, runtime };
|
|
3925
|
+
}
|
|
3631
3926
|
function runtimeSelectionHeaders(runtime) {
|
|
3632
3927
|
if (!runtime) return void 0;
|
|
3633
3928
|
const token = process.env.DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN?.trim();
|
|
@@ -3686,7 +3981,7 @@ function parseEnvTestPolicyOverrides() {
|
|
|
3686
3981
|
}
|
|
3687
3982
|
return normalizeTestPolicyOverrides(parsed, "DEEPLINE_TEST_POLICY_OVERRIDES");
|
|
3688
3983
|
}
|
|
3689
|
-
function
|
|
3984
|
+
function sleep3(ms) {
|
|
3690
3985
|
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
3691
3986
|
}
|
|
3692
3987
|
function isTransientCompileManifestError(error) {
|
|
@@ -3794,11 +4089,6 @@ function preferPrebuiltPlayDescriptions(plays) {
|
|
|
3794
4089
|
(left, right) => Number(right.play.pinned) - Number(left.play.pinned) || Number(isPrebuiltPlayDescription(right.play)) - Number(isPrebuiltPlayDescription(left.play)) || left.index - right.index
|
|
3795
4090
|
).map(({ play }) => play);
|
|
3796
4091
|
}
|
|
3797
|
-
function isPlayRunPackage(value) {
|
|
3798
|
-
return Boolean(
|
|
3799
|
-
value && typeof value === "object" && !Array.isArray(value) && value.kind === "play_run" && value.run && typeof value.run?.id === "string"
|
|
3800
|
-
);
|
|
3801
|
-
}
|
|
3802
4092
|
function normalizePlayStatus(raw) {
|
|
3803
4093
|
const runPackage = isPlayRunPackage(raw) ? raw : isPlayRunPackage(raw.package) ? raw.package : null;
|
|
3804
4094
|
const packageRun = runPackage?.run;
|
|
@@ -3826,93 +4116,6 @@ function normalizePlayStatus(raw) {
|
|
|
3826
4116
|
status
|
|
3827
4117
|
};
|
|
3828
4118
|
}
|
|
3829
|
-
function normalizePlayRunStart(raw) {
|
|
3830
|
-
const runPackage = isPlayRunPackage(raw) ? raw : isPlayRunPackage(raw.package) ? raw.package : null;
|
|
3831
|
-
if (!runPackage) {
|
|
3832
|
-
const workflowId = typeof raw.workflowId === "string" && raw.workflowId ? raw.workflowId : typeof raw.runId === "string" ? raw.runId : "";
|
|
3833
|
-
return {
|
|
3834
|
-
...raw,
|
|
3835
|
-
workflowId
|
|
3836
|
-
};
|
|
3837
|
-
}
|
|
3838
|
-
const status = typeof runPackage.run.status === "string" ? runPackage.run.status : "running";
|
|
3839
|
-
return {
|
|
3840
|
-
workflowId: runPackage.run.id,
|
|
3841
|
-
name: runPackage.run.playName,
|
|
3842
|
-
status,
|
|
3843
|
-
...runPackage.run.dashboardUrl ? { dashboardUrl: runPackage.run.dashboardUrl } : {},
|
|
3844
|
-
...isTerminalPlayRunLifecycleStatus(status) ? { finalStatus: runPackage } : {},
|
|
3845
|
-
package: runPackage
|
|
3846
|
-
};
|
|
3847
|
-
}
|
|
3848
|
-
function decodeBase64Bytes(value) {
|
|
3849
|
-
const binary = atob(value);
|
|
3850
|
-
const bytes = new Uint8Array(binary.length);
|
|
3851
|
-
for (let index = 0; index < binary.length; index += 1) {
|
|
3852
|
-
bytes[index] = binary.charCodeAt(index);
|
|
3853
|
-
}
|
|
3854
|
-
return bytes;
|
|
3855
|
-
}
|
|
3856
|
-
var STAGE_LEGACY_MULTIPART_MAX_BYTES = 4e6;
|
|
3857
|
-
var STAGE_DIRECT_UPLOAD_MAX_ATTEMPTS = 3;
|
|
3858
|
-
function stagedUploadIdentity(logicalPath, contentHash) {
|
|
3859
|
-
return `${contentHash}:${logicalPath}`;
|
|
3860
|
-
}
|
|
3861
|
-
function isStagedUploadMintUnsupported(error) {
|
|
3862
|
-
return error instanceof DeeplineError && error.statusCode === 404;
|
|
3863
|
-
}
|
|
3864
|
-
function isStagedUploadDirectEgressDenied(error) {
|
|
3865
|
-
return error instanceof DeeplineError && error.code === "STAGED_FILE_UPLOAD_EGRESS_DENIED";
|
|
3866
|
-
}
|
|
3867
|
-
function formatMegabytes(bytes) {
|
|
3868
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
3869
|
-
}
|
|
3870
|
-
async function uploadStagedFileToPresignedUrl(input) {
|
|
3871
|
-
const arrayBuffer = input.body.buffer.slice(
|
|
3872
|
-
input.body.byteOffset,
|
|
3873
|
-
input.body.byteOffset + input.body.byteLength
|
|
3874
|
-
);
|
|
3875
|
-
let lastError;
|
|
3876
|
-
for (let attempt = 1; attempt <= STAGE_DIRECT_UPLOAD_MAX_ATTEMPTS; attempt += 1) {
|
|
3877
|
-
try {
|
|
3878
|
-
const response = await fetch(input.url, {
|
|
3879
|
-
method: "PUT",
|
|
3880
|
-
headers: input.headers,
|
|
3881
|
-
body: new Blob([arrayBuffer])
|
|
3882
|
-
});
|
|
3883
|
-
if (response.ok) {
|
|
3884
|
-
return;
|
|
3885
|
-
}
|
|
3886
|
-
const text = await response.text().catch(() => "");
|
|
3887
|
-
const egressDenied = response.status === 403 && response.headers.get("x-deny-reason")?.trim().toLowerCase() === "host_not_allowed";
|
|
3888
|
-
lastError = new DeeplineError(
|
|
3889
|
-
`Direct storage upload of ${input.logicalPath} failed: ${response.status} ${text.slice(0, 200)}`,
|
|
3890
|
-
response.status,
|
|
3891
|
-
egressDenied ? "STAGED_FILE_UPLOAD_EGRESS_DENIED" : "STAGED_FILE_UPLOAD_FAILED",
|
|
3892
|
-
{ logicalPath: input.logicalPath }
|
|
3893
|
-
);
|
|
3894
|
-
if (response.status < 500 && response.status !== 429) {
|
|
3895
|
-
break;
|
|
3896
|
-
}
|
|
3897
|
-
} catch (error) {
|
|
3898
|
-
lastError = error instanceof TypeError ? new DeeplineError(
|
|
3899
|
-
`Direct storage upload of ${input.logicalPath} could not reach the storage endpoint: ${error.message}`,
|
|
3900
|
-
void 0,
|
|
3901
|
-
"STAGED_FILE_UPLOAD_EGRESS_DENIED",
|
|
3902
|
-
{ logicalPath: input.logicalPath }
|
|
3903
|
-
) : error;
|
|
3904
|
-
}
|
|
3905
|
-
if (attempt < STAGE_DIRECT_UPLOAD_MAX_ATTEMPTS) {
|
|
3906
|
-
await sleep2(250 * attempt);
|
|
3907
|
-
}
|
|
3908
|
-
}
|
|
3909
|
-
throw lastError instanceof Error ? lastError : new DeeplineError(
|
|
3910
|
-
`Direct storage upload of ${input.logicalPath} failed.`,
|
|
3911
|
-
void 0,
|
|
3912
|
-
"STAGED_FILE_UPLOAD_FAILED",
|
|
3913
|
-
{ logicalPath: input.logicalPath }
|
|
3914
|
-
);
|
|
3915
|
-
}
|
|
3916
4119
|
function readStringArray(value) {
|
|
3917
4120
|
return Array.isArray(value) ? value.filter((line) => typeof line === "string") : [];
|
|
3918
4121
|
}
|
|
@@ -4532,51 +4735,12 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
4532
4735
|
* ```
|
|
4533
4736
|
*/
|
|
4534
4737
|
async startPlayRun(request) {
|
|
4535
|
-
const
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
"/api/v2/plays/run",
|
|
4541
|
-
{
|
|
4542
|
-
...request.name ? { name: request.name } : {},
|
|
4543
|
-
...request.revisionId ? { revisionId: request.revisionId } : {},
|
|
4544
|
-
...request.artifactStorageKey ? { artifactStorageKey: request.artifactStorageKey } : {},
|
|
4545
|
-
...request.sourceCode ? { sourceCode: request.sourceCode } : {},
|
|
4546
|
-
...request.sourceFiles ? { sourceFiles: request.sourceFiles } : {},
|
|
4547
|
-
...request.description ? { description: request.description } : {},
|
|
4548
|
-
..."staticPipeline" in request ? { staticPipeline: request.staticPipeline } : {},
|
|
4549
|
-
...request.artifactHash ? { artifactHash: request.artifactHash } : {},
|
|
4550
|
-
...request.graphHash ? { graphHash: request.graphHash } : {},
|
|
4551
|
-
...request.runtimeArtifact ? { runtimeArtifact: request.runtimeArtifact } : {},
|
|
4552
|
-
...request.compilerManifest ? { compilerManifest: request.compilerManifest } : {},
|
|
4553
|
-
...request.inputFileUpload ? { inputFileUpload: request.inputFileUpload } : {},
|
|
4554
|
-
...request.packagedFileUploads?.length ? { packagedFileUploads: request.packagedFileUploads } : {},
|
|
4555
|
-
...request.input ? { input: request.input } : {},
|
|
4556
|
-
...request.inputFile ? { inputFile: request.inputFile } : {},
|
|
4557
|
-
...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
|
|
4558
|
-
...request.force ? { force: true } : {},
|
|
4559
|
-
...forceToolRefresh ? { forceToolRefresh: true } : {},
|
|
4560
|
-
...typeof request.maxConcurrentExternalCalls === "number" ? {
|
|
4561
|
-
maxConcurrentExternalCalls: request.maxConcurrentExternalCalls
|
|
4562
|
-
} : {},
|
|
4563
|
-
...typeof request.maxConcurrentRows === "number" ? { maxConcurrentRows: request.maxConcurrentRows } : {},
|
|
4564
|
-
...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
|
|
4565
|
-
// Profile selection is the API's job, not the CLI's. The server
|
|
4566
|
-
// defaults to absurd; callers normally omit this field.
|
|
4567
|
-
...request.profile ? { profile: request.profile } : {},
|
|
4568
|
-
...integrationMode ? { integrationMode } : {},
|
|
4569
|
-
...request.fixtureBehavior ? { fixtureBehavior: request.fixtureBehavior } : {},
|
|
4570
|
-
...runtime ? { runtime } : {},
|
|
4571
|
-
...testPolicyOverrides ? { testPolicyOverrides } : {}
|
|
4572
|
-
},
|
|
4573
|
-
runtimeSelectionHeaders(runtime),
|
|
4574
|
-
// A start can reach the server even when its response is lost or times
|
|
4575
|
-
// out. Retrying this mutation without an idempotency key can create a
|
|
4576
|
-
// second root run, so callers must resolve ambiguous failures explicitly.
|
|
4577
|
-
{ maxRetries: 0, exactUrlOnly: true }
|
|
4738
|
+
const resolved = resolveStartPlayRunRequest(request);
|
|
4739
|
+
return startPlayRun(
|
|
4740
|
+
this.http,
|
|
4741
|
+
resolved.request,
|
|
4742
|
+
runtimeSelectionHeaders(resolved.runtime)
|
|
4578
4743
|
);
|
|
4579
|
-
return normalizePlayRunStart(response);
|
|
4580
4744
|
}
|
|
4581
4745
|
/**
|
|
4582
4746
|
* Submit a play run through the legacy event response.
|
|
@@ -4592,44 +4756,14 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
4592
4756
|
* @returns Async generator of play-scoped live events.
|
|
4593
4757
|
*/
|
|
4594
4758
|
async *startPlayRunStream(request, options) {
|
|
4595
|
-
const
|
|
4596
|
-
const
|
|
4597
|
-
const forceToolRefresh = request.forceToolRefresh === true;
|
|
4598
|
-
const runtime = resolvePlayRunRuntimeSelection(request);
|
|
4599
|
-
const body = {
|
|
4600
|
-
...request.name ? { name: request.name } : {},
|
|
4601
|
-
...request.revisionId ? { revisionId: request.revisionId } : {},
|
|
4602
|
-
...request.artifactStorageKey ? { artifactStorageKey: request.artifactStorageKey } : {},
|
|
4603
|
-
...request.sourceCode ? { sourceCode: request.sourceCode } : {},
|
|
4604
|
-
...request.sourceFiles ? { sourceFiles: request.sourceFiles } : {},
|
|
4605
|
-
...request.description ? { description: request.description } : {},
|
|
4606
|
-
..."staticPipeline" in request ? { staticPipeline: request.staticPipeline } : {},
|
|
4607
|
-
...request.artifactHash ? { artifactHash: request.artifactHash } : {},
|
|
4608
|
-
...request.graphHash ? { graphHash: request.graphHash } : {},
|
|
4609
|
-
...request.runtimeArtifact ? { runtimeArtifact: request.runtimeArtifact } : {},
|
|
4610
|
-
...request.compilerManifest ? { compilerManifest: request.compilerManifest } : {},
|
|
4611
|
-
...request.inputFileUpload ? { inputFileUpload: request.inputFileUpload } : {},
|
|
4612
|
-
...request.packagedFileUploads?.length ? { packagedFileUploads: request.packagedFileUploads } : {},
|
|
4613
|
-
...request.input ? { input: request.input } : {},
|
|
4614
|
-
...request.inputFile ? { inputFile: request.inputFile } : {},
|
|
4615
|
-
...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
|
|
4616
|
-
...request.force ? { force: true } : {},
|
|
4617
|
-
...forceToolRefresh ? { forceToolRefresh: true } : {},
|
|
4618
|
-
...typeof request.maxConcurrentExternalCalls === "number" ? { maxConcurrentExternalCalls: request.maxConcurrentExternalCalls } : {},
|
|
4619
|
-
...typeof request.maxConcurrentRows === "number" ? { maxConcurrentRows: request.maxConcurrentRows } : {},
|
|
4620
|
-
...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
|
|
4621
|
-
...request.profile ? { profile: request.profile } : {},
|
|
4622
|
-
...integrationMode ? { integrationMode } : {},
|
|
4623
|
-
...request.fixtureBehavior ? { fixtureBehavior: request.fixtureBehavior } : {},
|
|
4624
|
-
...runtime ? { runtime } : {},
|
|
4625
|
-
...testPolicyOverrides ? { testPolicyOverrides } : {}
|
|
4626
|
-
};
|
|
4759
|
+
const resolved = resolveStartPlayRunRequest(request);
|
|
4760
|
+
const body = buildPlayRunStartBody(resolved.request);
|
|
4627
4761
|
for await (const event of this.http.streamSse(
|
|
4628
|
-
|
|
4762
|
+
PLAY_RUN_START_STREAM_PATH,
|
|
4629
4763
|
{
|
|
4630
4764
|
method: "POST",
|
|
4631
4765
|
body,
|
|
4632
|
-
headers: runtimeSelectionHeaders(runtime),
|
|
4766
|
+
headers: runtimeSelectionHeaders(resolved.runtime),
|
|
4633
4767
|
signal: options?.signal
|
|
4634
4768
|
}
|
|
4635
4769
|
)) {
|
|
@@ -4728,7 +4862,7 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
4728
4862
|
if (delayMs === void 0 || !isTransientCompileManifestError(error)) {
|
|
4729
4863
|
throw error;
|
|
4730
4864
|
}
|
|
4731
|
-
await
|
|
4865
|
+
await sleep3(delayMs);
|
|
4732
4866
|
}
|
|
4733
4867
|
}
|
|
4734
4868
|
}
|
|
@@ -4895,81 +5029,7 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
4895
5029
|
* ```
|
|
4896
5030
|
*/
|
|
4897
5031
|
async stagePlayFiles(files) {
|
|
4898
|
-
|
|
4899
|
-
try {
|
|
4900
|
-
uploads = await this.mintStagedPlayFileUploads(
|
|
4901
|
-
files.map((file) => ({
|
|
4902
|
-
logicalPath: file.logicalPath,
|
|
4903
|
-
contentHash: file.contentHash,
|
|
4904
|
-
contentType: file.contentType,
|
|
4905
|
-
bytes: file.bytes
|
|
4906
|
-
}))
|
|
4907
|
-
);
|
|
4908
|
-
} catch (error) {
|
|
4909
|
-
if (isStagedUploadMintUnsupported(error)) {
|
|
4910
|
-
return this.stagePlayFilesViaMultipart(files);
|
|
4911
|
-
}
|
|
4912
|
-
throw error;
|
|
4913
|
-
}
|
|
4914
|
-
const uploadByIdentity = /* @__PURE__ */ new Map();
|
|
4915
|
-
for (const upload of uploads) {
|
|
4916
|
-
uploadByIdentity.set(
|
|
4917
|
-
stagedUploadIdentity(upload.logicalPath, upload.contentHash),
|
|
4918
|
-
upload
|
|
4919
|
-
);
|
|
4920
|
-
}
|
|
4921
|
-
const directResults = await Promise.all(
|
|
4922
|
-
files.map(async (file) => {
|
|
4923
|
-
const upload = uploadByIdentity.get(
|
|
4924
|
-
stagedUploadIdentity(file.logicalPath, file.contentHash)
|
|
4925
|
-
);
|
|
4926
|
-
if (!upload) {
|
|
4927
|
-
throw new DeeplineError(
|
|
4928
|
-
`The staging server did not return an upload target for ${file.logicalPath}.`,
|
|
4929
|
-
void 0,
|
|
4930
|
-
"STAGED_FILE_MINT_INCOMPLETE"
|
|
4931
|
-
);
|
|
4932
|
-
}
|
|
4933
|
-
if (upload.alreadyStaged || !upload.uploadUrl) {
|
|
4934
|
-
return { ref: upload.ref };
|
|
4935
|
-
}
|
|
4936
|
-
try {
|
|
4937
|
-
await uploadStagedFileToPresignedUrl({
|
|
4938
|
-
url: upload.uploadUrl,
|
|
4939
|
-
headers: upload.uploadHeaders ?? {
|
|
4940
|
-
"content-type": file.contentType
|
|
4941
|
-
},
|
|
4942
|
-
body: decodeBase64Bytes(file.contentBase64),
|
|
4943
|
-
logicalPath: file.logicalPath
|
|
4944
|
-
});
|
|
4945
|
-
return { ref: upload.ref };
|
|
4946
|
-
} catch (error) {
|
|
4947
|
-
if (isStagedUploadDirectEgressDenied(error)) {
|
|
4948
|
-
return { fallbackFile: file };
|
|
4949
|
-
}
|
|
4950
|
-
throw error;
|
|
4951
|
-
}
|
|
4952
|
-
})
|
|
4953
|
-
);
|
|
4954
|
-
return await Promise.all(
|
|
4955
|
-
directResults.map(async (result) => {
|
|
4956
|
-
if ("fallbackFile" in result) {
|
|
4957
|
-
const [ref] = await this.stagePlayFilesViaMultipart(
|
|
4958
|
-
[result.fallbackFile],
|
|
4959
|
-
"direct-egress-denied"
|
|
4960
|
-
);
|
|
4961
|
-
if (!ref) {
|
|
4962
|
-
throw new DeeplineError(
|
|
4963
|
-
`The staging server did not return an upload target for ${result.fallbackFile.logicalPath}.`,
|
|
4964
|
-
void 0,
|
|
4965
|
-
"STAGED_FILE_MINT_INCOMPLETE"
|
|
4966
|
-
);
|
|
4967
|
-
}
|
|
4968
|
-
return ref;
|
|
4969
|
-
}
|
|
4970
|
-
return result.ref;
|
|
4971
|
-
})
|
|
4972
|
-
);
|
|
5032
|
+
return stagePlayFiles(this.http, files);
|
|
4973
5033
|
}
|
|
4974
5034
|
/**
|
|
4975
5035
|
* Mint short-lived presigned upload targets for staged play files.
|
|
@@ -4979,55 +5039,7 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
4979
5039
|
* already holds, or a presigned PUT URL the caller uploads the body to.
|
|
4980
5040
|
*/
|
|
4981
5041
|
async mintStagedPlayFileUploads(files) {
|
|
4982
|
-
|
|
4983
|
-
return response.uploads ?? [];
|
|
4984
|
-
}
|
|
4985
|
-
async stagePlayFilesViaMultipart(files, reason = "mint-unsupported") {
|
|
4986
|
-
for (const file of files) {
|
|
4987
|
-
if (file.bytes > STAGE_LEGACY_MULTIPART_MAX_BYTES) {
|
|
4988
|
-
const reasonMessage = reason === "direct-egress-denied" ? "direct storage is blocked by this environment's network egress policy" : "the connected Deepline server does not support direct-to-storage uploads";
|
|
4989
|
-
throw new DeeplineError(
|
|
4990
|
-
`Cannot stage ${file.logicalPath} (${formatMegabytes(file.bytes)}): ${reasonMessage}, and this file exceeds the ~4.5MB request-body limit the legacy upload path is subject to.`,
|
|
4991
|
-
413,
|
|
4992
|
-
"STAGED_FILE_TOO_LARGE_FOR_LEGACY_UPLOAD",
|
|
4993
|
-
{
|
|
4994
|
-
logicalPath: file.logicalPath,
|
|
4995
|
-
bytes: file.bytes,
|
|
4996
|
-
maxBytes: STAGE_LEGACY_MULTIPART_MAX_BYTES
|
|
4997
|
-
}
|
|
4998
|
-
);
|
|
4999
|
-
}
|
|
5000
|
-
}
|
|
5001
|
-
const buildFormData = () => {
|
|
5002
|
-
const formData = new FormData();
|
|
5003
|
-
formData.set(
|
|
5004
|
-
"metadata",
|
|
5005
|
-
JSON.stringify({
|
|
5006
|
-
files: files.map((file, index) => ({
|
|
5007
|
-
index,
|
|
5008
|
-
logicalPath: file.logicalPath,
|
|
5009
|
-
contentHash: file.contentHash,
|
|
5010
|
-
contentType: file.contentType,
|
|
5011
|
-
bytes: file.bytes
|
|
5012
|
-
}))
|
|
5013
|
-
})
|
|
5014
|
-
);
|
|
5015
|
-
for (const [index, file] of files.entries()) {
|
|
5016
|
-
const bytes = decodeBase64Bytes(file.contentBase64);
|
|
5017
|
-
const body = bytes.buffer.slice(
|
|
5018
|
-
bytes.byteOffset,
|
|
5019
|
-
bytes.byteOffset + bytes.byteLength
|
|
5020
|
-
);
|
|
5021
|
-
formData.set(
|
|
5022
|
-
`file:${index}`,
|
|
5023
|
-
new Blob([body], { type: file.contentType }),
|
|
5024
|
-
file.logicalPath
|
|
5025
|
-
);
|
|
5026
|
-
}
|
|
5027
|
-
return formData;
|
|
5028
|
-
};
|
|
5029
|
-
const response = await this.http.postFormData("/api/v2/plays/files/stage", buildFormData);
|
|
5030
|
-
return response.files;
|
|
5042
|
+
return mintStagedPlayFileUploads(this.http, files);
|
|
5031
5043
|
}
|
|
5032
5044
|
/**
|
|
5033
5045
|
* Resolve staged play files by content hash without uploading bytes.
|
|
@@ -5463,7 +5475,7 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
5463
5475
|
}
|
|
5464
5476
|
return this.http.post(
|
|
5465
5477
|
`/api/v2/runs/${encodeURIComponent(runId)}/rerun`,
|
|
5466
|
-
{},
|
|
5478
|
+
options?.inputOverrides ? { inputOverrides: options.inputOverrides } : {},
|
|
5467
5479
|
{ "Idempotency-Key": idempotencyKey || globalThis.crypto.randomUUID() }
|
|
5468
5480
|
);
|
|
5469
5481
|
}
|
|
@@ -5598,8 +5610,8 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
5598
5610
|
if (input.runId?.trim()) {
|
|
5599
5611
|
params.set("runId", input.runId.trim());
|
|
5600
5612
|
}
|
|
5601
|
-
if (input.rowMode === "all") {
|
|
5602
|
-
params.set("rowMode",
|
|
5613
|
+
if (input.rowMode === "all" || input.rowMode === "live") {
|
|
5614
|
+
params.set("rowMode", input.rowMode);
|
|
5603
5615
|
}
|
|
5604
5616
|
const result = await this.http.get(
|
|
5605
5617
|
`/api/v2/plays/${encodeURIComponent(input.playName)}/sheet?${params.toString()}`,
|
|
@@ -5763,6 +5775,18 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
5763
5775
|
patch
|
|
5764
5776
|
);
|
|
5765
5777
|
}
|
|
5778
|
+
/** Read a Play's cron and webhook triggers and their scheduler state. */
|
|
5779
|
+
async getPlayTriggerConfig(playName) {
|
|
5780
|
+
return this.http.get(playTriggerConfigPath(playName));
|
|
5781
|
+
}
|
|
5782
|
+
/**
|
|
5783
|
+
* Declare a Play's cron and/or webhook trigger (null removes it) and publish
|
|
5784
|
+
* the rewritten source as a new live revision. Retry-safe: a request the
|
|
5785
|
+
* live revision already satisfies returns `changed: false`.
|
|
5786
|
+
*/
|
|
5787
|
+
async updatePlayTriggerConfig(playName, update) {
|
|
5788
|
+
return this.http.put(playTriggerConfigPath(playName), update);
|
|
5789
|
+
}
|
|
5766
5790
|
/** List one bounded page of existing Play locations; continue with cursor. */
|
|
5767
5791
|
async listPlaySettingsPaths(options = {}) {
|
|
5768
5792
|
const query = new URLSearchParams();
|
|
@@ -6425,6 +6449,16 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
6425
6449
|
}
|
|
6426
6450
|
return event;
|
|
6427
6451
|
}
|
|
6452
|
+
/**
|
|
6453
|
+
* What Deepline has billed each run so far (customer-visible credits, never
|
|
6454
|
+
* provider spend) and whether any of its charges is still settling — the
|
|
6455
|
+
* same read the dashboard's runs grid shows. `GET /api/v2/runs/billing`.
|
|
6456
|
+
*/
|
|
6457
|
+
async getRunBilling(runIds) {
|
|
6458
|
+
const params = new URLSearchParams();
|
|
6459
|
+
for (const runId of runIds) params.append("runId", runId);
|
|
6460
|
+
return this.http.get(`/api/v2/runs/billing?${params}`);
|
|
6461
|
+
}
|
|
6428
6462
|
/**
|
|
6429
6463
|
* Read workspace usage and recent customer-facing Deepline charges. Pass
|
|
6430
6464
|
* the `job_id` from `executeTool` as `requestId` to retrieve one exact call,
|
|
@@ -7140,7 +7174,7 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
7140
7174
|
const state = typeof job?.state === "string" ? job.state : void 0;
|
|
7141
7175
|
if (state && terminal.has(state)) return latest;
|
|
7142
7176
|
if (Date.now() - startedAt >= timeoutMs) return latest;
|
|
7143
|
-
await
|
|
7177
|
+
await sleep3(pollIntervalMs);
|
|
7144
7178
|
latest = await this.getMonitorJob(jobId);
|
|
7145
7179
|
}
|
|
7146
7180
|
}
|
|
@@ -7253,7 +7287,7 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
7253
7287
|
const status = typeof latest.status === "string" ? latest.status : void 0;
|
|
7254
7288
|
if (status && terminal.has(status)) return latest;
|
|
7255
7289
|
if (Date.now() - startedAt >= timeoutMs) return latest;
|
|
7256
|
-
await
|
|
7290
|
+
await sleep3(pollIntervalMs);
|
|
7257
7291
|
latest = await this.getMonitorFleet(fleetId);
|
|
7258
7292
|
}
|
|
7259
7293
|
}
|