deepline 0.3.258 → 0.3.259
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/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 +21 -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
|
@@ -3,6 +3,14 @@ import type {
|
|
|
3
3
|
PlaySettingsPatch,
|
|
4
4
|
PlaySettingsPathsPage,
|
|
5
5
|
} from '../../shared_libs/plays/settings-contract';
|
|
6
|
+
import type {
|
|
7
|
+
PlayTriggerConfigUpdate,
|
|
8
|
+
PlayTriggerConfigUpdateResult,
|
|
9
|
+
PlayTriggerConfigView,
|
|
10
|
+
} from '../../shared_libs/plays/trigger-config-contract';
|
|
11
|
+
// Value import from the dependency-free module: the client is bundled into
|
|
12
|
+
// authored Plays, where `zod` (the contract's schemas) cannot resolve.
|
|
13
|
+
import { playTriggerConfigPath } from '../../shared_libs/plays/trigger-config-route';
|
|
6
14
|
import { iterateCursorPages } from './pagination.js';
|
|
7
15
|
import { playInputExampleArgs } from './plays/input-example.js';
|
|
8
16
|
/**
|
|
@@ -77,7 +85,6 @@ import type {
|
|
|
77
85
|
PlayRunResult,
|
|
78
86
|
PlayRunStart,
|
|
79
87
|
PlayStatus,
|
|
80
|
-
PlayRunPackage,
|
|
81
88
|
PlayLiveEvent,
|
|
82
89
|
PlayListItem,
|
|
83
90
|
ProductNotificationSettings,
|
|
@@ -112,6 +119,17 @@ import { isStopAllPlayRunsDryRunResult } from './types.js';
|
|
|
112
119
|
import type { MonitorDefinition } from './monitors.js';
|
|
113
120
|
import type { MonitorFleetDefinition } from './monitor-fleets.js';
|
|
114
121
|
import type { PlayStagedFileRef } from './plays/local-file-discovery.js';
|
|
122
|
+
import {
|
|
123
|
+
buildPlayRunStartBody,
|
|
124
|
+
isPlayRunPackage,
|
|
125
|
+
mintStagedPlayFileUploads,
|
|
126
|
+
normalizePlayRunStart,
|
|
127
|
+
PLAY_RUN_START_STREAM_PATH,
|
|
128
|
+
stagePlayFiles,
|
|
129
|
+
startPlayRun,
|
|
130
|
+
type MintStagedFileUpload,
|
|
131
|
+
type ResolvedStartPlayRunRequest,
|
|
132
|
+
} from './plays/run-request';
|
|
115
133
|
import type { PlayCompilerManifest } from '../../shared_libs/plays/compiler-manifest.js';
|
|
116
134
|
import type { EnrichCompiledConfig } from './cli/enrich-play-compiler.js';
|
|
117
135
|
import {
|
|
@@ -394,6 +412,30 @@ function resolvePlayRunRuntimeSelection(
|
|
|
394
412
|
};
|
|
395
413
|
}
|
|
396
414
|
|
|
415
|
+
/**
|
|
416
|
+
* Resolve the environment-derived run-start fields (eval integration mode,
|
|
417
|
+
* test policy overrides, preview runtime) into explicit request fields, in the
|
|
418
|
+
* order the SDK has always validated them. The shared body builder in
|
|
419
|
+
* `plays/run-request` never reads the environment.
|
|
420
|
+
*/
|
|
421
|
+
function resolveStartPlayRunRequest(request: StartPlayRunRequest): {
|
|
422
|
+
request: ResolvedStartPlayRunRequest;
|
|
423
|
+
runtime: PlayRuntimeSelection | undefined;
|
|
424
|
+
} {
|
|
425
|
+
const integrationMode = resolvePlayRunIntegrationMode(request);
|
|
426
|
+
const testPolicyOverrides =
|
|
427
|
+
request.testPolicyOverrides ?? parseEnvTestPolicyOverrides();
|
|
428
|
+
const runtime = resolvePlayRunRuntimeSelection(request);
|
|
429
|
+
const resolved: ResolvedStartPlayRunRequest = { ...request };
|
|
430
|
+
delete resolved.integrationMode;
|
|
431
|
+
delete resolved.runtime;
|
|
432
|
+
delete resolved.testPolicyOverrides;
|
|
433
|
+
if (integrationMode) resolved.integrationMode = integrationMode;
|
|
434
|
+
if (runtime) resolved.runtime = runtime;
|
|
435
|
+
if (testPolicyOverrides) resolved.testPolicyOverrides = testPolicyOverrides;
|
|
436
|
+
return { request: resolved, runtime };
|
|
437
|
+
}
|
|
438
|
+
|
|
397
439
|
function runtimeSelectionHeaders(
|
|
398
440
|
runtime: PlayRuntimeSelection | undefined,
|
|
399
441
|
): Record<string, string> | undefined {
|
|
@@ -884,7 +926,7 @@ export type RunsNamespace = {
|
|
|
884
926
|
runId?: string;
|
|
885
927
|
limit?: number;
|
|
886
928
|
offset?: number;
|
|
887
|
-
rowMode?: 'output' | 'all';
|
|
929
|
+
rowMode?: 'output' | 'all' | 'live';
|
|
888
930
|
/** Cancel the page request, including its response body and retry waits. */
|
|
889
931
|
signal?: AbortSignal;
|
|
890
932
|
}) => Promise<PlaySheetRowsResult>;
|
|
@@ -2163,6 +2205,17 @@ export type BillingUsageOptions = {
|
|
|
2163
2205
|
runId?: string;
|
|
2164
2206
|
};
|
|
2165
2207
|
|
|
2208
|
+
/** One run's billed credits and settlement state from `getRunBilling`. */
|
|
2209
|
+
export type RunBillingResult = {
|
|
2210
|
+
runs: Array<{
|
|
2211
|
+
runId: string;
|
|
2212
|
+
/** Customer-visible billed credits so far; absent when unknown. */
|
|
2213
|
+
credits?: number;
|
|
2214
|
+
/** The run owns a charge reservation that has not settled yet. */
|
|
2215
|
+
settling: boolean;
|
|
2216
|
+
}>;
|
|
2217
|
+
};
|
|
2218
|
+
|
|
2166
2219
|
export type BillingUsageResult = {
|
|
2167
2220
|
org_id: string;
|
|
2168
2221
|
balance?: number;
|
|
@@ -2308,17 +2361,6 @@ function preferPrebuiltPlayDescriptions<T extends PlayDescription>(
|
|
|
2308
2361
|
.map(({ play }) => play);
|
|
2309
2362
|
}
|
|
2310
2363
|
|
|
2311
|
-
function isPlayRunPackage(value: unknown): value is PlayRunPackage {
|
|
2312
|
-
return Boolean(
|
|
2313
|
-
value &&
|
|
2314
|
-
typeof value === 'object' &&
|
|
2315
|
-
!Array.isArray(value) &&
|
|
2316
|
-
(value as Record<string, unknown>).kind === 'play_run' &&
|
|
2317
|
-
(value as Record<string, unknown>).run &&
|
|
2318
|
-
typeof (value as { run?: { id?: unknown } }).run?.id === 'string',
|
|
2319
|
-
);
|
|
2320
|
-
}
|
|
2321
|
-
|
|
2322
2364
|
function normalizePlayStatus(raw: Record<string, unknown>): PlayStatus {
|
|
2323
2365
|
const runPackage = isPlayRunPackage(raw)
|
|
2324
2366
|
? raw
|
|
@@ -2367,170 +2409,6 @@ function normalizePlayStatus(raw: Record<string, unknown>): PlayStatus {
|
|
|
2367
2409
|
};
|
|
2368
2410
|
}
|
|
2369
2411
|
|
|
2370
|
-
function normalizePlayRunStart(raw: Record<string, unknown>): PlayRunStart {
|
|
2371
|
-
const runPackage = isPlayRunPackage(raw)
|
|
2372
|
-
? raw
|
|
2373
|
-
: isPlayRunPackage(raw.package)
|
|
2374
|
-
? raw.package
|
|
2375
|
-
: null;
|
|
2376
|
-
if (!runPackage) {
|
|
2377
|
-
const workflowId =
|
|
2378
|
-
typeof raw.workflowId === 'string' && raw.workflowId
|
|
2379
|
-
? raw.workflowId
|
|
2380
|
-
: typeof raw.runId === 'string'
|
|
2381
|
-
? raw.runId
|
|
2382
|
-
: '';
|
|
2383
|
-
return {
|
|
2384
|
-
...(raw as unknown as Omit<PlayRunStart, 'workflowId'>),
|
|
2385
|
-
workflowId,
|
|
2386
|
-
};
|
|
2387
|
-
}
|
|
2388
|
-
const status =
|
|
2389
|
-
typeof runPackage.run.status === 'string'
|
|
2390
|
-
? runPackage.run.status
|
|
2391
|
-
: 'running';
|
|
2392
|
-
return {
|
|
2393
|
-
workflowId: runPackage.run.id,
|
|
2394
|
-
name: runPackage.run.playName,
|
|
2395
|
-
status,
|
|
2396
|
-
...(runPackage.run.dashboardUrl
|
|
2397
|
-
? { dashboardUrl: runPackage.run.dashboardUrl }
|
|
2398
|
-
: {}),
|
|
2399
|
-
...(isTerminalPlayRunLifecycleStatus(status)
|
|
2400
|
-
? { finalStatus: runPackage }
|
|
2401
|
-
: {}),
|
|
2402
|
-
package: runPackage,
|
|
2403
|
-
};
|
|
2404
|
-
}
|
|
2405
|
-
|
|
2406
|
-
function decodeBase64Bytes(value: string): Uint8Array {
|
|
2407
|
-
const binary = atob(value);
|
|
2408
|
-
const bytes = new Uint8Array(binary.length);
|
|
2409
|
-
for (let index = 0; index < binary.length; index += 1) {
|
|
2410
|
-
bytes[index] = binary.charCodeAt(index);
|
|
2411
|
-
}
|
|
2412
|
-
return bytes;
|
|
2413
|
-
}
|
|
2414
|
-
|
|
2415
|
-
/**
|
|
2416
|
-
* A staged-file upload target minted by POST /api/v2/plays/files/stage/mint.
|
|
2417
|
-
* When `alreadyStaged` is true the server already holds the content-addressed
|
|
2418
|
-
* object and `uploadUrl` is null; otherwise the client PUTs the body to
|
|
2419
|
-
* `uploadUrl` with `uploadHeaders`.
|
|
2420
|
-
*/
|
|
2421
|
-
type MintStagedFileUpload = {
|
|
2422
|
-
logicalPath: string;
|
|
2423
|
-
contentHash: string;
|
|
2424
|
-
ref: PlayStagedFileRef;
|
|
2425
|
-
alreadyStaged: boolean;
|
|
2426
|
-
uploadUrl: string | null;
|
|
2427
|
-
uploadHeaders: Record<string, string> | null;
|
|
2428
|
-
uploadExpiresAt: string | null;
|
|
2429
|
-
};
|
|
2430
|
-
|
|
2431
|
-
// Legacy multipart staging proxies the body through the serverless function,
|
|
2432
|
-
// which caps request bodies near 4.5MB. Stay conservatively below that so the
|
|
2433
|
-
// fail-loud guidance fires before the platform returns an opaque 413.
|
|
2434
|
-
const STAGE_LEGACY_MULTIPART_MAX_BYTES = 4_000_000;
|
|
2435
|
-
|
|
2436
|
-
const STAGE_DIRECT_UPLOAD_MAX_ATTEMPTS = 3;
|
|
2437
|
-
|
|
2438
|
-
function stagedUploadIdentity(
|
|
2439
|
-
logicalPath: string,
|
|
2440
|
-
contentHash: string,
|
|
2441
|
-
): string {
|
|
2442
|
-
return `${contentHash}:${logicalPath}`;
|
|
2443
|
-
}
|
|
2444
|
-
|
|
2445
|
-
function isStagedUploadMintUnsupported(error: unknown): boolean {
|
|
2446
|
-
// A server without the mint route returns 404. Treat only that as
|
|
2447
|
-
// "unsupported, fall back"; every other failure propagates.
|
|
2448
|
-
return error instanceof DeeplineError && error.statusCode === 404;
|
|
2449
|
-
}
|
|
2450
|
-
|
|
2451
|
-
function isStagedUploadDirectEgressDenied(error: unknown): boolean {
|
|
2452
|
-
return (
|
|
2453
|
-
error instanceof DeeplineError &&
|
|
2454
|
-
error.code === 'STAGED_FILE_UPLOAD_EGRESS_DENIED'
|
|
2455
|
-
);
|
|
2456
|
-
}
|
|
2457
|
-
|
|
2458
|
-
function formatMegabytes(bytes: number): string {
|
|
2459
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
2460
|
-
}
|
|
2461
|
-
|
|
2462
|
-
async function uploadStagedFileToPresignedUrl(input: {
|
|
2463
|
-
url: string;
|
|
2464
|
-
headers: Record<string, string>;
|
|
2465
|
-
body: Uint8Array;
|
|
2466
|
-
logicalPath: string;
|
|
2467
|
-
}): Promise<void> {
|
|
2468
|
-
// Wrap the bytes in a fresh Blob so the body is a BodyInit and the upload is
|
|
2469
|
-
// re-runnable across retries (a consumed stream would not be).
|
|
2470
|
-
const arrayBuffer = input.body.buffer.slice(
|
|
2471
|
-
input.body.byteOffset,
|
|
2472
|
-
input.body.byteOffset + input.body.byteLength,
|
|
2473
|
-
) as ArrayBuffer;
|
|
2474
|
-
let lastError: unknown;
|
|
2475
|
-
for (
|
|
2476
|
-
let attempt = 1;
|
|
2477
|
-
attempt <= STAGE_DIRECT_UPLOAD_MAX_ATTEMPTS;
|
|
2478
|
-
attempt += 1
|
|
2479
|
-
) {
|
|
2480
|
-
try {
|
|
2481
|
-
const response = await fetch(input.url, {
|
|
2482
|
-
method: 'PUT',
|
|
2483
|
-
headers: input.headers,
|
|
2484
|
-
body: new Blob([arrayBuffer]),
|
|
2485
|
-
});
|
|
2486
|
-
if (response.ok) {
|
|
2487
|
-
return;
|
|
2488
|
-
}
|
|
2489
|
-
const text = await response.text().catch(() => '');
|
|
2490
|
-
const egressDenied =
|
|
2491
|
-
response.status === 403 &&
|
|
2492
|
-
response.headers.get('x-deny-reason')?.trim().toLowerCase() ===
|
|
2493
|
-
'host_not_allowed';
|
|
2494
|
-
lastError = new DeeplineError(
|
|
2495
|
-
`Direct storage upload of ${input.logicalPath} failed: ${response.status} ${text.slice(0, 200)}`,
|
|
2496
|
-
response.status,
|
|
2497
|
-
egressDenied
|
|
2498
|
-
? 'STAGED_FILE_UPLOAD_EGRESS_DENIED'
|
|
2499
|
-
: 'STAGED_FILE_UPLOAD_FAILED',
|
|
2500
|
-
{ logicalPath: input.logicalPath },
|
|
2501
|
-
);
|
|
2502
|
-
// 4xx (other than throttling) will not recover on retry.
|
|
2503
|
-
if (response.status < 500 && response.status !== 429) {
|
|
2504
|
-
break;
|
|
2505
|
-
}
|
|
2506
|
-
} catch (error) {
|
|
2507
|
-
// fetch rejects network-level failures instead of returning a Response.
|
|
2508
|
-
// Sandboxed egress proxies commonly reject the TLS CONNECT this way, so
|
|
2509
|
-
// preserve the existing multipart fallback after direct retries finish.
|
|
2510
|
-
lastError =
|
|
2511
|
-
error instanceof TypeError
|
|
2512
|
-
? new DeeplineError(
|
|
2513
|
-
`Direct storage upload of ${input.logicalPath} could not reach the storage endpoint: ${error.message}`,
|
|
2514
|
-
undefined,
|
|
2515
|
-
'STAGED_FILE_UPLOAD_EGRESS_DENIED',
|
|
2516
|
-
{ logicalPath: input.logicalPath },
|
|
2517
|
-
)
|
|
2518
|
-
: error;
|
|
2519
|
-
}
|
|
2520
|
-
if (attempt < STAGE_DIRECT_UPLOAD_MAX_ATTEMPTS) {
|
|
2521
|
-
await sleep(250 * attempt);
|
|
2522
|
-
}
|
|
2523
|
-
}
|
|
2524
|
-
throw lastError instanceof Error
|
|
2525
|
-
? lastError
|
|
2526
|
-
: new DeeplineError(
|
|
2527
|
-
`Direct storage upload of ${input.logicalPath} failed.`,
|
|
2528
|
-
undefined,
|
|
2529
|
-
'STAGED_FILE_UPLOAD_FAILED',
|
|
2530
|
-
{ logicalPath: input.logicalPath },
|
|
2531
|
-
);
|
|
2532
|
-
}
|
|
2533
|
-
|
|
2534
2412
|
function readStringArray(value: unknown): string[] {
|
|
2535
2413
|
return Array.isArray(value)
|
|
2536
2414
|
? value.filter((line): line is string => typeof line === 'string')
|
|
@@ -3422,74 +3300,12 @@ export class DeeplineClient {
|
|
|
3422
3300
|
* ```
|
|
3423
3301
|
*/
|
|
3424
3302
|
async startPlayRun(request: StartPlayRunRequest): Promise<PlayRunStart> {
|
|
3425
|
-
const
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
const response = await this.http.post<Record<string, unknown>>(
|
|
3431
|
-
'/api/v2/plays/run',
|
|
3432
|
-
{
|
|
3433
|
-
...(request.name ? { name: request.name } : {}),
|
|
3434
|
-
...(request.revisionId ? { revisionId: request.revisionId } : {}),
|
|
3435
|
-
...(request.artifactStorageKey
|
|
3436
|
-
? { artifactStorageKey: request.artifactStorageKey }
|
|
3437
|
-
: {}),
|
|
3438
|
-
...(request.sourceCode ? { sourceCode: request.sourceCode } : {}),
|
|
3439
|
-
...(request.sourceFiles ? { sourceFiles: request.sourceFiles } : {}),
|
|
3440
|
-
...(request.description ? { description: request.description } : {}),
|
|
3441
|
-
...('staticPipeline' in request
|
|
3442
|
-
? { staticPipeline: request.staticPipeline }
|
|
3443
|
-
: {}),
|
|
3444
|
-
...(request.artifactHash ? { artifactHash: request.artifactHash } : {}),
|
|
3445
|
-
...(request.graphHash ? { graphHash: request.graphHash } : {}),
|
|
3446
|
-
...(request.runtimeArtifact
|
|
3447
|
-
? { runtimeArtifact: request.runtimeArtifact }
|
|
3448
|
-
: {}),
|
|
3449
|
-
...(request.compilerManifest
|
|
3450
|
-
? { compilerManifest: request.compilerManifest }
|
|
3451
|
-
: {}),
|
|
3452
|
-
...(request.inputFileUpload
|
|
3453
|
-
? { inputFileUpload: request.inputFileUpload }
|
|
3454
|
-
: {}),
|
|
3455
|
-
...(request.packagedFileUploads?.length
|
|
3456
|
-
? { packagedFileUploads: request.packagedFileUploads }
|
|
3457
|
-
: {}),
|
|
3458
|
-
...(request.input ? { input: request.input } : {}),
|
|
3459
|
-
...(request.inputFile ? { inputFile: request.inputFile } : {}),
|
|
3460
|
-
...(request.packagedFiles?.length
|
|
3461
|
-
? { packagedFiles: request.packagedFiles }
|
|
3462
|
-
: {}),
|
|
3463
|
-
...(request.force ? { force: true } : {}),
|
|
3464
|
-
...(forceToolRefresh ? { forceToolRefresh: true } : {}),
|
|
3465
|
-
...(typeof request.maxConcurrentExternalCalls === 'number'
|
|
3466
|
-
? {
|
|
3467
|
-
maxConcurrentExternalCalls: request.maxConcurrentExternalCalls,
|
|
3468
|
-
}
|
|
3469
|
-
: {}),
|
|
3470
|
-
...(typeof request.maxConcurrentRows === 'number'
|
|
3471
|
-
? { maxConcurrentRows: request.maxConcurrentRows }
|
|
3472
|
-
: {}),
|
|
3473
|
-
...(typeof request.waitForCompletionMs === 'number'
|
|
3474
|
-
? { waitForCompletionMs: request.waitForCompletionMs }
|
|
3475
|
-
: {}),
|
|
3476
|
-
// Profile selection is the API's job, not the CLI's. The server
|
|
3477
|
-
// defaults to absurd; callers normally omit this field.
|
|
3478
|
-
...(request.profile ? { profile: request.profile } : {}),
|
|
3479
|
-
...(integrationMode ? { integrationMode } : {}),
|
|
3480
|
-
...(request.fixtureBehavior
|
|
3481
|
-
? { fixtureBehavior: request.fixtureBehavior }
|
|
3482
|
-
: {}),
|
|
3483
|
-
...(runtime ? { runtime } : {}),
|
|
3484
|
-
...(testPolicyOverrides ? { testPolicyOverrides } : {}),
|
|
3485
|
-
},
|
|
3486
|
-
runtimeSelectionHeaders(runtime),
|
|
3487
|
-
// A start can reach the server even when its response is lost or times
|
|
3488
|
-
// out. Retrying this mutation without an idempotency key can create a
|
|
3489
|
-
// second root run, so callers must resolve ambiguous failures explicitly.
|
|
3490
|
-
{ maxRetries: 0, exactUrlOnly: true },
|
|
3303
|
+
const resolved = resolveStartPlayRunRequest(request);
|
|
3304
|
+
return startPlayRun(
|
|
3305
|
+
this.http,
|
|
3306
|
+
resolved.request,
|
|
3307
|
+
runtimeSelectionHeaders(resolved.runtime),
|
|
3491
3308
|
);
|
|
3492
|
-
return normalizePlayRunStart(response);
|
|
3493
3309
|
}
|
|
3494
3310
|
|
|
3495
3311
|
/**
|
|
@@ -3509,67 +3325,14 @@ export class DeeplineClient {
|
|
|
3509
3325
|
request: StartPlayRunRequest,
|
|
3510
3326
|
options?: { signal?: AbortSignal },
|
|
3511
3327
|
): AsyncGenerator<PlayLiveEvent> {
|
|
3512
|
-
const
|
|
3513
|
-
const
|
|
3514
|
-
request.testPolicyOverrides ?? parseEnvTestPolicyOverrides();
|
|
3515
|
-
const forceToolRefresh = request.forceToolRefresh === true;
|
|
3516
|
-
const runtime = resolvePlayRunRuntimeSelection(request);
|
|
3517
|
-
const body = {
|
|
3518
|
-
...(request.name ? { name: request.name } : {}),
|
|
3519
|
-
...(request.revisionId ? { revisionId: request.revisionId } : {}),
|
|
3520
|
-
...(request.artifactStorageKey
|
|
3521
|
-
? { artifactStorageKey: request.artifactStorageKey }
|
|
3522
|
-
: {}),
|
|
3523
|
-
...(request.sourceCode ? { sourceCode: request.sourceCode } : {}),
|
|
3524
|
-
...(request.sourceFiles ? { sourceFiles: request.sourceFiles } : {}),
|
|
3525
|
-
...(request.description ? { description: request.description } : {}),
|
|
3526
|
-
...('staticPipeline' in request
|
|
3527
|
-
? { staticPipeline: request.staticPipeline }
|
|
3528
|
-
: {}),
|
|
3529
|
-
...(request.artifactHash ? { artifactHash: request.artifactHash } : {}),
|
|
3530
|
-
...(request.graphHash ? { graphHash: request.graphHash } : {}),
|
|
3531
|
-
...(request.runtimeArtifact
|
|
3532
|
-
? { runtimeArtifact: request.runtimeArtifact }
|
|
3533
|
-
: {}),
|
|
3534
|
-
...(request.compilerManifest
|
|
3535
|
-
? { compilerManifest: request.compilerManifest }
|
|
3536
|
-
: {}),
|
|
3537
|
-
...(request.inputFileUpload
|
|
3538
|
-
? { inputFileUpload: request.inputFileUpload }
|
|
3539
|
-
: {}),
|
|
3540
|
-
...(request.packagedFileUploads?.length
|
|
3541
|
-
? { packagedFileUploads: request.packagedFileUploads }
|
|
3542
|
-
: {}),
|
|
3543
|
-
...(request.input ? { input: request.input } : {}),
|
|
3544
|
-
...(request.inputFile ? { inputFile: request.inputFile } : {}),
|
|
3545
|
-
...(request.packagedFiles?.length
|
|
3546
|
-
? { packagedFiles: request.packagedFiles }
|
|
3547
|
-
: {}),
|
|
3548
|
-
...(request.force ? { force: true } : {}),
|
|
3549
|
-
...(forceToolRefresh ? { forceToolRefresh: true } : {}),
|
|
3550
|
-
...(typeof request.maxConcurrentExternalCalls === 'number'
|
|
3551
|
-
? { maxConcurrentExternalCalls: request.maxConcurrentExternalCalls }
|
|
3552
|
-
: {}),
|
|
3553
|
-
...(typeof request.maxConcurrentRows === 'number'
|
|
3554
|
-
? { maxConcurrentRows: request.maxConcurrentRows }
|
|
3555
|
-
: {}),
|
|
3556
|
-
...(typeof request.waitForCompletionMs === 'number'
|
|
3557
|
-
? { waitForCompletionMs: request.waitForCompletionMs }
|
|
3558
|
-
: {}),
|
|
3559
|
-
...(request.profile ? { profile: request.profile } : {}),
|
|
3560
|
-
...(integrationMode ? { integrationMode } : {}),
|
|
3561
|
-
...(request.fixtureBehavior
|
|
3562
|
-
? { fixtureBehavior: request.fixtureBehavior }
|
|
3563
|
-
: {}),
|
|
3564
|
-
...(runtime ? { runtime } : {}),
|
|
3565
|
-
...(testPolicyOverrides ? { testPolicyOverrides } : {}),
|
|
3566
|
-
};
|
|
3328
|
+
const resolved = resolveStartPlayRunRequest(request);
|
|
3329
|
+
const body = buildPlayRunStartBody(resolved.request);
|
|
3567
3330
|
for await (const event of this.http.streamSse<PlayLiveEvent>(
|
|
3568
|
-
|
|
3331
|
+
PLAY_RUN_START_STREAM_PATH,
|
|
3569
3332
|
{
|
|
3570
3333
|
method: 'POST',
|
|
3571
3334
|
body,
|
|
3572
|
-
headers: runtimeSelectionHeaders(runtime),
|
|
3335
|
+
headers: runtimeSelectionHeaders(resolved.runtime),
|
|
3573
3336
|
signal: options?.signal,
|
|
3574
3337
|
},
|
|
3575
3338
|
)) {
|
|
@@ -3998,94 +3761,7 @@ export class DeeplineClient {
|
|
|
3998
3761
|
bytes: number;
|
|
3999
3762
|
}>,
|
|
4000
3763
|
): Promise<PlayStagedFileRef[]> {
|
|
4001
|
-
|
|
4002
|
-
// straight to storage. This bypasses the ~4.5MB serverless request-body
|
|
4003
|
-
// limit that the legacy multipart proxy hits (413
|
|
4004
|
-
// FUNCTION_PAYLOAD_TOO_LARGE), so large enriched CSVs stage and resume.
|
|
4005
|
-
let uploads: MintStagedFileUpload[];
|
|
4006
|
-
try {
|
|
4007
|
-
uploads = await this.mintStagedPlayFileUploads(
|
|
4008
|
-
files.map((file) => ({
|
|
4009
|
-
logicalPath: file.logicalPath,
|
|
4010
|
-
contentHash: file.contentHash,
|
|
4011
|
-
contentType: file.contentType,
|
|
4012
|
-
bytes: file.bytes,
|
|
4013
|
-
})),
|
|
4014
|
-
);
|
|
4015
|
-
} catch (error) {
|
|
4016
|
-
if (isStagedUploadMintUnsupported(error)) {
|
|
4017
|
-
// The connected server predates direct-to-storage staging. Fall back to
|
|
4018
|
-
// the legacy multipart proxy, but only for files small enough to clear
|
|
4019
|
-
// the serverless body limit; larger files fail loud with guidance.
|
|
4020
|
-
return this.stagePlayFilesViaMultipart(files);
|
|
4021
|
-
}
|
|
4022
|
-
throw error;
|
|
4023
|
-
}
|
|
4024
|
-
|
|
4025
|
-
const uploadByIdentity = new Map<string, MintStagedFileUpload>();
|
|
4026
|
-
for (const upload of uploads) {
|
|
4027
|
-
uploadByIdentity.set(
|
|
4028
|
-
stagedUploadIdentity(upload.logicalPath, upload.contentHash),
|
|
4029
|
-
upload,
|
|
4030
|
-
);
|
|
4031
|
-
}
|
|
4032
|
-
|
|
4033
|
-
type DirectStageResult =
|
|
4034
|
-
| { ref: PlayStagedFileRef }
|
|
4035
|
-
| { fallbackFile: (typeof files)[number] };
|
|
4036
|
-
const directResults: DirectStageResult[] = await Promise.all(
|
|
4037
|
-
files.map(async (file) => {
|
|
4038
|
-
const upload = uploadByIdentity.get(
|
|
4039
|
-
stagedUploadIdentity(file.logicalPath, file.contentHash),
|
|
4040
|
-
);
|
|
4041
|
-
if (!upload) {
|
|
4042
|
-
throw new DeeplineError(
|
|
4043
|
-
`The staging server did not return an upload target for ${file.logicalPath}.`,
|
|
4044
|
-
undefined,
|
|
4045
|
-
'STAGED_FILE_MINT_INCOMPLETE',
|
|
4046
|
-
);
|
|
4047
|
-
}
|
|
4048
|
-
if (upload.alreadyStaged || !upload.uploadUrl) {
|
|
4049
|
-
return { ref: upload.ref };
|
|
4050
|
-
}
|
|
4051
|
-
try {
|
|
4052
|
-
await uploadStagedFileToPresignedUrl({
|
|
4053
|
-
url: upload.uploadUrl,
|
|
4054
|
-
headers: upload.uploadHeaders ?? {
|
|
4055
|
-
'content-type': file.contentType,
|
|
4056
|
-
},
|
|
4057
|
-
body: decodeBase64Bytes(file.contentBase64),
|
|
4058
|
-
logicalPath: file.logicalPath,
|
|
4059
|
-
});
|
|
4060
|
-
return { ref: upload.ref };
|
|
4061
|
-
} catch (error) {
|
|
4062
|
-
if (isStagedUploadDirectEgressDenied(error)) {
|
|
4063
|
-
return { fallbackFile: file };
|
|
4064
|
-
}
|
|
4065
|
-
throw error;
|
|
4066
|
-
}
|
|
4067
|
-
}),
|
|
4068
|
-
);
|
|
4069
|
-
|
|
4070
|
-
return await Promise.all(
|
|
4071
|
-
directResults.map(async (result) => {
|
|
4072
|
-
if ('fallbackFile' in result) {
|
|
4073
|
-
const [ref] = await this.stagePlayFilesViaMultipart(
|
|
4074
|
-
[result.fallbackFile],
|
|
4075
|
-
'direct-egress-denied',
|
|
4076
|
-
);
|
|
4077
|
-
if (!ref) {
|
|
4078
|
-
throw new DeeplineError(
|
|
4079
|
-
`The staging server did not return an upload target for ${result.fallbackFile.logicalPath}.`,
|
|
4080
|
-
undefined,
|
|
4081
|
-
'STAGED_FILE_MINT_INCOMPLETE',
|
|
4082
|
-
);
|
|
4083
|
-
}
|
|
4084
|
-
return ref;
|
|
4085
|
-
}
|
|
4086
|
-
return result.ref;
|
|
4087
|
-
}),
|
|
4088
|
-
);
|
|
3764
|
+
return stagePlayFiles(this.http, files);
|
|
4089
3765
|
}
|
|
4090
3766
|
|
|
4091
3767
|
/**
|
|
@@ -4103,72 +3779,7 @@ export class DeeplineClient {
|
|
|
4103
3779
|
bytes: number;
|
|
4104
3780
|
}>,
|
|
4105
3781
|
): Promise<MintStagedFileUpload[]> {
|
|
4106
|
-
|
|
4107
|
-
uploads: MintStagedFileUpload[];
|
|
4108
|
-
}>('/api/v2/plays/files/stage/mint', { files });
|
|
4109
|
-
return response.uploads ?? [];
|
|
4110
|
-
}
|
|
4111
|
-
|
|
4112
|
-
private async stagePlayFilesViaMultipart(
|
|
4113
|
-
files: Array<{
|
|
4114
|
-
logicalPath: string;
|
|
4115
|
-
contentBase64: string;
|
|
4116
|
-
contentHash: string;
|
|
4117
|
-
contentType: string;
|
|
4118
|
-
bytes: number;
|
|
4119
|
-
}>,
|
|
4120
|
-
reason: 'mint-unsupported' | 'direct-egress-denied' = 'mint-unsupported',
|
|
4121
|
-
): Promise<PlayStagedFileRef[]> {
|
|
4122
|
-
for (const file of files) {
|
|
4123
|
-
if (file.bytes > STAGE_LEGACY_MULTIPART_MAX_BYTES) {
|
|
4124
|
-
const reasonMessage =
|
|
4125
|
-
reason === 'direct-egress-denied'
|
|
4126
|
-
? "direct storage is blocked by this environment's network egress policy"
|
|
4127
|
-
: 'the connected Deepline server does not support direct-to-storage uploads';
|
|
4128
|
-
throw new DeeplineError(
|
|
4129
|
-
`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.`,
|
|
4130
|
-
413,
|
|
4131
|
-
'STAGED_FILE_TOO_LARGE_FOR_LEGACY_UPLOAD',
|
|
4132
|
-
{
|
|
4133
|
-
logicalPath: file.logicalPath,
|
|
4134
|
-
bytes: file.bytes,
|
|
4135
|
-
maxBytes: STAGE_LEGACY_MULTIPART_MAX_BYTES,
|
|
4136
|
-
},
|
|
4137
|
-
);
|
|
4138
|
-
}
|
|
4139
|
-
}
|
|
4140
|
-
const buildFormData = () => {
|
|
4141
|
-
const formData = new FormData();
|
|
4142
|
-
formData.set(
|
|
4143
|
-
'metadata',
|
|
4144
|
-
JSON.stringify({
|
|
4145
|
-
files: files.map((file, index) => ({
|
|
4146
|
-
index,
|
|
4147
|
-
logicalPath: file.logicalPath,
|
|
4148
|
-
contentHash: file.contentHash,
|
|
4149
|
-
contentType: file.contentType,
|
|
4150
|
-
bytes: file.bytes,
|
|
4151
|
-
})),
|
|
4152
|
-
}),
|
|
4153
|
-
);
|
|
4154
|
-
for (const [index, file] of files.entries()) {
|
|
4155
|
-
const bytes = decodeBase64Bytes(file.contentBase64);
|
|
4156
|
-
const body = bytes.buffer.slice(
|
|
4157
|
-
bytes.byteOffset,
|
|
4158
|
-
bytes.byteOffset + bytes.byteLength,
|
|
4159
|
-
) as ArrayBuffer;
|
|
4160
|
-
formData.set(
|
|
4161
|
-
`file:${index}`,
|
|
4162
|
-
new Blob([body], { type: file.contentType }),
|
|
4163
|
-
file.logicalPath,
|
|
4164
|
-
);
|
|
4165
|
-
}
|
|
4166
|
-
return formData;
|
|
4167
|
-
};
|
|
4168
|
-
const response = await this.http.postFormData<{
|
|
4169
|
-
files: PlayStagedFileRef[];
|
|
4170
|
-
}>('/api/v2/plays/files/stage', buildFormData);
|
|
4171
|
-
return response.files;
|
|
3782
|
+
return mintStagedPlayFileUploads(this.http, files);
|
|
4172
3783
|
}
|
|
4173
3784
|
|
|
4174
3785
|
/**
|
|
@@ -4750,7 +4361,7 @@ export class DeeplineClient {
|
|
|
4750
4361
|
}
|
|
4751
4362
|
return this.http.post<RerunPlayRunResult>(
|
|
4752
4363
|
`/api/v2/runs/${encodeURIComponent(runId)}/rerun`,
|
|
4753
|
-
{},
|
|
4364
|
+
options?.inputOverrides ? { inputOverrides: options.inputOverrides } : {},
|
|
4754
4365
|
{ 'Idempotency-Key': idempotencyKey || globalThis.crypto.randomUUID() },
|
|
4755
4366
|
);
|
|
4756
4367
|
}
|
|
@@ -4906,7 +4517,7 @@ export class DeeplineClient {
|
|
|
4906
4517
|
runId?: string;
|
|
4907
4518
|
limit?: number;
|
|
4908
4519
|
offset?: number;
|
|
4909
|
-
rowMode?: 'output' | 'all';
|
|
4520
|
+
rowMode?: 'output' | 'all' | 'live';
|
|
4910
4521
|
/** Cancel the page request, including its response body and retry waits. */
|
|
4911
4522
|
signal?: AbortSignal;
|
|
4912
4523
|
}): Promise<PlaySheetRowsResult> {
|
|
@@ -4918,8 +4529,8 @@ export class DeeplineClient {
|
|
|
4918
4529
|
if (input.runId?.trim()) {
|
|
4919
4530
|
params.set('runId', input.runId.trim());
|
|
4920
4531
|
}
|
|
4921
|
-
if (input.rowMode === 'all') {
|
|
4922
|
-
params.set('rowMode',
|
|
4532
|
+
if (input.rowMode === 'all' || input.rowMode === 'live') {
|
|
4533
|
+
params.set('rowMode', input.rowMode);
|
|
4923
4534
|
}
|
|
4924
4535
|
const result = await this.http.get<PlaySheetRowsResult>(
|
|
4925
4536
|
`/api/v2/plays/${encodeURIComponent(input.playName)}/sheet?${params.toString()}`,
|
|
@@ -5146,6 +4757,23 @@ export class DeeplineClient {
|
|
|
5146
4757
|
);
|
|
5147
4758
|
}
|
|
5148
4759
|
|
|
4760
|
+
/** Read a Play's cron and webhook triggers and their scheduler state. */
|
|
4761
|
+
async getPlayTriggerConfig(playName: string): Promise<PlayTriggerConfigView> {
|
|
4762
|
+
return this.http.get(playTriggerConfigPath(playName));
|
|
4763
|
+
}
|
|
4764
|
+
|
|
4765
|
+
/**
|
|
4766
|
+
* Declare a Play's cron and/or webhook trigger (null removes it) and publish
|
|
4767
|
+
* the rewritten source as a new live revision. Retry-safe: a request the
|
|
4768
|
+
* live revision already satisfies returns `changed: false`.
|
|
4769
|
+
*/
|
|
4770
|
+
async updatePlayTriggerConfig(
|
|
4771
|
+
playName: string,
|
|
4772
|
+
update: PlayTriggerConfigUpdate,
|
|
4773
|
+
): Promise<PlayTriggerConfigUpdateResult> {
|
|
4774
|
+
return this.http.put(playTriggerConfigPath(playName), update);
|
|
4775
|
+
}
|
|
4776
|
+
|
|
5149
4777
|
/** List one bounded page of existing Play locations; continue with cursor. */
|
|
5150
4778
|
async listPlaySettingsPaths(
|
|
5151
4779
|
options: { root?: 'person' | 'team'; limit?: number; cursor?: string } = {},
|
|
@@ -6028,6 +5656,17 @@ export class DeeplineClient {
|
|
|
6028
5656
|
return event;
|
|
6029
5657
|
}
|
|
6030
5658
|
|
|
5659
|
+
/**
|
|
5660
|
+
* What Deepline has billed each run so far (customer-visible credits, never
|
|
5661
|
+
* provider spend) and whether any of its charges is still settling — the
|
|
5662
|
+
* same read the dashboard's runs grid shows. `GET /api/v2/runs/billing`.
|
|
5663
|
+
*/
|
|
5664
|
+
async getRunBilling(runIds: readonly string[]): Promise<RunBillingResult> {
|
|
5665
|
+
const params = new URLSearchParams();
|
|
5666
|
+
for (const runId of runIds) params.append('runId', runId);
|
|
5667
|
+
return this.http.get<RunBillingResult>(`/api/v2/runs/billing?${params}`);
|
|
5668
|
+
}
|
|
5669
|
+
|
|
6031
5670
|
/**
|
|
6032
5671
|
* Read workspace usage and recent customer-facing Deepline charges. Pass
|
|
6033
5672
|
* the `job_id` from `executeTool` as `requestId` to retrieve one exact call,
|