deepline 0.1.313 → 0.1.314
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/play.ts +5 -9
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +136 -38
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +20 -93
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runtime-limits.ts +68 -61
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +46 -18
- package/dist/cli/index.js +58 -44
- package/dist/cli/index.mjs +58 -44
- package/dist/index.d.mts +5 -9
- package/dist/index.d.ts +5 -9
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/plays/bundle-play-file.d.mts +2 -3
- package/dist/plays/bundle-play-file.d.ts +2 -3
- package/dist/plays/bundle-play-file.mjs +37 -16
- package/package.json +1 -1
|
@@ -198,16 +198,12 @@ export type PlayBindings = {
|
|
|
198
198
|
/** Stop the run before a billed action would push total run credits above this cap. */
|
|
199
199
|
maxCreditsPerRun?: number;
|
|
200
200
|
};
|
|
201
|
-
/** Requested sandbox
|
|
201
|
+
/** Requested prebuilt sandbox and runtime deadline. */
|
|
202
202
|
runtime?: {
|
|
203
203
|
/** Duration such as `"90m"` or `"2h"`. */
|
|
204
204
|
timeout?: string;
|
|
205
|
-
/**
|
|
206
|
-
|
|
207
|
-
/** Whole vCPU count. */
|
|
208
|
-
cpu?: number;
|
|
209
|
-
/** Disk such as `"10GiB"`. */
|
|
210
|
-
disk?: string;
|
|
205
|
+
/** Deepline-managed prebuilt sandbox size. */
|
|
206
|
+
size?: 'standard';
|
|
211
207
|
};
|
|
212
208
|
/** Webhook trigger with optional HMAC signature verification. */
|
|
213
209
|
webhook?: {
|
|
@@ -1204,7 +1200,7 @@ export type DefinePlayConfig<TInput, TOutput extends PlayReturnObject> = {
|
|
|
1204
1200
|
bindings?: PlayBindings;
|
|
1205
1201
|
/** Billing options. */
|
|
1206
1202
|
billing?: PlayBindings['billing'];
|
|
1207
|
-
/** Requested sandbox
|
|
1203
|
+
/** Requested prebuilt sandbox and runtime deadline. */
|
|
1208
1204
|
runtime?: PlayBindings['runtime'];
|
|
1209
1205
|
/** Runtime compatibility override. Omit for the current typed contract. */
|
|
1210
1206
|
compatibility?: PlayBindings['compatibility'];
|
|
@@ -1367,7 +1363,7 @@ export type DefinedPlay<TInput, TOutput extends PlayReturnObject> = ((
|
|
|
1367
1363
|
DeeplineNamedPlay<TInput, TOutput> & {
|
|
1368
1364
|
/** Optional trigger bindings (cron, webhook). */
|
|
1369
1365
|
readonly bindings?: PlayBindings;
|
|
1370
|
-
/** Requested sandbox
|
|
1366
|
+
/** Requested prebuilt sandbox and runtime deadline. */
|
|
1371
1367
|
readonly runtime?: PlayBindings['runtime'];
|
|
1372
1368
|
/** Runtime compatibility explicitly selected by the author. */
|
|
1373
1369
|
readonly compatibility?: PlayBindings['compatibility'];
|
|
@@ -157,7 +157,7 @@ export const SDK_RELEASE = {
|
|
|
157
157
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
158
158
|
// 0.1.254 removes the internal operations tree from the published SDK CLI.
|
|
159
159
|
// Operators use the checkout-local deepline-admin binary instead.
|
|
160
|
-
version: '0.1.
|
|
160
|
+
version: '0.1.314',
|
|
161
161
|
contracts: {
|
|
162
162
|
api: {
|
|
163
163
|
name: 'sdk-http-api',
|
|
@@ -1291,6 +1291,12 @@ function createPacingResolver(
|
|
|
1291
1291
|
export class PlayContextImpl {
|
|
1292
1292
|
private rowStates = new Map<number, RowState>();
|
|
1293
1293
|
private toolCallQueue: ToolCallRequest[] = [];
|
|
1294
|
+
private pendingRuntimeToolOwnershipAssertions: Array<{
|
|
1295
|
+
targets: Array<{ receiptKey: string; leaseId: string }>;
|
|
1296
|
+
resolve: () => void;
|
|
1297
|
+
reject: (error: unknown) => void;
|
|
1298
|
+
}> = [];
|
|
1299
|
+
private runtimeToolOwnershipAssertionFlushScheduled = false;
|
|
1294
1300
|
/**
|
|
1295
1301
|
* Direct durable boundaries (including ctx.fetch) arrive independently from
|
|
1296
1302
|
* concurrent map rows. Hold one microtask's worth so they can use the bulk
|
|
@@ -2094,17 +2100,19 @@ export class PlayContextImpl {
|
|
|
2094
2100
|
try {
|
|
2095
2101
|
const receipts = await this.dispatchChunkedRuntimeReceiptRequest(
|
|
2096
2102
|
requests,
|
|
2097
|
-
(chunk) =>
|
|
2098
|
-
|
|
2103
|
+
(chunk) => {
|
|
2104
|
+
const leaseId = `receipt-lease:${crypto.randomUUID()}`;
|
|
2105
|
+
return claimReceipts({
|
|
2099
2106
|
keys: chunk.map((request) => request.key),
|
|
2100
|
-
leaseIds: chunk.map(() =>
|
|
2107
|
+
leaseIds: chunk.map(() => leaseId),
|
|
2101
2108
|
runId: this.currentReceiptOwnerRunId,
|
|
2102
2109
|
runAttempt: this.currentRunAttempt,
|
|
2103
2110
|
leaseAware: true,
|
|
2104
2111
|
...(first.reclaimRunning ? { reclaimRunning: true } : {}),
|
|
2105
2112
|
...(first.forceRefresh ? { forceRefresh: true } : {}),
|
|
2106
2113
|
...(first.forceFailedRefresh ? { forceFailedRefresh: true } : {}),
|
|
2107
|
-
})
|
|
2114
|
+
});
|
|
2115
|
+
},
|
|
2108
2116
|
);
|
|
2109
2117
|
for (let index = 0; index < requests.length; index += 1) {
|
|
2110
2118
|
const request = requests[index]!;
|
|
@@ -2203,59 +2211,148 @@ export class PlayContextImpl {
|
|
|
2203
2211
|
private async assertRuntimeToolReceiptOwnership(
|
|
2204
2212
|
requests: ToolCallRequest[],
|
|
2205
2213
|
): Promise<void> {
|
|
2206
|
-
const targets =
|
|
2214
|
+
const targets = this.runtimeToolReceiptOwnershipTargets(requests);
|
|
2215
|
+
if (targets.length === 0) return;
|
|
2216
|
+
|
|
2217
|
+
return await new Promise<void>((resolve, reject) => {
|
|
2218
|
+
this.pendingRuntimeToolOwnershipAssertions.push({
|
|
2219
|
+
targets,
|
|
2220
|
+
resolve,
|
|
2221
|
+
reject,
|
|
2222
|
+
});
|
|
2223
|
+
if (this.runtimeToolOwnershipAssertionFlushScheduled) return;
|
|
2224
|
+
this.runtimeToolOwnershipAssertionFlushScheduled = true;
|
|
2225
|
+
queueMicrotask(() => void this.flushRuntimeToolOwnershipAssertionBatch());
|
|
2226
|
+
});
|
|
2227
|
+
}
|
|
2228
|
+
|
|
2229
|
+
private runtimeToolReceiptOwnershipTargets(
|
|
2230
|
+
requests: ToolCallRequest[],
|
|
2231
|
+
): Array<{ receiptKey: string; leaseId: string }> {
|
|
2232
|
+
return requests.flatMap((request) => {
|
|
2207
2233
|
const receiptKey = request.receiptKey?.trim() || null;
|
|
2208
2234
|
if (!receiptKey) return [];
|
|
2209
2235
|
const leaseId = request.receiptLeaseId?.trim() || null;
|
|
2210
2236
|
if (!leaseId) return [];
|
|
2211
2237
|
return [{ receiptKey, leaseId }];
|
|
2212
2238
|
});
|
|
2213
|
-
|
|
2239
|
+
}
|
|
2214
2240
|
|
|
2241
|
+
private async renewRuntimeToolReceiptOwnership(
|
|
2242
|
+
requests: ToolCallRequest[],
|
|
2243
|
+
): Promise<void> {
|
|
2244
|
+
const targets = this.runtimeToolReceiptOwnershipTargets(requests);
|
|
2245
|
+
if (targets.length === 0) return;
|
|
2246
|
+
if (!this.#options.heartbeatRuntimeStepReceipts) {
|
|
2247
|
+
return await this.assertRuntimeToolReceiptOwnership(requests);
|
|
2248
|
+
}
|
|
2215
2249
|
const byLeaseId = new Map<string, string[]>();
|
|
2216
2250
|
for (const target of targets) {
|
|
2217
2251
|
const keys = byLeaseId.get(target.leaseId) ?? [];
|
|
2218
2252
|
keys.push(target.receiptKey);
|
|
2219
2253
|
byLeaseId.set(target.leaseId, keys);
|
|
2220
2254
|
}
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
const receipts = await this.#options.heartbeatRuntimeStepReceipts({
|
|
2255
|
+
await Promise.all(
|
|
2256
|
+
[...byLeaseId].map(async ([leaseId, keys]) => {
|
|
2257
|
+
const receipts = await this.#options.heartbeatRuntimeStepReceipts!({
|
|
2225
2258
|
runId: this.currentReceiptOwnerRunId,
|
|
2226
2259
|
runAttempt: this.currentRunAttempt,
|
|
2227
2260
|
leaseId,
|
|
2228
2261
|
keys,
|
|
2229
2262
|
});
|
|
2230
2263
|
this.assertRuntimeToolReceiptHeartbeatResult(keys, leaseId, receipts);
|
|
2264
|
+
}),
|
|
2265
|
+
);
|
|
2266
|
+
}
|
|
2267
|
+
|
|
2268
|
+
private async flushRuntimeToolOwnershipAssertionBatch(): Promise<void> {
|
|
2269
|
+
this.runtimeToolOwnershipAssertionFlushScheduled = false;
|
|
2270
|
+
const assertions = this.pendingRuntimeToolOwnershipAssertions.splice(0);
|
|
2271
|
+
if (assertions.length === 0) return;
|
|
2272
|
+
const targets = assertions.flatMap((assertion) => assertion.targets);
|
|
2273
|
+
|
|
2274
|
+
if (this.#options.heartbeatRuntimeStepReceipts) {
|
|
2275
|
+
try {
|
|
2276
|
+
const byLeaseId = new Map<string, string[]>();
|
|
2277
|
+
for (const target of targets) {
|
|
2278
|
+
const keys = byLeaseId.get(target.leaseId) ?? [];
|
|
2279
|
+
keys.push(target.receiptKey);
|
|
2280
|
+
byLeaseId.set(target.leaseId, keys);
|
|
2281
|
+
}
|
|
2282
|
+
const renewed = new Map<string, RuntimeStepReceipt | null>();
|
|
2283
|
+
await Promise.all(
|
|
2284
|
+
[...byLeaseId].map(async ([leaseId, keys]) => {
|
|
2285
|
+
const receipts = await this.#options.heartbeatRuntimeStepReceipts!({
|
|
2286
|
+
runId: this.currentReceiptOwnerRunId,
|
|
2287
|
+
runAttempt: this.currentRunAttempt,
|
|
2288
|
+
leaseId,
|
|
2289
|
+
keys,
|
|
2290
|
+
});
|
|
2291
|
+
for (let index = 0; index < keys.length; index += 1) {
|
|
2292
|
+
renewed.set(keys[index]!, receipts[index] ?? null);
|
|
2293
|
+
}
|
|
2294
|
+
}),
|
|
2295
|
+
);
|
|
2296
|
+
for (const assertion of assertions) {
|
|
2297
|
+
const lost = assertion.targets.find((target) => {
|
|
2298
|
+
const receipt = renewed.get(target.receiptKey);
|
|
2299
|
+
return !this.runtimeToolReceiptStillOwned(receipt, target.leaseId);
|
|
2300
|
+
});
|
|
2301
|
+
if (lost) {
|
|
2302
|
+
assertion.reject(
|
|
2303
|
+
new RuntimeReceiptLeaseLostError({
|
|
2304
|
+
receiptKey: lost.receiptKey,
|
|
2305
|
+
runId: this.currentReceiptOwnerRunId,
|
|
2306
|
+
leaseId: lost.leaseId,
|
|
2307
|
+
}),
|
|
2308
|
+
);
|
|
2309
|
+
} else {
|
|
2310
|
+
assertion.resolve();
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2313
|
+
} catch (error) {
|
|
2314
|
+
for (const assertion of assertions) assertion.reject(error);
|
|
2231
2315
|
}
|
|
2232
2316
|
return;
|
|
2233
2317
|
}
|
|
2234
2318
|
|
|
2235
2319
|
if (
|
|
2236
|
-
|
|
2237
|
-
|
|
2320
|
+
this.#options.getRuntimeStepReceipt ||
|
|
2321
|
+
this.#options.getRuntimeStepReceipts
|
|
2238
2322
|
) {
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2323
|
+
try {
|
|
2324
|
+
const latest = await this.getRuntimeStepReceipts(
|
|
2325
|
+
targets.map((target) => target.receiptKey),
|
|
2326
|
+
);
|
|
2327
|
+
for (const assertion of assertions) {
|
|
2328
|
+
const lost = assertion.targets.find((target) => {
|
|
2329
|
+
const receipt = latest.get(target.receiptKey);
|
|
2330
|
+
return !this.runtimeToolReceiptStillOwned(receipt, target.leaseId);
|
|
2331
|
+
});
|
|
2332
|
+
if (lost) {
|
|
2333
|
+
assertion.reject(
|
|
2334
|
+
new RuntimeReceiptLeaseLostError({
|
|
2335
|
+
receiptKey: lost.receiptKey,
|
|
2336
|
+
runId: this.currentReceiptOwnerRunId,
|
|
2337
|
+
leaseId: lost.leaseId,
|
|
2338
|
+
}),
|
|
2339
|
+
);
|
|
2340
|
+
} else {
|
|
2341
|
+
assertion.resolve();
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
} catch (error) {
|
|
2345
|
+
for (const assertion of assertions) assertion.reject(error);
|
|
2257
2346
|
}
|
|
2347
|
+
return;
|
|
2258
2348
|
}
|
|
2349
|
+
|
|
2350
|
+
const error = new RuntimeReceiptLeaseLostError({
|
|
2351
|
+
receiptKey: targets[0]?.receiptKey ?? 'unknown',
|
|
2352
|
+
runId: this.currentReceiptOwnerRunId,
|
|
2353
|
+
leaseId: targets[0]?.leaseId ?? 'unknown',
|
|
2354
|
+
});
|
|
2355
|
+
for (const assertion of assertions) assertion.reject(error);
|
|
2259
2356
|
}
|
|
2260
2357
|
|
|
2261
2358
|
private assertRuntimeToolReceiptHeartbeatResult(
|
|
@@ -2458,22 +2555,23 @@ export class PlayContextImpl {
|
|
|
2458
2555
|
if (uniqueKeys.length === 0) return new Map();
|
|
2459
2556
|
const claimReceipts = this.#options.claimRuntimeStepReceipts;
|
|
2460
2557
|
const receipts = claimReceipts
|
|
2461
|
-
? await this.dispatchChunkedRuntimeReceiptRequest(uniqueKeys, (chunk) =>
|
|
2462
|
-
|
|
2558
|
+
? await this.dispatchChunkedRuntimeReceiptRequest(uniqueKeys, (chunk) => {
|
|
2559
|
+
const leaseId = `receipt-lease:${crypto.randomUUID()}`;
|
|
2560
|
+
return claimReceipts({
|
|
2463
2561
|
keys: chunk,
|
|
2464
2562
|
// A transport retry can replay this mutation after the store
|
|
2465
2563
|
// committed but before the response body was consumed. Stable
|
|
2466
2564
|
// caller-owned tokens distinguish that replay from a concurrent
|
|
2467
2565
|
// claimant without weakening the provider-call execution fence.
|
|
2468
|
-
leaseIds: chunk.map(() =>
|
|
2566
|
+
leaseIds: chunk.map(() => leaseId),
|
|
2469
2567
|
runId: this.currentReceiptOwnerRunId,
|
|
2470
2568
|
runAttempt: this.currentRunAttempt,
|
|
2471
2569
|
leaseAware: true,
|
|
2472
2570
|
...(reclaimRunning ? { reclaimRunning: true } : {}),
|
|
2473
2571
|
...(forceRefresh ? { forceRefresh: true } : {}),
|
|
2474
2572
|
...(forceFailedRefresh ? { forceFailedRefresh: true } : {}),
|
|
2475
|
-
})
|
|
2476
|
-
)
|
|
2573
|
+
});
|
|
2574
|
+
})
|
|
2477
2575
|
: await Promise.all(
|
|
2478
2576
|
uniqueKeys.map((key) =>
|
|
2479
2577
|
this.claimRuntimeStepReceipt(
|
|
@@ -8286,7 +8384,7 @@ export class PlayContextImpl {
|
|
|
8286
8384
|
executionAuthScopeDigest: owner.executionAuthScopeDigest,
|
|
8287
8385
|
receiptLeaseExpiresAt: owner.receiptLeaseExpiresAt,
|
|
8288
8386
|
heartbeatReceipt: () =>
|
|
8289
|
-
this.
|
|
8387
|
+
this.renewRuntimeToolReceiptOwnership([owner]),
|
|
8290
8388
|
providerIdempotencyKey:
|
|
8291
8389
|
this.providerIdempotencyKeyForToolCall({
|
|
8292
8390
|
cacheKey: owner.cacheKey,
|
|
@@ -8563,7 +8661,7 @@ export class PlayContextImpl {
|
|
|
8563
8661
|
batch.memberRequests,
|
|
8564
8662
|
),
|
|
8565
8663
|
heartbeatReceipt: () =>
|
|
8566
|
-
this.
|
|
8664
|
+
this.renewRuntimeToolReceiptOwnership(
|
|
8567
8665
|
batch.memberRequests,
|
|
8568
8666
|
),
|
|
8569
8667
|
},
|
|
@@ -8726,7 +8824,7 @@ export class PlayContextImpl {
|
|
|
8726
8824
|
}),
|
|
8727
8825
|
receiptLeaseExpiresAt: request.receiptLeaseExpiresAt,
|
|
8728
8826
|
heartbeatReceipt: () =>
|
|
8729
|
-
this.
|
|
8827
|
+
this.renewRuntimeToolReceiptOwnership([request]),
|
|
8730
8828
|
}
|
|
8731
8829
|
: {}),
|
|
8732
8830
|
timeoutMs: resolveRuntimeTimeoutMsForClaimedOwners([
|
package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts
CHANGED
|
@@ -1,33 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Image,
|
|
3
|
-
type CreateSandboxFromImageParams,
|
|
4
|
-
type Daytona,
|
|
5
|
-
} from '@daytonaio/sdk';
|
|
6
|
-
import { DAYTONA_DEFAULT_WORKDIR } from '@shared_libs/play-runtime/daytona-runtime-config';
|
|
1
|
+
import { type Daytona } from '@daytonaio/sdk';
|
|
7
2
|
import type {
|
|
8
3
|
PlayRunnerExecutionConfig,
|
|
9
4
|
PlayRunnerResult,
|
|
10
5
|
} from '@shared_libs/play-runtime/protocol';
|
|
11
6
|
import { isIsolatedRuntimeSchedulerSchema } from '@shared_libs/play-runtime/runtime-scheduler-topology';
|
|
12
7
|
import { PLAY_RUNNER_TIMEOUT_SECONDS } from '@shared_libs/play-runtime/runtime-constants';
|
|
13
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS,
|
|
10
|
+
validatePlaySandboxRuntimeLimits,
|
|
11
|
+
} from '@shared_libs/play-runtime/sandbox-runtime-limits';
|
|
14
12
|
|
|
15
13
|
const DAYTONA_CREATE_TIMEOUT_SECONDS = 10;
|
|
16
|
-
const DAYTONA_CUSTOM_RESOURCE_CREATE_TIMEOUT_SECONDS = 120;
|
|
17
14
|
const DAYTONA_CREATE_RETRY_DELAYS_MS = [0, 500, 1_500] as const;
|
|
18
15
|
// Explicit runner deadline + scheduler GC own the normal lifecycle. Daytona's
|
|
19
16
|
// inactivity stop is a wider crash backstop measured from sandbox creation, so
|
|
20
17
|
// setup time cannot consume the terminal-flush grace.
|
|
21
18
|
const DAYTONA_AUTO_ARCHIVE_INTERVAL_MINUTES = 15;
|
|
22
19
|
const DAYTONA_SANDBOX_LABEL_SOURCE = 'deepline-play-runner';
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
export const
|
|
29
|
-
|
|
30
|
-
export const DAYTONA_SANDBOX_DISK_GIB = 3;
|
|
20
|
+
// Daytona's Deepline-managed default snapshot is the only admitted prebuilt.
|
|
21
|
+
// Resources are verified during acquisition, before customer code or billing.
|
|
22
|
+
export const DAYTONA_SANDBOX_CPU = STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS.cpu;
|
|
23
|
+
export const DAYTONA_SANDBOX_MEMORY_GIB =
|
|
24
|
+
STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS.memoryGiB;
|
|
25
|
+
export const DAYTONA_SANDBOX_DISK_GIB =
|
|
26
|
+
STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS.diskGiB;
|
|
31
27
|
export const DAYTONA_SANDBOX_GPU = 0;
|
|
32
28
|
const DAYTONA_NETWORK_ALLOW_LIST_ENV = 'DEEPLINE_DAYTONA_NETWORK_ALLOW_LIST';
|
|
33
29
|
|
|
@@ -182,15 +178,10 @@ async function createOneShotDaytonaSandbox(input: {
|
|
|
182
178
|
orgId: string;
|
|
183
179
|
context: DaytonaExecutionContext;
|
|
184
180
|
}): Promise<DaytonaSandbox> {
|
|
185
|
-
const limits =
|
|
186
|
-
input.context.sandboxRuntimeLimits
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
memory: `${input.context.sandboxRuntimeLimits.memoryGiB}GiB`,
|
|
190
|
-
cpu: input.context.sandboxRuntimeLimits.cpu,
|
|
191
|
-
disk: `${input.context.sandboxRuntimeLimits.diskGiB}GiB`,
|
|
192
|
-
}
|
|
193
|
-
: null,
|
|
181
|
+
const limits = validatePlaySandboxRuntimeLimits(
|
|
182
|
+
input.context.sandboxRuntimeLimits ?? {
|
|
183
|
+
...STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS,
|
|
184
|
+
},
|
|
194
185
|
);
|
|
195
186
|
const orgId = normalizeLabelValue(input.orgId);
|
|
196
187
|
const workflowId = normalizeLabelValue(input.context.workflowId);
|
|
@@ -213,10 +204,6 @@ async function createOneShotDaytonaSandbox(input: {
|
|
|
213
204
|
runtimeSchedulerSchema: input.context.runtimeSchedulerSchema ?? null,
|
|
214
205
|
});
|
|
215
206
|
|
|
216
|
-
const hasCustomResources =
|
|
217
|
-
limits.cpu !== DAYTONA_SANDBOX_CPU ||
|
|
218
|
-
limits.memoryGiB !== DAYTONA_SANDBOX_MEMORY_GIB ||
|
|
219
|
-
limits.diskGiB !== DAYTONA_SANDBOX_DISK_GIB;
|
|
220
207
|
const commonParams = {
|
|
221
208
|
labels,
|
|
222
209
|
ephemeral: true,
|
|
@@ -232,25 +219,6 @@ async function createOneShotDaytonaSandbox(input: {
|
|
|
232
219
|
// contradictory flag.
|
|
233
220
|
...(networkAllowList ? { networkAllowList } : {}),
|
|
234
221
|
};
|
|
235
|
-
if (hasCustomResources) {
|
|
236
|
-
// Daytona fixes resources into snapshots and rejects a resources field on
|
|
237
|
-
// snapshot/default-image creates. Its supported custom-resource path
|
|
238
|
-
// builds from an OCI image and applies CPU, memory, and disk at creation.
|
|
239
|
-
const createParams: CreateSandboxFromImageParams = {
|
|
240
|
-
...commonParams,
|
|
241
|
-
image: DAYTONA_CUSTOM_RESOURCE_IMAGE,
|
|
242
|
-
resources: {
|
|
243
|
-
cpu: limits.cpu,
|
|
244
|
-
memory: limits.memoryGiB,
|
|
245
|
-
disk: limits.diskGiB,
|
|
246
|
-
},
|
|
247
|
-
};
|
|
248
|
-
return input.daytona.create(createParams, {
|
|
249
|
-
timeout: DAYTONA_CUSTOM_RESOURCE_CREATE_TIMEOUT_SECONDS,
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
// Keep the fast default snapshot for standard resources, including plays
|
|
253
|
-
// that override timeout only.
|
|
254
222
|
return input.daytona.create(commonParams, {
|
|
255
223
|
timeout: DAYTONA_CREATE_TIMEOUT_SECONDS,
|
|
256
224
|
});
|
|
@@ -316,15 +284,10 @@ async function acquireOneShotDaytonaSandbox(input: {
|
|
|
316
284
|
emitStage: DaytonaStageEmitter;
|
|
317
285
|
startedAt: number;
|
|
318
286
|
}): Promise<AcquiredDaytonaSandbox> {
|
|
319
|
-
const limits =
|
|
320
|
-
input.context.sandboxRuntimeLimits
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
memory: `${input.context.sandboxRuntimeLimits.memoryGiB}GiB`,
|
|
324
|
-
cpu: input.context.sandboxRuntimeLimits.cpu,
|
|
325
|
-
disk: `${input.context.sandboxRuntimeLimits.diskGiB}GiB`,
|
|
326
|
-
}
|
|
327
|
-
: null,
|
|
287
|
+
const limits = validatePlaySandboxRuntimeLimits(
|
|
288
|
+
input.context.sandboxRuntimeLimits ?? {
|
|
289
|
+
...STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS,
|
|
290
|
+
},
|
|
328
291
|
);
|
|
329
292
|
input.emitStage('create:start');
|
|
330
293
|
const result = await createRetriedOneShotDaytonaSandbox(input);
|
|
@@ -334,42 +297,6 @@ async function acquireOneShotDaytonaSandbox(input: {
|
|
|
334
297
|
diskGiB: result.sandbox.disk,
|
|
335
298
|
gpu: result.sandbox.gpu ?? 0,
|
|
336
299
|
};
|
|
337
|
-
// Compatibility fallback for Daytona targets that ignore create-time
|
|
338
|
-
// resources but still support resize. The hosted target should normally
|
|
339
|
-
// match immediately; either path is verified before code or billing starts.
|
|
340
|
-
if (
|
|
341
|
-
typeof result.sandbox.resize === 'function' &&
|
|
342
|
-
(granted.cpu !== limits.cpu ||
|
|
343
|
-
granted.memoryGiB !== limits.memoryGiB ||
|
|
344
|
-
granted.diskGiB !== limits.diskGiB)
|
|
345
|
-
) {
|
|
346
|
-
try {
|
|
347
|
-
if (granted.diskGiB !== limits.diskGiB) {
|
|
348
|
-
await result.sandbox.stop(60);
|
|
349
|
-
await result.sandbox.resize({
|
|
350
|
-
cpu: limits.cpu,
|
|
351
|
-
memory: limits.memoryGiB,
|
|
352
|
-
disk: limits.diskGiB,
|
|
353
|
-
});
|
|
354
|
-
await result.sandbox.start(60);
|
|
355
|
-
} else {
|
|
356
|
-
await result.sandbox.resize({
|
|
357
|
-
cpu: limits.cpu,
|
|
358
|
-
memory: limits.memoryGiB,
|
|
359
|
-
disk: limits.diskGiB,
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
} catch (error) {
|
|
363
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
364
|
-
return await rejectAcquiredSandbox(
|
|
365
|
-
result.sandbox,
|
|
366
|
-
`Daytona sandbox resize failed before execution: ${message}.`,
|
|
367
|
-
);
|
|
368
|
-
}
|
|
369
|
-
granted.cpu = result.sandbox.cpu;
|
|
370
|
-
granted.memoryGiB = result.sandbox.memory;
|
|
371
|
-
granted.diskGiB = result.sandbox.disk;
|
|
372
|
-
}
|
|
373
300
|
if (
|
|
374
301
|
granted.cpu !== limits.cpu ||
|
|
375
302
|
granted.memoryGiB !== limits.memoryGiB ||
|
|
@@ -5,36 +5,38 @@ export type PlaySandboxRuntimeLimits = {
|
|
|
5
5
|
diskGiB: number;
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
+
export type PlaySandboxSize = 'standard';
|
|
9
|
+
|
|
10
|
+
export const PLAY_SANDBOX_SIZE_LIMITS = {
|
|
11
|
+
standard: {
|
|
12
|
+
memoryGiB: 1,
|
|
13
|
+
cpu: 1,
|
|
14
|
+
diskGiB: 3,
|
|
15
|
+
},
|
|
16
|
+
} as const satisfies Record<
|
|
17
|
+
PlaySandboxSize,
|
|
18
|
+
Omit<PlaySandboxRuntimeLimits, 'timeoutSeconds'>
|
|
19
|
+
>;
|
|
20
|
+
|
|
8
21
|
export const STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS: PlaySandboxRuntimeLimits = {
|
|
9
22
|
timeoutSeconds: 30 * 60,
|
|
10
|
-
|
|
11
|
-
cpu: 1,
|
|
12
|
-
diskGiB: 3,
|
|
23
|
+
...PLAY_SANDBOX_SIZE_LIMITS.standard,
|
|
13
24
|
};
|
|
14
25
|
|
|
15
26
|
// Product-wide ceilings. Organisation entitlements may lower these, but a
|
|
16
27
|
// customer-authored Play can never ask Daytona for an unbounded resource.
|
|
17
28
|
export const MAX_PLAY_SANDBOX_RUNTIME_LIMITS: PlaySandboxRuntimeLimits = {
|
|
18
29
|
timeoutSeconds: 4 * 60 * 60,
|
|
19
|
-
memoryGiB:
|
|
20
|
-
cpu:
|
|
21
|
-
diskGiB:
|
|
30
|
+
memoryGiB: STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS.memoryGiB,
|
|
31
|
+
cpu: STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS.cpu,
|
|
32
|
+
diskGiB: STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS.diskGiB,
|
|
22
33
|
};
|
|
23
34
|
|
|
24
35
|
export type PlaySandboxRuntimeDeclaration = {
|
|
25
36
|
timeout?: string;
|
|
26
|
-
|
|
27
|
-
cpu?: number;
|
|
28
|
-
disk?: string;
|
|
37
|
+
size?: PlaySandboxSize;
|
|
29
38
|
};
|
|
30
39
|
|
|
31
|
-
function parsePositiveInteger(value: string, unit: string): number | null {
|
|
32
|
-
const match = new RegExp(`^(\\d+)\\s*${unit}$`, 'i').exec(value.trim());
|
|
33
|
-
if (!match) return null;
|
|
34
|
-
const parsed = Number(match[1]);
|
|
35
|
-
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
40
|
function parseTimeout(value: string): number | null {
|
|
39
41
|
const match = /^(\d+)\s*([mh])$/i.exec(value.trim());
|
|
40
42
|
if (!match) return null;
|
|
@@ -43,60 +45,65 @@ function parseTimeout(value: string): number | null {
|
|
|
43
45
|
return amount * (match[2].toLowerCase() === 'h' ? 3600 : 60);
|
|
44
46
|
}
|
|
45
47
|
|
|
46
|
-
export function
|
|
47
|
-
|
|
48
|
+
export function validatePlaySandboxRuntimeLimits(
|
|
49
|
+
value: PlaySandboxRuntimeLimits,
|
|
48
50
|
): PlaySandboxRuntimeLimits {
|
|
49
51
|
const base = STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS;
|
|
50
|
-
if (!declaration) return { ...base };
|
|
51
|
-
const timeoutSeconds = declaration.timeout
|
|
52
|
-
? parseTimeout(declaration.timeout)
|
|
53
|
-
: base.timeoutSeconds;
|
|
54
|
-
const memoryGiB = declaration.memory
|
|
55
|
-
? parsePositiveInteger(declaration.memory, 'GiB')
|
|
56
|
-
: base.memoryGiB;
|
|
57
|
-
const diskGiB = declaration.disk
|
|
58
|
-
? parsePositiveInteger(declaration.disk, 'GiB')
|
|
59
|
-
: base.diskGiB;
|
|
60
|
-
const cpu = declaration.cpu ?? base.cpu;
|
|
61
|
-
if (
|
|
62
|
-
timeoutSeconds === null ||
|
|
63
|
-
memoryGiB === null ||
|
|
64
|
-
diskGiB === null ||
|
|
65
|
-
!Number.isSafeInteger(cpu) ||
|
|
66
|
-
cpu <= 0
|
|
67
|
-
) {
|
|
68
|
-
throw new Error(
|
|
69
|
-
'Invalid runtime sandbox declaration. Use timeout like "90m" or "2h", memory/disk like "4GiB", and a positive integer cpu.',
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
const resolved = { timeoutSeconds, memoryGiB, cpu, diskGiB };
|
|
73
52
|
for (const key of ['memoryGiB', 'cpu', 'diskGiB'] as const) {
|
|
74
|
-
if (
|
|
53
|
+
if (value[key] !== base[key]) {
|
|
75
54
|
throw new Error(
|
|
76
|
-
`
|
|
55
|
+
`Unsupported runtime sandbox resources: ${key}=${value[key]}. ` +
|
|
56
|
+
`Use runtime.size with a Deepline prebuilt sandbox. Supported sizes: "standard" ` +
|
|
57
|
+
`(${base.cpu} CPU, ${base.memoryGiB}GiB memory, ${base.diskGiB}GiB disk).`,
|
|
77
58
|
);
|
|
78
59
|
}
|
|
79
60
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
61
|
+
if (
|
|
62
|
+
!Number.isSafeInteger(value.timeoutSeconds) ||
|
|
63
|
+
value.timeoutSeconds <= 0
|
|
64
|
+
) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
'Invalid runtime sandbox timeout. Use timeout like "90m" or "2h".',
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
if (value.timeoutSeconds > MAX_PLAY_SANDBOX_RUNTIME_LIMITS.timeoutSeconds) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
`Requested runtime timeoutSeconds=${value.timeoutSeconds} exceeds this organisation's maximum ${MAX_PLAY_SANDBOX_RUNTIME_LIMITS.timeoutSeconds}.`,
|
|
72
|
+
);
|
|
88
73
|
}
|
|
89
|
-
return
|
|
74
|
+
return { ...value };
|
|
90
75
|
}
|
|
91
76
|
|
|
92
|
-
export function
|
|
93
|
-
|
|
94
|
-
):
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
key as keyof PlaySandboxRuntimeLimits
|
|
100
|
-
],
|
|
77
|
+
export function resolvePlaySandboxRuntimeLimits(
|
|
78
|
+
declaration: PlaySandboxRuntimeDeclaration | null | undefined,
|
|
79
|
+
): PlaySandboxRuntimeLimits {
|
|
80
|
+
const base = STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS;
|
|
81
|
+
if (!declaration) return { ...base };
|
|
82
|
+
const unsupportedProperties = Object.keys(declaration).filter(
|
|
83
|
+
(key) => key !== 'timeout' && key !== 'size',
|
|
101
84
|
);
|
|
85
|
+
if (unsupportedProperties.length > 0) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`Unsupported runtime sandbox option${unsupportedProperties.length === 1 ? '' : 's'}: ${unsupportedProperties.join(', ')}. ` +
|
|
88
|
+
'Use runtime.size with a Deepline prebuilt sandbox. Supported sizes: "standard".',
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
if (declaration.size !== undefined && declaration.size !== 'standard') {
|
|
92
|
+
throw new Error(
|
|
93
|
+
`Unsupported runtime sandbox size "${String(declaration.size)}". Supported sizes: "standard".`,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
const timeoutSeconds = declaration.timeout
|
|
97
|
+
? parseTimeout(declaration.timeout)
|
|
98
|
+
: base.timeoutSeconds;
|
|
99
|
+
if (timeoutSeconds === null) {
|
|
100
|
+
throw new Error(
|
|
101
|
+
'Invalid runtime sandbox timeout. Use timeout like "90m" or "2h".',
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
const size = declaration.size ?? 'standard';
|
|
105
|
+
return validatePlaySandboxRuntimeLimits({
|
|
106
|
+
timeoutSeconds,
|
|
107
|
+
...PLAY_SANDBOX_SIZE_LIMITS[size],
|
|
108
|
+
});
|
|
102
109
|
}
|
|
@@ -887,6 +887,35 @@ function resolveStaticProperty(
|
|
|
887
887
|
return resolution;
|
|
888
888
|
}
|
|
889
889
|
|
|
890
|
+
function staticPropertyNames(
|
|
891
|
+
node: AstNode | null | undefined,
|
|
892
|
+
context: PlayMetadataExtractionContext,
|
|
893
|
+
ancestors = new Set<AstNode>(),
|
|
894
|
+
): Set<string> | null {
|
|
895
|
+
if (!node) return new Set();
|
|
896
|
+
const object = objectExpressionFromNode(node, context);
|
|
897
|
+
if (!object || ancestors.has(object)) return null;
|
|
898
|
+
const nextAncestors = new Set(ancestors).add(object);
|
|
899
|
+
const names = new Set<string>();
|
|
900
|
+
for (const property of astArray(object.properties)) {
|
|
901
|
+
if (property.type === 'SpreadElement') {
|
|
902
|
+
const spreadNames = staticPropertyNames(
|
|
903
|
+
isAstNode(property.argument) ? property.argument : null,
|
|
904
|
+
context,
|
|
905
|
+
nextAncestors,
|
|
906
|
+
);
|
|
907
|
+
if (!spreadNames) return null;
|
|
908
|
+
for (const name of spreadNames) names.add(name);
|
|
909
|
+
continue;
|
|
910
|
+
}
|
|
911
|
+
if (property.type !== 'Property') return null;
|
|
912
|
+
const name = propertyNameFromKey(property);
|
|
913
|
+
if (name === null) return null;
|
|
914
|
+
names.add(name);
|
|
915
|
+
}
|
|
916
|
+
return names;
|
|
917
|
+
}
|
|
918
|
+
|
|
890
919
|
function staticNumberFromExpression(
|
|
891
920
|
node: AstNode | null | undefined,
|
|
892
921
|
context: PlayMetadataExtractionContext,
|
|
@@ -957,30 +986,30 @@ function sandboxRuntimeDeclarationFromOptions(
|
|
|
957
986
|
directRuntime.kind === 'found' ? directRuntime : bindingRuntime;
|
|
958
987
|
if (runtime.kind !== 'found') return null;
|
|
959
988
|
|
|
989
|
+
const propertyNames = staticPropertyNames(runtime.value, context);
|
|
990
|
+
const unsupportedProperties = propertyNames
|
|
991
|
+
? [...propertyNames].filter(
|
|
992
|
+
(propertyName) => propertyName !== 'timeout' && propertyName !== 'size',
|
|
993
|
+
)
|
|
994
|
+
: [];
|
|
995
|
+
if (unsupportedProperties.length > 0) {
|
|
996
|
+
throw new Error(
|
|
997
|
+
`Unsupported runtime sandbox option${unsupportedProperties.length === 1 ? '' : 's'} "${unsupportedProperties.join('", "')}". ` +
|
|
998
|
+
'Use runtime.size with a Deepline prebuilt sandbox. Supported sizes: "standard".',
|
|
999
|
+
);
|
|
1000
|
+
}
|
|
960
1001
|
const timeout = resolveStaticProperty(runtime.value, 'timeout', context);
|
|
961
|
-
const
|
|
962
|
-
const cpu = resolveStaticProperty(runtime.value, 'cpu', context);
|
|
963
|
-
const disk = resolveStaticProperty(runtime.value, 'disk', context);
|
|
1002
|
+
const size = resolveStaticProperty(runtime.value, 'size', context);
|
|
964
1003
|
const declaration: PlaySandboxRuntimeDeclaration = {};
|
|
965
1004
|
if (timeout.kind === 'found') {
|
|
966
1005
|
const value = staticStringFromExpression(timeout.value, context);
|
|
967
1006
|
if (value === null) return null;
|
|
968
1007
|
declaration.timeout = value;
|
|
969
1008
|
}
|
|
970
|
-
if (
|
|
971
|
-
const value = staticStringFromExpression(
|
|
972
|
-
if (value === null) return null;
|
|
973
|
-
declaration.memory = value;
|
|
974
|
-
}
|
|
975
|
-
if (cpu.kind === 'found') {
|
|
976
|
-
const value = staticNumberFromExpression(cpu.value, context);
|
|
977
|
-
if (value === null) return null;
|
|
978
|
-
declaration.cpu = value;
|
|
979
|
-
}
|
|
980
|
-
if (disk.kind === 'found') {
|
|
981
|
-
const value = staticStringFromExpression(disk.value, context);
|
|
1009
|
+
if (size.kind === 'found') {
|
|
1010
|
+
const value = staticStringFromExpression(size.value, context);
|
|
982
1011
|
if (value === null) return null;
|
|
983
|
-
declaration.
|
|
1012
|
+
declaration.size = value as PlaySandboxRuntimeDeclaration['size'];
|
|
984
1013
|
}
|
|
985
1014
|
return declaration;
|
|
986
1015
|
}
|
|
@@ -1596,8 +1625,7 @@ async function analyzeSourceGraph(
|
|
|
1596
1625
|
}
|
|
1597
1626
|
const playName = metadata?.name ?? null;
|
|
1598
1627
|
const playDescription = metadata?.description ?? null;
|
|
1599
|
-
const sandboxRuntimeDeclaration =
|
|
1600
|
-
metadata?.sandboxRuntimeDeclaration ?? null;
|
|
1628
|
+
const sandboxRuntimeDeclaration = metadata?.sandboxRuntimeDeclaration ?? null;
|
|
1601
1629
|
|
|
1602
1630
|
return {
|
|
1603
1631
|
sourceCode,
|
package/dist/cli/index.js
CHANGED
|
@@ -1037,7 +1037,7 @@ var SDK_RELEASE = {
|
|
|
1037
1037
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
1038
1038
|
// 0.1.254 removes the internal operations tree from the published SDK CLI.
|
|
1039
1039
|
// Operators use the checkout-local deepline-admin binary instead.
|
|
1040
|
-
version: "0.1.
|
|
1040
|
+
version: "0.1.314",
|
|
1041
1041
|
contracts: {
|
|
1042
1042
|
api: {
|
|
1043
1043
|
name: "sdk-http-api",
|
|
@@ -12143,24 +12143,23 @@ function resolveEnabledExecutionProfile(override) {
|
|
|
12143
12143
|
}
|
|
12144
12144
|
|
|
12145
12145
|
// ../shared_libs/play-runtime/sandbox-runtime-limits.ts
|
|
12146
|
+
var PLAY_SANDBOX_SIZE_LIMITS = {
|
|
12147
|
+
standard: {
|
|
12148
|
+
memoryGiB: 1,
|
|
12149
|
+
cpu: 1,
|
|
12150
|
+
diskGiB: 3
|
|
12151
|
+
}
|
|
12152
|
+
};
|
|
12146
12153
|
var STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS = {
|
|
12147
12154
|
timeoutSeconds: 30 * 60,
|
|
12148
|
-
|
|
12149
|
-
cpu: 1,
|
|
12150
|
-
diskGiB: 3
|
|
12155
|
+
...PLAY_SANDBOX_SIZE_LIMITS.standard
|
|
12151
12156
|
};
|
|
12152
12157
|
var MAX_PLAY_SANDBOX_RUNTIME_LIMITS = {
|
|
12153
12158
|
timeoutSeconds: 4 * 60 * 60,
|
|
12154
|
-
memoryGiB:
|
|
12155
|
-
cpu:
|
|
12156
|
-
diskGiB:
|
|
12159
|
+
memoryGiB: STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS.memoryGiB,
|
|
12160
|
+
cpu: STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS.cpu,
|
|
12161
|
+
diskGiB: STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS.diskGiB
|
|
12157
12162
|
};
|
|
12158
|
-
function parsePositiveInteger3(value, unit) {
|
|
12159
|
-
const match = new RegExp(`^(\\d+)\\s*${unit}$`, "i").exec(value.trim());
|
|
12160
|
-
if (!match) return null;
|
|
12161
|
-
const parsed = Number(match[1]);
|
|
12162
|
-
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;
|
|
12163
|
-
}
|
|
12164
12163
|
function parseTimeout(value) {
|
|
12165
12164
|
const match = /^(\d+)\s*([mh])$/i.exec(value.trim());
|
|
12166
12165
|
if (!match) return null;
|
|
@@ -12168,41 +12167,54 @@ function parseTimeout(value) {
|
|
|
12168
12167
|
if (!Number.isSafeInteger(amount) || amount <= 0) return null;
|
|
12169
12168
|
return amount * (match[2].toLowerCase() === "h" ? 3600 : 60);
|
|
12170
12169
|
}
|
|
12171
|
-
function
|
|
12170
|
+
function validatePlaySandboxRuntimeLimits(value) {
|
|
12172
12171
|
const base = STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS;
|
|
12173
|
-
if (!declaration) return { ...base };
|
|
12174
|
-
const timeoutSeconds = declaration.timeout ? parseTimeout(declaration.timeout) : base.timeoutSeconds;
|
|
12175
|
-
const memoryGiB = declaration.memory ? parsePositiveInteger3(declaration.memory, "GiB") : base.memoryGiB;
|
|
12176
|
-
const diskGiB = declaration.disk ? parsePositiveInteger3(declaration.disk, "GiB") : base.diskGiB;
|
|
12177
|
-
const cpu = declaration.cpu ?? base.cpu;
|
|
12178
|
-
if (timeoutSeconds === null || memoryGiB === null || diskGiB === null || !Number.isSafeInteger(cpu) || cpu <= 0) {
|
|
12179
|
-
throw new Error(
|
|
12180
|
-
'Invalid runtime sandbox declaration. Use timeout like "90m" or "2h", memory/disk like "4GiB", and a positive integer cpu.'
|
|
12181
|
-
);
|
|
12182
|
-
}
|
|
12183
|
-
const resolved = { timeoutSeconds, memoryGiB, cpu, diskGiB };
|
|
12184
12172
|
for (const key of ["memoryGiB", "cpu", "diskGiB"]) {
|
|
12185
|
-
if (
|
|
12173
|
+
if (value[key] !== base[key]) {
|
|
12186
12174
|
throw new Error(
|
|
12187
|
-
`
|
|
12175
|
+
`Unsupported runtime sandbox resources: ${key}=${value[key]}. Use runtime.size with a Deepline prebuilt sandbox. Supported sizes: "standard" (${base.cpu} CPU, ${base.memoryGiB}GiB memory, ${base.diskGiB}GiB disk).`
|
|
12188
12176
|
);
|
|
12189
12177
|
}
|
|
12190
12178
|
}
|
|
12191
|
-
|
|
12192
|
-
|
|
12193
|
-
|
|
12194
|
-
|
|
12195
|
-
throw new Error(
|
|
12196
|
-
`Requested runtime ${key}=${resolved[key]} exceeds this organisation's maximum ${MAX_PLAY_SANDBOX_RUNTIME_LIMITS[key]}.`
|
|
12197
|
-
);
|
|
12198
|
-
}
|
|
12179
|
+
if (!Number.isSafeInteger(value.timeoutSeconds) || value.timeoutSeconds <= 0) {
|
|
12180
|
+
throw new Error(
|
|
12181
|
+
'Invalid runtime sandbox timeout. Use timeout like "90m" or "2h".'
|
|
12182
|
+
);
|
|
12199
12183
|
}
|
|
12200
|
-
|
|
12184
|
+
if (value.timeoutSeconds > MAX_PLAY_SANDBOX_RUNTIME_LIMITS.timeoutSeconds) {
|
|
12185
|
+
throw new Error(
|
|
12186
|
+
`Requested runtime timeoutSeconds=${value.timeoutSeconds} exceeds this organisation's maximum ${MAX_PLAY_SANDBOX_RUNTIME_LIMITS.timeoutSeconds}.`
|
|
12187
|
+
);
|
|
12188
|
+
}
|
|
12189
|
+
return { ...value };
|
|
12201
12190
|
}
|
|
12202
|
-
function
|
|
12203
|
-
|
|
12204
|
-
|
|
12191
|
+
function resolvePlaySandboxRuntimeLimits(declaration) {
|
|
12192
|
+
const base = STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS;
|
|
12193
|
+
if (!declaration) return { ...base };
|
|
12194
|
+
const unsupportedProperties = Object.keys(declaration).filter(
|
|
12195
|
+
(key) => key !== "timeout" && key !== "size"
|
|
12205
12196
|
);
|
|
12197
|
+
if (unsupportedProperties.length > 0) {
|
|
12198
|
+
throw new Error(
|
|
12199
|
+
`Unsupported runtime sandbox option${unsupportedProperties.length === 1 ? "" : "s"}: ${unsupportedProperties.join(", ")}. Use runtime.size with a Deepline prebuilt sandbox. Supported sizes: "standard".`
|
|
12200
|
+
);
|
|
12201
|
+
}
|
|
12202
|
+
if (declaration.size !== void 0 && declaration.size !== "standard") {
|
|
12203
|
+
throw new Error(
|
|
12204
|
+
`Unsupported runtime sandbox size "${String(declaration.size)}". Supported sizes: "standard".`
|
|
12205
|
+
);
|
|
12206
|
+
}
|
|
12207
|
+
const timeoutSeconds = declaration.timeout ? parseTimeout(declaration.timeout) : base.timeoutSeconds;
|
|
12208
|
+
if (timeoutSeconds === null) {
|
|
12209
|
+
throw new Error(
|
|
12210
|
+
'Invalid runtime sandbox timeout. Use timeout like "90m" or "2h".'
|
|
12211
|
+
);
|
|
12212
|
+
}
|
|
12213
|
+
const size = declaration.size ?? "standard";
|
|
12214
|
+
return validatePlaySandboxRuntimeLimits({
|
|
12215
|
+
timeoutSeconds,
|
|
12216
|
+
...PLAY_SANDBOX_SIZE_LIMITS[size]
|
|
12217
|
+
});
|
|
12206
12218
|
}
|
|
12207
12219
|
|
|
12208
12220
|
// ../shared_libs/play-runtime/worker-api-types.ts
|
|
@@ -12265,9 +12277,11 @@ function estimateDaytonaMaximumComputeCredits(limits) {
|
|
|
12265
12277
|
);
|
|
12266
12278
|
}
|
|
12267
12279
|
function formatNonStandardSandboxRuntimeWarning(limits) {
|
|
12268
|
-
if (
|
|
12280
|
+
if (limits.timeoutSeconds <= STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS.timeoutSeconds) {
|
|
12281
|
+
return null;
|
|
12282
|
+
}
|
|
12269
12283
|
const maximumComputeCredits = estimateDaytonaMaximumComputeCredits(limits);
|
|
12270
|
-
return `This Play requests
|
|
12284
|
+
return `This Play requests the standard sandbox for up to ${limits.timeoutSeconds}s (${limits.memoryGiB}GiB memory, ${limits.cpu} CPU, ${limits.diskGiB}GiB disk). Maximum compute estimate: ${maximumComputeCredits.toFixed(2)} Deepline credits. Longer runtimes are risky.`;
|
|
12271
12285
|
}
|
|
12272
12286
|
|
|
12273
12287
|
// ../shared_libs/play-runtime/internal-step-ids.ts
|
|
@@ -12829,7 +12843,7 @@ function looksLikeFilePath(target) {
|
|
|
12829
12843
|
}
|
|
12830
12844
|
return target.includes("\\") || /\.(ts|js|mjs|play\.ts)$/.test(target);
|
|
12831
12845
|
}
|
|
12832
|
-
function
|
|
12846
|
+
function parsePositiveInteger3(value, flagName) {
|
|
12833
12847
|
const parsed = Number.parseInt(value, 10);
|
|
12834
12848
|
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
12835
12849
|
throw new Error(`${flagName} must be a positive integer.`);
|
|
@@ -16349,7 +16363,7 @@ function parsePlayRunOptions(args) {
|
|
|
16349
16363
|
);
|
|
16350
16364
|
}
|
|
16351
16365
|
if ((arg === "--tail-timeout-ms" || arg === "--timeout-ms") && args[index + 1]) {
|
|
16352
|
-
waitTimeoutMs =
|
|
16366
|
+
waitTimeoutMs = parsePositiveInteger3(args[++index], arg);
|
|
16353
16367
|
continue;
|
|
16354
16368
|
}
|
|
16355
16369
|
if (PLAY_RUN_RESERVED_BOOLEAN_FLAGS.has(arg)) {
|
|
@@ -17510,7 +17524,7 @@ async function handleRunLogs(args) {
|
|
|
17510
17524
|
for (let index = 0; index < args.length; index += 1) {
|
|
17511
17525
|
const arg = args[index];
|
|
17512
17526
|
if (arg === "--limit" && args[index + 1]) {
|
|
17513
|
-
limit =
|
|
17527
|
+
limit = parsePositiveInteger3(args[++index], "--limit");
|
|
17514
17528
|
continue;
|
|
17515
17529
|
}
|
|
17516
17530
|
if (arg === "--out" && args[index + 1]) {
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1022,7 +1022,7 @@ var SDK_RELEASE = {
|
|
|
1022
1022
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
1023
1023
|
// 0.1.254 removes the internal operations tree from the published SDK CLI.
|
|
1024
1024
|
// Operators use the checkout-local deepline-admin binary instead.
|
|
1025
|
-
version: "0.1.
|
|
1025
|
+
version: "0.1.314",
|
|
1026
1026
|
contracts: {
|
|
1027
1027
|
api: {
|
|
1028
1028
|
name: "sdk-http-api",
|
|
@@ -12172,24 +12172,23 @@ function resolveEnabledExecutionProfile(override) {
|
|
|
12172
12172
|
}
|
|
12173
12173
|
|
|
12174
12174
|
// ../shared_libs/play-runtime/sandbox-runtime-limits.ts
|
|
12175
|
+
var PLAY_SANDBOX_SIZE_LIMITS = {
|
|
12176
|
+
standard: {
|
|
12177
|
+
memoryGiB: 1,
|
|
12178
|
+
cpu: 1,
|
|
12179
|
+
diskGiB: 3
|
|
12180
|
+
}
|
|
12181
|
+
};
|
|
12175
12182
|
var STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS = {
|
|
12176
12183
|
timeoutSeconds: 30 * 60,
|
|
12177
|
-
|
|
12178
|
-
cpu: 1,
|
|
12179
|
-
diskGiB: 3
|
|
12184
|
+
...PLAY_SANDBOX_SIZE_LIMITS.standard
|
|
12180
12185
|
};
|
|
12181
12186
|
var MAX_PLAY_SANDBOX_RUNTIME_LIMITS = {
|
|
12182
12187
|
timeoutSeconds: 4 * 60 * 60,
|
|
12183
|
-
memoryGiB:
|
|
12184
|
-
cpu:
|
|
12185
|
-
diskGiB:
|
|
12188
|
+
memoryGiB: STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS.memoryGiB,
|
|
12189
|
+
cpu: STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS.cpu,
|
|
12190
|
+
diskGiB: STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS.diskGiB
|
|
12186
12191
|
};
|
|
12187
|
-
function parsePositiveInteger3(value, unit) {
|
|
12188
|
-
const match = new RegExp(`^(\\d+)\\s*${unit}$`, "i").exec(value.trim());
|
|
12189
|
-
if (!match) return null;
|
|
12190
|
-
const parsed = Number(match[1]);
|
|
12191
|
-
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;
|
|
12192
|
-
}
|
|
12193
12192
|
function parseTimeout(value) {
|
|
12194
12193
|
const match = /^(\d+)\s*([mh])$/i.exec(value.trim());
|
|
12195
12194
|
if (!match) return null;
|
|
@@ -12197,41 +12196,54 @@ function parseTimeout(value) {
|
|
|
12197
12196
|
if (!Number.isSafeInteger(amount) || amount <= 0) return null;
|
|
12198
12197
|
return amount * (match[2].toLowerCase() === "h" ? 3600 : 60);
|
|
12199
12198
|
}
|
|
12200
|
-
function
|
|
12199
|
+
function validatePlaySandboxRuntimeLimits(value) {
|
|
12201
12200
|
const base = STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS;
|
|
12202
|
-
if (!declaration) return { ...base };
|
|
12203
|
-
const timeoutSeconds = declaration.timeout ? parseTimeout(declaration.timeout) : base.timeoutSeconds;
|
|
12204
|
-
const memoryGiB = declaration.memory ? parsePositiveInteger3(declaration.memory, "GiB") : base.memoryGiB;
|
|
12205
|
-
const diskGiB = declaration.disk ? parsePositiveInteger3(declaration.disk, "GiB") : base.diskGiB;
|
|
12206
|
-
const cpu = declaration.cpu ?? base.cpu;
|
|
12207
|
-
if (timeoutSeconds === null || memoryGiB === null || diskGiB === null || !Number.isSafeInteger(cpu) || cpu <= 0) {
|
|
12208
|
-
throw new Error(
|
|
12209
|
-
'Invalid runtime sandbox declaration. Use timeout like "90m" or "2h", memory/disk like "4GiB", and a positive integer cpu.'
|
|
12210
|
-
);
|
|
12211
|
-
}
|
|
12212
|
-
const resolved = { timeoutSeconds, memoryGiB, cpu, diskGiB };
|
|
12213
12201
|
for (const key of ["memoryGiB", "cpu", "diskGiB"]) {
|
|
12214
|
-
if (
|
|
12202
|
+
if (value[key] !== base[key]) {
|
|
12215
12203
|
throw new Error(
|
|
12216
|
-
`
|
|
12204
|
+
`Unsupported runtime sandbox resources: ${key}=${value[key]}. Use runtime.size with a Deepline prebuilt sandbox. Supported sizes: "standard" (${base.cpu} CPU, ${base.memoryGiB}GiB memory, ${base.diskGiB}GiB disk).`
|
|
12217
12205
|
);
|
|
12218
12206
|
}
|
|
12219
12207
|
}
|
|
12220
|
-
|
|
12221
|
-
|
|
12222
|
-
|
|
12223
|
-
|
|
12224
|
-
throw new Error(
|
|
12225
|
-
`Requested runtime ${key}=${resolved[key]} exceeds this organisation's maximum ${MAX_PLAY_SANDBOX_RUNTIME_LIMITS[key]}.`
|
|
12226
|
-
);
|
|
12227
|
-
}
|
|
12208
|
+
if (!Number.isSafeInteger(value.timeoutSeconds) || value.timeoutSeconds <= 0) {
|
|
12209
|
+
throw new Error(
|
|
12210
|
+
'Invalid runtime sandbox timeout. Use timeout like "90m" or "2h".'
|
|
12211
|
+
);
|
|
12228
12212
|
}
|
|
12229
|
-
|
|
12213
|
+
if (value.timeoutSeconds > MAX_PLAY_SANDBOX_RUNTIME_LIMITS.timeoutSeconds) {
|
|
12214
|
+
throw new Error(
|
|
12215
|
+
`Requested runtime timeoutSeconds=${value.timeoutSeconds} exceeds this organisation's maximum ${MAX_PLAY_SANDBOX_RUNTIME_LIMITS.timeoutSeconds}.`
|
|
12216
|
+
);
|
|
12217
|
+
}
|
|
12218
|
+
return { ...value };
|
|
12230
12219
|
}
|
|
12231
|
-
function
|
|
12232
|
-
|
|
12233
|
-
|
|
12220
|
+
function resolvePlaySandboxRuntimeLimits(declaration) {
|
|
12221
|
+
const base = STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS;
|
|
12222
|
+
if (!declaration) return { ...base };
|
|
12223
|
+
const unsupportedProperties = Object.keys(declaration).filter(
|
|
12224
|
+
(key) => key !== "timeout" && key !== "size"
|
|
12234
12225
|
);
|
|
12226
|
+
if (unsupportedProperties.length > 0) {
|
|
12227
|
+
throw new Error(
|
|
12228
|
+
`Unsupported runtime sandbox option${unsupportedProperties.length === 1 ? "" : "s"}: ${unsupportedProperties.join(", ")}. Use runtime.size with a Deepline prebuilt sandbox. Supported sizes: "standard".`
|
|
12229
|
+
);
|
|
12230
|
+
}
|
|
12231
|
+
if (declaration.size !== void 0 && declaration.size !== "standard") {
|
|
12232
|
+
throw new Error(
|
|
12233
|
+
`Unsupported runtime sandbox size "${String(declaration.size)}". Supported sizes: "standard".`
|
|
12234
|
+
);
|
|
12235
|
+
}
|
|
12236
|
+
const timeoutSeconds = declaration.timeout ? parseTimeout(declaration.timeout) : base.timeoutSeconds;
|
|
12237
|
+
if (timeoutSeconds === null) {
|
|
12238
|
+
throw new Error(
|
|
12239
|
+
'Invalid runtime sandbox timeout. Use timeout like "90m" or "2h".'
|
|
12240
|
+
);
|
|
12241
|
+
}
|
|
12242
|
+
const size = declaration.size ?? "standard";
|
|
12243
|
+
return validatePlaySandboxRuntimeLimits({
|
|
12244
|
+
timeoutSeconds,
|
|
12245
|
+
...PLAY_SANDBOX_SIZE_LIMITS[size]
|
|
12246
|
+
});
|
|
12235
12247
|
}
|
|
12236
12248
|
|
|
12237
12249
|
// ../shared_libs/play-runtime/worker-api-types.ts
|
|
@@ -12294,9 +12306,11 @@ function estimateDaytonaMaximumComputeCredits(limits) {
|
|
|
12294
12306
|
);
|
|
12295
12307
|
}
|
|
12296
12308
|
function formatNonStandardSandboxRuntimeWarning(limits) {
|
|
12297
|
-
if (
|
|
12309
|
+
if (limits.timeoutSeconds <= STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS.timeoutSeconds) {
|
|
12310
|
+
return null;
|
|
12311
|
+
}
|
|
12298
12312
|
const maximumComputeCredits = estimateDaytonaMaximumComputeCredits(limits);
|
|
12299
|
-
return `This Play requests
|
|
12313
|
+
return `This Play requests the standard sandbox for up to ${limits.timeoutSeconds}s (${limits.memoryGiB}GiB memory, ${limits.cpu} CPU, ${limits.diskGiB}GiB disk). Maximum compute estimate: ${maximumComputeCredits.toFixed(2)} Deepline credits. Longer runtimes are risky.`;
|
|
12300
12314
|
}
|
|
12301
12315
|
|
|
12302
12316
|
// ../shared_libs/play-runtime/internal-step-ids.ts
|
|
@@ -12858,7 +12872,7 @@ function looksLikeFilePath(target) {
|
|
|
12858
12872
|
}
|
|
12859
12873
|
return target.includes("\\") || /\.(ts|js|mjs|play\.ts)$/.test(target);
|
|
12860
12874
|
}
|
|
12861
|
-
function
|
|
12875
|
+
function parsePositiveInteger3(value, flagName) {
|
|
12862
12876
|
const parsed = Number.parseInt(value, 10);
|
|
12863
12877
|
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
12864
12878
|
throw new Error(`${flagName} must be a positive integer.`);
|
|
@@ -16378,7 +16392,7 @@ function parsePlayRunOptions(args) {
|
|
|
16378
16392
|
);
|
|
16379
16393
|
}
|
|
16380
16394
|
if ((arg === "--tail-timeout-ms" || arg === "--timeout-ms") && args[index + 1]) {
|
|
16381
|
-
waitTimeoutMs =
|
|
16395
|
+
waitTimeoutMs = parsePositiveInteger3(args[++index], arg);
|
|
16382
16396
|
continue;
|
|
16383
16397
|
}
|
|
16384
16398
|
if (PLAY_RUN_RESERVED_BOOLEAN_FLAGS.has(arg)) {
|
|
@@ -17539,7 +17553,7 @@ async function handleRunLogs(args) {
|
|
|
17539
17553
|
for (let index = 0; index < args.length; index += 1) {
|
|
17540
17554
|
const arg = args[index];
|
|
17541
17555
|
if (arg === "--limit" && args[index + 1]) {
|
|
17542
|
-
limit =
|
|
17556
|
+
limit = parsePositiveInteger3(args[++index], "--limit");
|
|
17543
17557
|
continue;
|
|
17544
17558
|
}
|
|
17545
17559
|
if (arg === "--out" && args[index + 1]) {
|
package/dist/index.d.mts
CHANGED
|
@@ -3844,16 +3844,12 @@ type PlayBindings = {
|
|
|
3844
3844
|
/** Stop the run before a billed action would push total run credits above this cap. */
|
|
3845
3845
|
maxCreditsPerRun?: number;
|
|
3846
3846
|
};
|
|
3847
|
-
/** Requested sandbox
|
|
3847
|
+
/** Requested prebuilt sandbox and runtime deadline. */
|
|
3848
3848
|
runtime?: {
|
|
3849
3849
|
/** Duration such as `"90m"` or `"2h"`. */
|
|
3850
3850
|
timeout?: string;
|
|
3851
|
-
/**
|
|
3852
|
-
|
|
3853
|
-
/** Whole vCPU count. */
|
|
3854
|
-
cpu?: number;
|
|
3855
|
-
/** Disk such as `"10GiB"`. */
|
|
3856
|
-
disk?: string;
|
|
3851
|
+
/** Deepline-managed prebuilt sandbox size. */
|
|
3852
|
+
size?: 'standard';
|
|
3857
3853
|
};
|
|
3858
3854
|
/** Webhook trigger with optional HMAC signature verification. */
|
|
3859
3855
|
webhook?: {
|
|
@@ -4669,7 +4665,7 @@ type DefinePlayConfig<TInput, TOutput extends PlayReturnObject> = {
|
|
|
4669
4665
|
bindings?: PlayBindings;
|
|
4670
4666
|
/** Billing options. */
|
|
4671
4667
|
billing?: PlayBindings['billing'];
|
|
4672
|
-
/** Requested sandbox
|
|
4668
|
+
/** Requested prebuilt sandbox and runtime deadline. */
|
|
4673
4669
|
runtime?: PlayBindings['runtime'];
|
|
4674
4670
|
/** Runtime compatibility override. Omit for the current typed contract. */
|
|
4675
4671
|
compatibility?: PlayBindings['compatibility'];
|
|
@@ -4713,7 +4709,7 @@ declare function runIf<Row, Value>(predicate: (row: Row, index: number) => boole
|
|
|
4713
4709
|
type DefinedPlay<TInput, TOutput extends PlayReturnObject> = ((ctx: DeeplinePlayRuntimeContext, input: TInput) => Promise<TOutput>) & DeeplineNamedPlay<TInput, TOutput> & {
|
|
4714
4710
|
/** Optional trigger bindings (cron, webhook). */
|
|
4715
4711
|
readonly bindings?: PlayBindings;
|
|
4716
|
-
/** Requested sandbox
|
|
4712
|
+
/** Requested prebuilt sandbox and runtime deadline. */
|
|
4717
4713
|
readonly runtime?: PlayBindings['runtime'];
|
|
4718
4714
|
/** Runtime compatibility explicitly selected by the author. */
|
|
4719
4715
|
readonly compatibility?: PlayBindings['compatibility'];
|
package/dist/index.d.ts
CHANGED
|
@@ -3844,16 +3844,12 @@ type PlayBindings = {
|
|
|
3844
3844
|
/** Stop the run before a billed action would push total run credits above this cap. */
|
|
3845
3845
|
maxCreditsPerRun?: number;
|
|
3846
3846
|
};
|
|
3847
|
-
/** Requested sandbox
|
|
3847
|
+
/** Requested prebuilt sandbox and runtime deadline. */
|
|
3848
3848
|
runtime?: {
|
|
3849
3849
|
/** Duration such as `"90m"` or `"2h"`. */
|
|
3850
3850
|
timeout?: string;
|
|
3851
|
-
/**
|
|
3852
|
-
|
|
3853
|
-
/** Whole vCPU count. */
|
|
3854
|
-
cpu?: number;
|
|
3855
|
-
/** Disk such as `"10GiB"`. */
|
|
3856
|
-
disk?: string;
|
|
3851
|
+
/** Deepline-managed prebuilt sandbox size. */
|
|
3852
|
+
size?: 'standard';
|
|
3857
3853
|
};
|
|
3858
3854
|
/** Webhook trigger with optional HMAC signature verification. */
|
|
3859
3855
|
webhook?: {
|
|
@@ -4669,7 +4665,7 @@ type DefinePlayConfig<TInput, TOutput extends PlayReturnObject> = {
|
|
|
4669
4665
|
bindings?: PlayBindings;
|
|
4670
4666
|
/** Billing options. */
|
|
4671
4667
|
billing?: PlayBindings['billing'];
|
|
4672
|
-
/** Requested sandbox
|
|
4668
|
+
/** Requested prebuilt sandbox and runtime deadline. */
|
|
4673
4669
|
runtime?: PlayBindings['runtime'];
|
|
4674
4670
|
/** Runtime compatibility override. Omit for the current typed contract. */
|
|
4675
4671
|
compatibility?: PlayBindings['compatibility'];
|
|
@@ -4713,7 +4709,7 @@ declare function runIf<Row, Value>(predicate: (row: Row, index: number) => boole
|
|
|
4713
4709
|
type DefinedPlay<TInput, TOutput extends PlayReturnObject> = ((ctx: DeeplinePlayRuntimeContext, input: TInput) => Promise<TOutput>) & DeeplineNamedPlay<TInput, TOutput> & {
|
|
4714
4710
|
/** Optional trigger bindings (cron, webhook). */
|
|
4715
4711
|
readonly bindings?: PlayBindings;
|
|
4716
|
-
/** Requested sandbox
|
|
4712
|
+
/** Requested prebuilt sandbox and runtime deadline. */
|
|
4717
4713
|
readonly runtime?: PlayBindings['runtime'];
|
|
4718
4714
|
/** Runtime compatibility explicitly selected by the author. */
|
|
4719
4715
|
readonly compatibility?: PlayBindings['compatibility'];
|
package/dist/index.js
CHANGED
|
@@ -760,7 +760,7 @@ var SDK_RELEASE = {
|
|
|
760
760
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
761
761
|
// 0.1.254 removes the internal operations tree from the published SDK CLI.
|
|
762
762
|
// Operators use the checkout-local deepline-admin binary instead.
|
|
763
|
-
version: "0.1.
|
|
763
|
+
version: "0.1.314",
|
|
764
764
|
contracts: {
|
|
765
765
|
api: {
|
|
766
766
|
name: "sdk-http-api",
|
package/dist/index.mjs
CHANGED
|
@@ -686,7 +686,7 @@ var SDK_RELEASE = {
|
|
|
686
686
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
687
687
|
// 0.1.254 removes the internal operations tree from the published SDK CLI.
|
|
688
688
|
// Operators use the checkout-local deepline-admin binary instead.
|
|
689
|
-
version: "0.1.
|
|
689
|
+
version: "0.1.314",
|
|
690
690
|
contracts: {
|
|
691
691
|
api: {
|
|
692
692
|
name: "sdk-http-api",
|
|
@@ -40,11 +40,10 @@ type PlayBundleArtifact = {
|
|
|
40
40
|
cacheHit: boolean;
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
+
type PlaySandboxSize = 'standard';
|
|
43
44
|
type PlaySandboxRuntimeDeclaration = {
|
|
44
45
|
timeout?: string;
|
|
45
|
-
|
|
46
|
-
cpu?: number;
|
|
47
|
-
disk?: string;
|
|
46
|
+
size?: PlaySandboxSize;
|
|
48
47
|
};
|
|
49
48
|
|
|
50
49
|
type ImportedPlayDependency = {
|
|
@@ -40,11 +40,10 @@ type PlayBundleArtifact = {
|
|
|
40
40
|
cacheHit: boolean;
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
+
type PlaySandboxSize = 'standard';
|
|
43
44
|
type PlaySandboxRuntimeDeclaration = {
|
|
44
45
|
timeout?: string;
|
|
45
|
-
|
|
46
|
-
cpu?: number;
|
|
47
|
-
disk?: string;
|
|
46
|
+
size?: PlaySandboxSize;
|
|
48
47
|
};
|
|
49
48
|
|
|
50
49
|
type ImportedPlayDependency = {
|
|
@@ -556,6 +556,30 @@ function resolveStaticProperty(node, propertyName, context, ancestors = /* @__PU
|
|
|
556
556
|
}
|
|
557
557
|
return resolution;
|
|
558
558
|
}
|
|
559
|
+
function staticPropertyNames(node, context, ancestors = /* @__PURE__ */ new Set()) {
|
|
560
|
+
if (!node) return /* @__PURE__ */ new Set();
|
|
561
|
+
const object = objectExpressionFromNode(node, context);
|
|
562
|
+
if (!object || ancestors.has(object)) return null;
|
|
563
|
+
const nextAncestors = new Set(ancestors).add(object);
|
|
564
|
+
const names = /* @__PURE__ */ new Set();
|
|
565
|
+
for (const property of astArray(object.properties)) {
|
|
566
|
+
if (property.type === "SpreadElement") {
|
|
567
|
+
const spreadNames = staticPropertyNames(
|
|
568
|
+
isAstNode(property.argument) ? property.argument : null,
|
|
569
|
+
context,
|
|
570
|
+
nextAncestors
|
|
571
|
+
);
|
|
572
|
+
if (!spreadNames) return null;
|
|
573
|
+
for (const name2 of spreadNames) names.add(name2);
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
576
|
+
if (property.type !== "Property") return null;
|
|
577
|
+
const name = propertyNameFromKey(property);
|
|
578
|
+
if (name === null) return null;
|
|
579
|
+
names.add(name);
|
|
580
|
+
}
|
|
581
|
+
return names;
|
|
582
|
+
}
|
|
559
583
|
function staticNumberFromExpression(node, context, seen = /* @__PURE__ */ new Set()) {
|
|
560
584
|
const expression = unwrapStaticExpression(node);
|
|
561
585
|
if (!expression) return null;
|
|
@@ -600,30 +624,27 @@ function sandboxRuntimeDeclarationFromOptions(node, context) {
|
|
|
600
624
|
const bindingRuntime = bindings.kind === "found" ? resolveStaticProperty(bindings.value, "runtime", context) : { kind: "absent" };
|
|
601
625
|
const runtime = directRuntime.kind === "found" ? directRuntime : bindingRuntime;
|
|
602
626
|
if (runtime.kind !== "found") return null;
|
|
627
|
+
const propertyNames = staticPropertyNames(runtime.value, context);
|
|
628
|
+
const unsupportedProperties = propertyNames ? [...propertyNames].filter(
|
|
629
|
+
(propertyName) => propertyName !== "timeout" && propertyName !== "size"
|
|
630
|
+
) : [];
|
|
631
|
+
if (unsupportedProperties.length > 0) {
|
|
632
|
+
throw new Error(
|
|
633
|
+
`Unsupported runtime sandbox option${unsupportedProperties.length === 1 ? "" : "s"} "${unsupportedProperties.join('", "')}". Use runtime.size with a Deepline prebuilt sandbox. Supported sizes: "standard".`
|
|
634
|
+
);
|
|
635
|
+
}
|
|
603
636
|
const timeout = resolveStaticProperty(runtime.value, "timeout", context);
|
|
604
|
-
const
|
|
605
|
-
const cpu = resolveStaticProperty(runtime.value, "cpu", context);
|
|
606
|
-
const disk = resolveStaticProperty(runtime.value, "disk", context);
|
|
637
|
+
const size = resolveStaticProperty(runtime.value, "size", context);
|
|
607
638
|
const declaration = {};
|
|
608
639
|
if (timeout.kind === "found") {
|
|
609
640
|
const value = staticStringFromExpression(timeout.value, context);
|
|
610
641
|
if (value === null) return null;
|
|
611
642
|
declaration.timeout = value;
|
|
612
643
|
}
|
|
613
|
-
if (
|
|
614
|
-
const value = staticStringFromExpression(
|
|
615
|
-
if (value === null) return null;
|
|
616
|
-
declaration.memory = value;
|
|
617
|
-
}
|
|
618
|
-
if (cpu.kind === "found") {
|
|
619
|
-
const value = staticNumberFromExpression(cpu.value, context);
|
|
620
|
-
if (value === null) return null;
|
|
621
|
-
declaration.cpu = value;
|
|
622
|
-
}
|
|
623
|
-
if (disk.kind === "found") {
|
|
624
|
-
const value = staticStringFromExpression(disk.value, context);
|
|
644
|
+
if (size.kind === "found") {
|
|
645
|
+
const value = staticStringFromExpression(size.value, context);
|
|
625
646
|
if (value === null) return null;
|
|
626
|
-
declaration.
|
|
647
|
+
declaration.size = value;
|
|
627
648
|
}
|
|
628
649
|
return declaration;
|
|
629
650
|
}
|