deepline 0.3.473 → 0.3.475
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/client-core.ts +4 -1
- package/dist/bundling-sources/sdk/src/play.ts +7 -2
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/integration-contracts/billing-entitlements.ts +3 -1
- package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +18 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-machines.ts +101 -2
- package/dist/bundling-sources/shared_libs/play-runtime/modal-runtime-config.ts +62 -20
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-launch-transport.ts +2 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +24 -8
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +19 -7
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-runtime-watchdog.ts +196 -10
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +40 -17
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/local-process.ts +4 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/modal-resource-usage.ts +222 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/modal.ts +46 -14
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/types.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-incident-drills.ts +9 -5
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-compute-usage.ts +8 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/contract.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/runner-backend-adapter.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-scope.ts +39 -15
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-state.ts +18 -8
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +64 -35
- package/dist/bundling-sources/shared_libs/play-runtime/worker-api-types.ts +36 -0
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +18 -8
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +1 -1
- package/dist/bundling-sources/shared_libs/plays/sandbox-runtime-limits.ts +64 -16
- package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +1 -1
- package/dist/bundling-sources/shared_libs/product-notifications/billing-sales.ts +14 -1
- package/dist/bundling-sources/shared_libs/product-notifications/catalog.ts +40 -0
- package/dist/bundling-sources/shared_libs/product-notifications/default-policy.ts +23 -1
- package/dist/bundling-sources/shared_libs/product-notifications/events.ts +18 -0
- package/dist/bundling-sources/shared_libs/product-notifications/slack-delivery.ts +2 -1
- package/dist/cli/auth-7GVCW24N.js +41 -0
- package/dist/cli/{auth-KLJOQ4DZ.mjs → auth-CFDYJ7FZ.mjs} +5 -5
- package/dist/cli/{billing-DNDYNBQ7.mjs → billing-PEXWWLRT.mjs} +12 -10
- package/dist/cli/{billing-IQNJXKH5.js → billing-XLIL3FLK.js} +85 -83
- package/dist/cli/{chunk-4U3RNA3J.js → chunk-3MQJJ6YX.js} +51 -51
- package/dist/cli/{chunk-EUHTZV2E.mjs → chunk-3QSFSHCJ.mjs} +1 -1
- package/dist/cli/{chunk-CNCK2D6B.mjs → chunk-3WVA7E7O.mjs} +2 -2
- package/dist/cli/{chunk-NTFM7JQW.mjs → chunk-42F6LTBJ.mjs} +3 -3
- package/dist/cli/{chunk-V25CXRQ7.mjs → chunk-4QHAP3MR.mjs} +5 -5
- package/dist/cli/{chunk-3LFSIUFI.js → chunk-4QHQ3WYW.js} +21 -21
- package/dist/cli/{chunk-6ZTSHKJF.js → chunk-5QS4T4KR.js} +10 -3
- package/dist/cli/{chunk-VS7JKS22.mjs → chunk-6PRYHABU.mjs} +1 -1
- package/dist/cli/{chunk-63OOFT6B.js → chunk-7SWRXZ4A.js} +93 -93
- package/dist/cli/{chunk-6YOGOXOJ.mjs → chunk-7U3L2S7X.mjs} +10 -10
- package/dist/cli/{chunk-D4B3EV55.js → chunk-7XTBEYLS.js} +36 -36
- package/dist/cli/{chunk-QD6IW2HP.mjs → chunk-AD7KL6AI.mjs} +4 -4
- package/dist/cli/{chunk-YH5SFKHJ.js → chunk-B7NJ5JQ2.js} +4 -4
- package/dist/cli/{chunk-F4PUDYBY.js → chunk-BLW2K6YH.js} +3 -3
- package/dist/cli/{chunk-N4ZCMQ54.js → chunk-BSK2TGB4.js} +8 -8
- package/dist/cli/{chunk-QG3THSTN.mjs → chunk-BVAYLXMH.mjs} +2 -2
- package/dist/cli/{chunk-IC6AHOYS.js → chunk-CKSRTD45.js} +1 -1
- package/dist/cli/{chunk-RVRG57OB.js → chunk-D3Q4FUFS.js} +8 -8
- package/dist/cli/{chunk-ABLEU3QI.mjs → chunk-D6SXN34W.mjs} +4 -4
- package/dist/cli/{chunk-GTH7JORC.mjs → chunk-DIMKSDF6.mjs} +2 -2
- package/dist/cli/{chunk-Z52WEIBR.js → chunk-DKR7QPEO.js} +11 -7
- package/dist/cli/{chunk-YUNPYX5T.mjs → chunk-DUGZKPRK.mjs} +10 -3
- package/dist/cli/{chunk-6QS7522K.mjs → chunk-EA45HSEC.mjs} +2 -2
- package/dist/cli/{chunk-TUFQFTOC.js → chunk-F4FNMXI3.js} +53 -53
- package/dist/cli/{chunk-3OPQLFUK.mjs → chunk-FC4C7MZM.mjs} +4 -4
- package/dist/cli/{chunk-WGQKOLXH.js → chunk-G4SGYWKV.js} +6 -6
- package/dist/cli/{chunk-GISBRE2H.mjs → chunk-HALAYT3Y.mjs} +3 -3
- package/dist/cli/{chunk-GQBAJTQU.mjs → chunk-HMHH7JQD.mjs} +2 -2
- package/dist/cli/{chunk-PMJAGTSQ.js → chunk-KTWXY73Q.js} +5 -5
- package/dist/cli/{chunk-GAWP2YF5.mjs → chunk-M27SSAQ7.mjs} +1 -1
- package/dist/cli/{chunk-UON3WCBD.js → chunk-M4QO3GRD.js} +3 -3
- package/dist/cli/{chunk-36KEQFWZ.js → chunk-M7K5BCWP.js} +10 -10
- package/dist/cli/{chunk-SWAYZST7.mjs → chunk-MUDOASYL.mjs} +2 -2
- package/dist/cli/{chunk-D22QIUE3.js → chunk-NBVYS6VG.js} +9 -9
- package/dist/cli/{chunk-GE5GPLNM.mjs → chunk-NGOKBSBH.mjs} +1 -1
- package/dist/cli/{chunk-VGVSHQN5.mjs → chunk-NHQP4UPJ.mjs} +5 -5
- package/dist/cli/{chunk-3J2N7YF5.js → chunk-QKMWQTMI.js} +3 -3
- package/dist/cli/{chunk-B3BM3PAI.js → chunk-TLPW2SHS.js} +6 -6
- package/dist/cli/{chunk-QI73EL5C.js → chunk-TZRTT7EI.js} +26 -26
- package/dist/cli/{chunk-DD7E4ZVH.js → chunk-U3F63UWD.js} +7 -7
- package/dist/cli/{chunk-RZHUHL53.mjs → chunk-V4ILQ2DS.mjs} +11 -7
- package/dist/cli/{chunk-YHB6MASP.js → chunk-VBGPRRJ6.js} +2 -2
- package/dist/cli/{chunk-HQCTPAXP.mjs → chunk-VD3E3QMI.mjs} +1 -1
- package/dist/cli/{chunk-X6R5UNDZ.mjs → chunk-VFP3MFLD.mjs} +1 -1
- package/dist/cli/{chunk-EVLUSXQG.mjs → chunk-VTCXSICG.mjs} +2 -2
- package/dist/cli/{chunk-TBLBYIKO.mjs → chunk-YAAQNDP6.mjs} +1 -1
- package/dist/cli/{chunk-IFZ76E5H.mjs → chunk-YMS7VYFA.mjs} +1 -1
- package/dist/cli/{chunk-OHUGXZ7N.js → chunk-Z5VSBCFV.js} +16 -16
- package/dist/cli/{chunk-ZVLYUKJU.js → chunk-ZANUM4XV.js} +5 -5
- package/dist/cli/{chunk-MREO5LZD.js → chunk-ZQYBKDPA.js} +2 -2
- package/dist/cli/command-docs.js +2 -2
- package/dist/cli/command-docs.mjs +1 -1
- package/dist/cli/{csv-OVV3HWN4.js → csv-4YHSYV2C.js} +13 -13
- package/dist/cli/{csv-NCY5MWS2.mjs → csv-WC7ILC7P.mjs} +4 -4
- package/dist/cli/{db-BOELNDS4.js → db-APZNM2GI.js} +27 -27
- package/dist/cli/{db-VPH6JHUD.mjs → db-I5PV6NTC.mjs} +6 -6
- package/dist/cli/describe-OR7FZBCD.js +48 -0
- package/dist/cli/{describe-FFDCPYZH.mjs → describe-XH5F3X5W.mjs} +17 -17
- package/dist/cli/describe-core.d.mts +3 -3
- package/dist/cli/describe-core.d.ts +3 -3
- package/dist/cli/{executions-5GCCDENS.mjs → executions-PIY4XM7T.mjs} +6 -6
- package/dist/cli/{executions-RF44ANF5.js → executions-VIXFKZYU.js} +8 -8
- package/dist/cli/{feedback-OI2A5L6F.mjs → feedback-IGDHBWGT.mjs} +4 -4
- package/dist/cli/{feedback-NJM3V7QV.js → feedback-WCLIFQTR.js} +8 -8
- package/dist/cli/git-CKN2F32Y.js +25 -0
- package/dist/cli/{git-EOGSZ3T2.mjs → git-FRICPPTA.mjs} +5 -5
- package/dist/cli/index.js +139 -139
- package/dist/cli/index.mjs +41 -41
- package/dist/cli/{legacy-noops-5QM7XGGX.js → legacy-noops-DSFOPYDY.js} +8 -8
- package/dist/cli/{legacy-noops-UYKK7AAB.mjs → legacy-noops-ROAXEG6D.mjs} +5 -5
- package/dist/cli/{monitors-N3ITC5MP.mjs → monitors-FZ5PRLW6.mjs} +7 -7
- package/dist/cli/{monitors-52GW2V4V.js → monitors-KUCYQLU5.js} +91 -91
- package/dist/cli/{org-KUZUG33W.mjs → org-DRNND5XU.mjs} +6 -6
- package/dist/cli/{org-ADF47NPV.js → org-SRHMWKQR.js} +72 -72
- package/dist/cli/{pages-H3H7ODBN.js → pages-TEJQIHTU.js} +17 -17
- package/dist/cli/{pages-C3S5WU3S.mjs → pages-XNGA356T.mjs} +6 -6
- package/dist/cli/{play-YWZWBG32.js → play-GCGFQSFP.js} +662 -601
- package/dist/cli/{play-SZETTQPV.mjs → play-NE45ROIZ.mjs} +110 -49
- package/dist/cli/{providers-FSCD35HB.mjs → providers-57TJOSMV.mjs} +6 -6
- package/dist/cli/{providers-V3BP7ZB2.js → providers-VHMUR63R.js} +9 -9
- package/dist/cli/{quickstart-ICULVGAR.js → quickstart-BPXWO4UD.js} +6 -6
- package/dist/cli/{quickstart-SYZCT2WI.mjs → quickstart-K3SH4NXP.mjs} +4 -4
- package/dist/cli/{run-WUJSKGUM.js → run-553AAXDU.js} +36 -36
- package/dist/cli/{run-HA5B3AYQ.mjs → run-ZRWJUEN2.mjs} +22 -22
- package/dist/cli/{search-A27AGYDV.mjs → search-BW6XRS4I.mjs} +7 -7
- package/dist/cli/search-WF26AUDJ.js +32 -0
- package/dist/cli/{secrets-ODX56QBF.js → secrets-AMYQYUL5.js} +15 -15
- package/dist/cli/{secrets-2L4VRJ2F.mjs → secrets-OYYCFGZE.mjs} +6 -6
- package/dist/cli/{sessions-PRF36DHO.mjs → sessions-O4SVVOMO.mjs} +5 -5
- package/dist/cli/{sessions-DVZ4FECP.js → sessions-RYCJUMJ2.js} +6 -6
- package/dist/cli/{settings-RJT5DBWG.js → settings-7R5FQKII.js} +78 -78
- package/dist/cli/{settings-LUATIKJE.mjs → settings-QK7DHDU7.mjs} +11 -11
- package/dist/cli/{setup-FJSBKCLU.js → setup-OTQDQHDN.js} +44 -44
- package/dist/cli/{setup-IQXTYLRH.mjs → setup-VDAAVCKK.mjs} +9 -9
- package/dist/cli/{skills-XJH4ZC5Y.mjs → skills-HRK5O5JO.mjs} +7 -7
- package/dist/cli/skills-VNLMEOXW.js +31 -0
- package/dist/cli/tools-C3MUHL7G.js +55 -0
- package/dist/cli/{tools-IGXLZCKZ.mjs → tools-O7BM62QV.mjs} +16 -16
- package/dist/cli/update-TCKTU6QJ.js +33 -0
- package/dist/cli/{update-AH7G5VSL.mjs → update-UHKHCSTY.mjs} +9 -9
- package/dist/cli/{workflow-IQ2J7LWM.js → workflow-7Z5NCTGG.js} +17 -17
- package/dist/cli/{workflow-WOYSCWVD.mjs → workflow-T2EDR7L4.mjs} +7 -7
- package/dist/{client-C9bJ0QXu.d.mts → client-Bgl0_zXi.d.mts} +1 -1
- package/dist/{client-CuNH54w3.d.ts → client-_ah6IuhK.d.ts} +1 -1
- package/dist/{client-core-CSiXbe2n.d.mts → client-core-Bfsedm0_.d.mts} +44 -3
- package/dist/{client-core-C8Q6DKga.d.ts → client-core-C-ZF5vh9.d.ts} +44 -3
- package/dist/{compiler-manifest-Zwm9yqOA.d.mts → compiler-manifest-CCOqDGjU.d.mts} +12 -10
- package/dist/{compiler-manifest-Zwm9yqOA.d.ts → compiler-manifest-CCOqDGjU.d.ts} +12 -10
- package/dist/{errors-nEsqNLL8.d.mts → errors-BLccD7tG.d.mts} +1 -1
- package/dist/{errors-CsYwlpn4.d.ts → errors-Cy3kPnsi.d.ts} +1 -1
- package/dist/{index-CXF2jtza.d.mts → index-4-j44HuT.d.mts} +1 -1
- package/dist/{index-9pUZqkPH.d.ts → index-D5e4h1-H.d.ts} +1 -1
- package/dist/index.d.mts +14 -9
- package/dist/index.d.ts +14 -9
- package/dist/index.js +9 -9
- package/dist/index.mjs +6 -6
- package/dist/install-integrity.json +111 -110
- package/dist/plays/bundle-play-file.d.mts +3 -3
- package/dist/plays/bundle-play-file.d.ts +3 -3
- package/dist/plays/bundle-play-file.mjs +1 -1
- package/dist/plays/play-description.d.mts +2 -2
- package/dist/plays/play-description.d.ts +2 -2
- package/dist/plays/run-request.d.mts +2 -2
- package/dist/plays/run-request.d.ts +2 -2
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +2 -2
- package/dist/release.mjs +1 -1
- package/dist/server.d.mts +4 -4
- package/dist/server.d.ts +4 -4
- package/dist/server.js +5 -5
- package/dist/server.mjs +3 -3
- package/package.json +1 -1
- package/dist/cli/auth-IJOWKNSB.js +0 -41
- package/dist/cli/describe-7SFESEFL.js +0 -48
- package/dist/cli/git-4V5ZS5SE.js +0 -25
- package/dist/cli/search-XATDPNEM.js +0 -32
- package/dist/cli/skills-N6CPBF6T.js +0 -31
- package/dist/cli/tools-YMVEVRCE.js +0 -55
- package/dist/cli/update-MUCWGTXH.js +0 -33
|
@@ -2555,7 +2555,10 @@ export type BillingNamespace = {
|
|
|
2555
2555
|
|
|
2556
2556
|
export type BillingQuoteRequest = {
|
|
2557
2557
|
quantity: number;
|
|
2558
|
-
sandbox_runtime: {
|
|
2558
|
+
sandbox_runtime: {
|
|
2559
|
+
timeout?: string;
|
|
2560
|
+
size?: 'standard' | 'large' | 'xlarge';
|
|
2561
|
+
};
|
|
2559
2562
|
};
|
|
2560
2563
|
|
|
2561
2564
|
export type BillingQuoteResult = {
|
|
@@ -184,8 +184,13 @@ export type PlayFetchResponse = PlayAuthoringFetchResponse;
|
|
|
184
184
|
* `deepline describe <id>` for a tool's streams and row columns).
|
|
185
185
|
* The changed row is delivered as the listener event's `after` in the play function's input.
|
|
186
186
|
*
|
|
187
|
-
* The default Play runtime is 30 minutes
|
|
188
|
-
*
|
|
187
|
+
* The default Play runtime is 30 minutes with the `standard` 1 GiB / 1 CPU
|
|
188
|
+
* profile. Preview deployments also support `large` (4 GiB / 2 CPU) and
|
|
189
|
+
* `xlarge` (8 GiB / 4 CPU) through `runtime.size`. Production uses `standard`.
|
|
190
|
+
* Compute pricing follows the workspace plan; use `deepline billing quote`
|
|
191
|
+
* for the session ceiling.
|
|
192
|
+
* Set `runtime.timeout` for longer bounded runs; duration values are whole
|
|
193
|
+
* minutes or hours, up to `4h`.
|
|
189
194
|
* It differs from `deepline.tools.execute({ timeoutMs })`, which limits one provider call.
|
|
190
195
|
*
|
|
191
196
|
* @example Webhook with HMAC verification. `secretEnv` is the Deepline Secret
|
|
@@ -205,7 +205,7 @@ export const SDK_RELEASE = {
|
|
|
205
205
|
// getters keep their established compatibility behavior.
|
|
206
206
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
207
207
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
208
|
-
version: '0.3.
|
|
208
|
+
version: '0.3.475',
|
|
209
209
|
updateSummary: {
|
|
210
210
|
introducedIn: '0.3.90',
|
|
211
211
|
summary:
|
|
@@ -74,7 +74,7 @@ export type BillingEntitlements = {
|
|
|
74
74
|
export type IncludedCompute = {
|
|
75
75
|
/** `unavailable`: the workspace is outside the November pricing rollout. */
|
|
76
76
|
status: 'on' | 'off' | 'unavailable';
|
|
77
|
-
/** Credits per
|
|
77
|
+
/** Credits per standard-equivalent sandbox minute; null at provider cost. */
|
|
78
78
|
credits_per_minute: number | null;
|
|
79
79
|
included_minutes: number;
|
|
80
80
|
/** What turning included compute on gives this workspace's plan. */
|
|
@@ -83,6 +83,8 @@ export type IncludedCompute = {
|
|
|
83
83
|
period_end_at: string;
|
|
84
84
|
resets_on: 'calendar_month' | 'billing_cycle';
|
|
85
85
|
included_minutes_used: number;
|
|
86
|
+
/** Exact Deepline credits consumed from included compute; older servers may omit it. */
|
|
87
|
+
included_credits_used?: number;
|
|
86
88
|
minutes_used: number;
|
|
87
89
|
days: Array<{ day: string; minutes: number }>;
|
|
88
90
|
};
|
|
@@ -946,6 +946,24 @@
|
|
|
946
946
|
"failureAlert": "convex_action_wrapper",
|
|
947
947
|
"domainReportRequired": true
|
|
948
948
|
},
|
|
949
|
+
{
|
|
950
|
+
"id": "convex.observe-large-usage-charges",
|
|
951
|
+
"name": "Observe unusually large usage charges",
|
|
952
|
+
"scheduler": "convex_scheduled_action",
|
|
953
|
+
"cadence": "runAfter(0) from each consumed positive usage-notification batch",
|
|
954
|
+
"timezone": "UTC",
|
|
955
|
+
"source": "packages/convex/scheduledJobsNode.ts",
|
|
956
|
+
"locator": "observeLargeUsageCharges",
|
|
957
|
+
"owner": "billing",
|
|
958
|
+
"criticality": "critical",
|
|
959
|
+
"purpose": "Observe committed individual charges against their tool thresholds, including cumulative async settlements.",
|
|
960
|
+
"successDefinition": "The bounded source batch and each billing-owner total are read independently, and any threshold breach is reported.",
|
|
961
|
+
"failureDefinition": "Committed usage or its billing-owner total cannot be observed; failure remains visible for operator recovery.",
|
|
962
|
+
"startGraceMs": 120000,
|
|
963
|
+
"runTimeoutMs": 1800000,
|
|
964
|
+
"failureAlert": "convex_action_wrapper",
|
|
965
|
+
"domainReportRequired": true
|
|
966
|
+
},
|
|
949
967
|
{
|
|
950
968
|
"id": "convex.credit-balance-auto-recharge-trigger",
|
|
951
969
|
"name": "Credit-balance automatic recharge trigger",
|
|
@@ -657,6 +657,20 @@ function assertMinSecretsVersion(value: unknown): asserts value is number {
|
|
|
657
657
|
}
|
|
658
658
|
}
|
|
659
659
|
|
|
660
|
+
export type FlyMachinePhaseEvent = Readonly<{
|
|
661
|
+
phase:
|
|
662
|
+
| 'machine-create'
|
|
663
|
+
| 'machine-update'
|
|
664
|
+
| 'machine-start'
|
|
665
|
+
| 'readiness-read';
|
|
666
|
+
component: 'worker';
|
|
667
|
+
source: 'machines-api';
|
|
668
|
+
startedAtMs: number;
|
|
669
|
+
finishedAtMs: number;
|
|
670
|
+
elapsedMs: number;
|
|
671
|
+
outcome: 'success' | 'error';
|
|
672
|
+
}>;
|
|
673
|
+
|
|
660
674
|
export class FlyMachinesClient {
|
|
661
675
|
constructor(
|
|
662
676
|
private readonly app: string,
|
|
@@ -666,6 +680,11 @@ export class FlyMachinesClient {
|
|
|
666
680
|
wait?: (ms: number) => Promise<void>;
|
|
667
681
|
retryDelaysMs?: readonly number[];
|
|
668
682
|
requestTimeoutMs?: number;
|
|
683
|
+
/** Preview CLI diagnostics only; no provider arguments or bodies. */
|
|
684
|
+
phaseTiming?: Readonly<{
|
|
685
|
+
now?: () => number;
|
|
686
|
+
report?: (event: FlyMachinePhaseEvent) => void;
|
|
687
|
+
}>;
|
|
669
688
|
}> = {},
|
|
670
689
|
) {}
|
|
671
690
|
|
|
@@ -674,6 +693,67 @@ export class FlyMachinesClient {
|
|
|
674
693
|
path: string,
|
|
675
694
|
body?: unknown,
|
|
676
695
|
leaseNonce?: string,
|
|
696
|
+
): Promise<unknown> {
|
|
697
|
+
const timing = this.rateLimitOptions.phaseTiming;
|
|
698
|
+
const phase: FlyMachinePhaseEvent['phase'] | undefined =
|
|
699
|
+
method === 'GET' && /^\/machines(?:\/[^/]+)?$/.test(path)
|
|
700
|
+
? 'readiness-read'
|
|
701
|
+
: method === 'POST' && path === '/machines'
|
|
702
|
+
? 'machine-create'
|
|
703
|
+
: method === 'POST' && /^\/machines\/[^/]+$/.test(path)
|
|
704
|
+
? 'machine-update'
|
|
705
|
+
: method === 'POST' && /^\/machines\/[^/]+\/start$/.test(path)
|
|
706
|
+
? 'machine-start'
|
|
707
|
+
: undefined;
|
|
708
|
+
if (!timing || !phase)
|
|
709
|
+
return this.requestUntimed(method, path, body, leaseNonce);
|
|
710
|
+
const now = timing.now ?? Date.now;
|
|
711
|
+
let startedAtMs: number;
|
|
712
|
+
try {
|
|
713
|
+
startedAtMs = now();
|
|
714
|
+
} catch {
|
|
715
|
+
this.reportTimingUnavailable();
|
|
716
|
+
return this.requestUntimed(method, path, body, leaseNonce);
|
|
717
|
+
}
|
|
718
|
+
let outcome: FlyMachinePhaseEvent['outcome'] = 'error';
|
|
719
|
+
try {
|
|
720
|
+
const result = await this.requestUntimed(method, path, body, leaseNonce);
|
|
721
|
+
outcome = 'success';
|
|
722
|
+
return result;
|
|
723
|
+
} finally {
|
|
724
|
+
// Diagnostic failures cannot change a provider outcome or retry an effect.
|
|
725
|
+
try {
|
|
726
|
+
const finishedAtMs = now();
|
|
727
|
+
const event: FlyMachinePhaseEvent = {
|
|
728
|
+
phase,
|
|
729
|
+
component: 'worker',
|
|
730
|
+
source: 'machines-api',
|
|
731
|
+
startedAtMs,
|
|
732
|
+
finishedAtMs,
|
|
733
|
+
elapsedMs: finishedAtMs - startedAtMs,
|
|
734
|
+
outcome,
|
|
735
|
+
};
|
|
736
|
+
if (timing.report) timing.report(event);
|
|
737
|
+
else console.error(`[runtime-fly-phase] ${JSON.stringify(event)}`);
|
|
738
|
+
} catch {
|
|
739
|
+
this.reportTimingUnavailable();
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
private reportTimingUnavailable(): void {
|
|
745
|
+
try {
|
|
746
|
+
console.error('[runtime-fly-phase] timing_unavailable');
|
|
747
|
+
} catch {
|
|
748
|
+
// A closed diagnostic stream must preserve the original provider result.
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
private async requestUntimed(
|
|
753
|
+
method: string,
|
|
754
|
+
path: string,
|
|
755
|
+
body?: unknown,
|
|
756
|
+
leaseNonce?: string,
|
|
677
757
|
): Promise<unknown> {
|
|
678
758
|
const retryDelaysMs =
|
|
679
759
|
this.rateLimitOptions.retryDelaysMs ??
|
|
@@ -1458,6 +1538,23 @@ export async function replaceLane(input: {
|
|
|
1458
1538
|
return replacements;
|
|
1459
1539
|
}
|
|
1460
1540
|
|
|
1541
|
+
function previewMachinePhaseTiming(
|
|
1542
|
+
flags: Record<string, string | boolean>,
|
|
1543
|
+
): Readonly<{ report: (event: FlyMachinePhaseEvent) => void }> | undefined {
|
|
1544
|
+
if (flags.environment !== 'preview') return undefined;
|
|
1545
|
+
const output =
|
|
1546
|
+
flags['phase-timings-file'] === undefined
|
|
1547
|
+
? undefined
|
|
1548
|
+
: requireStringFlag(flags, 'phase-timings-file');
|
|
1549
|
+
return {
|
|
1550
|
+
report(event) {
|
|
1551
|
+
const record = JSON.stringify(event);
|
|
1552
|
+
if (output) appendFileSync(output, `${record}\n`);
|
|
1553
|
+
console.error(`[runtime-fly-phase] ${record}`);
|
|
1554
|
+
},
|
|
1555
|
+
};
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1461
1558
|
async function cmdBoot(flags: Record<string, string | boolean>): Promise<void> {
|
|
1462
1559
|
const app = resolveApp(flags);
|
|
1463
1560
|
const releaseId = requireReleaseId(flags);
|
|
@@ -1505,6 +1602,7 @@ async function cmdBoot(flags: Record<string, string | boolean>): Promise<void> {
|
|
|
1505
1602
|
app,
|
|
1506
1603
|
requireFlyToken(),
|
|
1507
1604
|
globalThis.fetch as FetchLike,
|
|
1605
|
+
{ phaseTiming: previewMachinePhaseTiming(flags) },
|
|
1508
1606
|
);
|
|
1509
1607
|
await bootLane({
|
|
1510
1608
|
client,
|
|
@@ -1549,6 +1647,7 @@ async function cmdReplace(
|
|
|
1549
1647
|
app,
|
|
1550
1648
|
requireFlyToken(),
|
|
1551
1649
|
globalThis.fetch as FetchLike,
|
|
1650
|
+
{ phaseTiming: previewMachinePhaseTiming(flags) },
|
|
1552
1651
|
);
|
|
1553
1652
|
await replaceLane({
|
|
1554
1653
|
client,
|
|
@@ -2214,8 +2313,8 @@ const USAGE = `fly-absurd-lane <command> [flags]
|
|
|
2214
2313
|
Commands:
|
|
2215
2314
|
push-image --sha <sha> --release <id> [--app <app>]
|
|
2216
2315
|
plan-image --release <id> [--image-ref <ref>] [--app <app>]
|
|
2217
|
-
boot --release <id> --sha <sha> --count <K> [--image-ref <ref>] [--reuse-existing] [--component-input-hash <sha256>] [--rollback-hold-until-ms <ms>] [--app <app>] [--region <r>]
|
|
2218
|
-
replace --release <id> --sha <sha> --count <K> [--image-ref <ref>] --environment preview [--component-input-hash <sha256>] [--app <app>] [--region <r>]
|
|
2316
|
+
boot --release <id> --sha <sha> --count <K> [--image-ref <ref>] [--phase-timings-file <path>] [--reuse-existing] [--component-input-hash <sha256>] [--rollback-hold-until-ms <ms>] [--app <app>] [--region <r>]
|
|
2317
|
+
replace --release <id> --sha <sha> --count <K> [--image-ref <ref>] [--phase-timings-file <path>] --environment preview [--component-input-hash <sha256>] [--app <app>] [--region <r>]
|
|
2219
2318
|
list [--release <id>] [--json] [--app <app>]
|
|
2220
2319
|
drain --release <id> [--if-present] [--app <app>]
|
|
2221
2320
|
stop-claiming --release <id> [--environment production|preview]
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
2
|
import type { ModalClient } from 'modal';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
isIsolatedRuntimeSchedulerSchema,
|
|
5
|
+
normalizeRuntimeSchedulerSchema,
|
|
6
|
+
} from './runtime-scheduler-topology';
|
|
4
7
|
import {
|
|
5
8
|
STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS,
|
|
9
|
+
modalSandboxMemoryLimitGiBForPlay,
|
|
6
10
|
validatePlaySandboxRuntimeLimits,
|
|
7
11
|
type PlaySandboxRuntimeLimits,
|
|
8
12
|
} from '../plays/sandbox-runtime-limits';
|
|
@@ -10,9 +14,47 @@ import {
|
|
|
10
14
|
export const MODAL_RUNNER_APP_NAME = 'deepline-play-runner';
|
|
11
15
|
export const MODAL_RUNNER_IMAGE = 'node:20-bookworm-slim';
|
|
12
16
|
export const MODAL_RUNNER_WORKDIR = '/root/deepline';
|
|
13
|
-
export {
|
|
17
|
+
export {
|
|
18
|
+
MODAL_SANDBOX_CPU_CORES,
|
|
19
|
+
modalSandboxResourcesForPlay,
|
|
20
|
+
} from './worker-api-types';
|
|
14
21
|
export const MODAL_SANDBOX_MEMORY_MIB = 1024;
|
|
15
22
|
|
|
23
|
+
export function isModalPreviewEvaluation(input: {
|
|
24
|
+
runtimeSchedulerSchema: string | null | undefined;
|
|
25
|
+
env?: NodeJS.ProcessEnv;
|
|
26
|
+
}): boolean {
|
|
27
|
+
const schema = normalizeRuntimeSchedulerSchema(input.runtimeSchedulerSchema);
|
|
28
|
+
return (
|
|
29
|
+
(input.env ?? process.env).DEEPLINE_RUNTIME_ENVIRONMENT === 'preview' &&
|
|
30
|
+
schema !== null &&
|
|
31
|
+
isIsolatedRuntimeSchedulerSchema(schema)
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Reservation and burst ceiling are separate provider facts. Keep the launch's
|
|
37
|
+
* profile unchanged: it still selects guaranteed resources. Preview evaluates
|
|
38
|
+
* headroom before any Production rollout. Preview workers and a valid isolated
|
|
39
|
+
* scheduler schema are both required; absence keeps the Production policy.
|
|
40
|
+
*/
|
|
41
|
+
export function resolveModalSandboxMemoryPolicy(input: {
|
|
42
|
+
limits: PlaySandboxRuntimeLimits;
|
|
43
|
+
runtimeSchedulerSchema: string | null | undefined;
|
|
44
|
+
env?: NodeJS.ProcessEnv;
|
|
45
|
+
}): { reservationMemoryMiB: number; memoryLimitMiB: number } {
|
|
46
|
+
const limits = validatePlaySandboxRuntimeLimits(input.limits);
|
|
47
|
+
const reservationMemoryMiB = limits.memoryGiB * 1024;
|
|
48
|
+
const enableBurst = isModalPreviewEvaluation(input);
|
|
49
|
+
// The retained buffered Node/Python transport completes in 4 GiB. Larger
|
|
50
|
+
// reservations can burst to the existing product ceiling, without increasing
|
|
51
|
+
// their CPU reservation or paying for unused memory headroom.
|
|
52
|
+
const memoryLimitMiB = enableBurst
|
|
53
|
+
? modalSandboxMemoryLimitGiBForPlay(limits) * 1024
|
|
54
|
+
: reservationMemoryMiB;
|
|
55
|
+
return { reservationMemoryMiB, memoryLimitMiB };
|
|
56
|
+
}
|
|
57
|
+
|
|
16
58
|
export type ModalRequiredConfig = {
|
|
17
59
|
client: ModalClient;
|
|
18
60
|
appName: string;
|
|
@@ -105,24 +147,24 @@ export function withModalCallSignal<T>(
|
|
|
105
147
|
|
|
106
148
|
// Modal runs custom middleware outside its own retry loop, so the signal also
|
|
107
149
|
// ends a retry or throttle wait.
|
|
108
|
-
const cancelModalCallsWithScopedSignal: ModalGrpcMiddleware =
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return yield* call.next(call.request,
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
150
|
+
const cancelModalCallsWithScopedSignal: ModalGrpcMiddleware = async function* (
|
|
151
|
+
call,
|
|
152
|
+
options,
|
|
153
|
+
) {
|
|
154
|
+
const signal = modalCallSignal.getStore();
|
|
155
|
+
// Every caller shares one auth token refresh, so one read's deadline must
|
|
156
|
+
// not cancel it.
|
|
157
|
+
if (
|
|
158
|
+
!signal ||
|
|
159
|
+
call.method.path === '/modal.client.ModalClient/AuthTokenGet'
|
|
160
|
+
) {
|
|
161
|
+
return yield* call.next(call.request, options);
|
|
162
|
+
}
|
|
163
|
+
return yield* call.next(call.request, {
|
|
164
|
+
...options,
|
|
165
|
+
signal: options.signal ? AbortSignal.any([options.signal, signal]) : signal,
|
|
166
|
+
});
|
|
167
|
+
};
|
|
126
168
|
|
|
127
169
|
let sharedModalClient: {
|
|
128
170
|
tokenId: string;
|
|
@@ -12,12 +12,12 @@ import {
|
|
|
12
12
|
DaytonaConflictError,
|
|
13
13
|
DaytonaRateLimitError,
|
|
14
14
|
DaytonaValidationError,
|
|
15
|
-
type CreateSandboxFromSnapshotParams,
|
|
16
15
|
} from '@daytonaio/sdk';
|
|
17
16
|
import axios, { type InternalAxiosRequestConfig } from 'axios';
|
|
18
17
|
import { Readable } from 'node:stream';
|
|
19
18
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
20
19
|
import type { DaytonaClientOptions } from '../../daytona-runtime-config';
|
|
20
|
+
import type { CreateSandboxFromSnapshotParams } from '@daytonaio/sdk';
|
|
21
21
|
import type { DaytonaDeleteRetryAuthorization } from './daytona-lifecycle';
|
|
22
22
|
import {
|
|
23
23
|
DAYTONA_CONTROL_TIMEOUT_MS,
|
|
@@ -429,7 +429,7 @@ function deadline(timeoutMs: number, signal?: AbortSignal) {
|
|
|
429
429
|
};
|
|
430
430
|
}
|
|
431
431
|
|
|
432
|
-
/** Deepline's
|
|
432
|
+
/** Deepline's snapshot launch contract; image/build orchestration stays in the SDK. */
|
|
433
433
|
export function createDaytonaLaunchClient(
|
|
434
434
|
options: DaytonaClientOptions,
|
|
435
435
|
cancellation?: AbortSignal,
|
package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts
CHANGED
|
@@ -20,8 +20,10 @@ import { isIsolatedRuntimeSchedulerSchema } from '../../runtime-scheduler-topolo
|
|
|
20
20
|
import { PLAY_RUNNER_TIMEOUT_SECONDS } from '../../runtime-constants';
|
|
21
21
|
import {
|
|
22
22
|
STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS,
|
|
23
|
+
playSandboxSizeForLimits,
|
|
23
24
|
validatePlaySandboxRuntimeLimits,
|
|
24
25
|
} from '../../../plays/sandbox-runtime-limits';
|
|
26
|
+
import type { PlaySandboxSize } from '../../../plays/sandbox-runtime-limits';
|
|
25
27
|
import type {
|
|
26
28
|
PlayRunnerDaytonaCleanupIntent,
|
|
27
29
|
PlayRunnerRuntimeLifecycleEvent,
|
|
@@ -65,8 +67,15 @@ const DAYTONA_ABSENT_OPERATION_RECREATE_AFTER_MS = 3 * 60_000;
|
|
|
65
67
|
// inactivity stop is a wider crash backstop measured from sandbox creation, so
|
|
66
68
|
// setup time cannot consume the terminal-flush grace.
|
|
67
69
|
const DAYTONA_AUTO_ARCHIVE_INTERVAL_MINUTES = 15;
|
|
68
|
-
// Daytona
|
|
69
|
-
//
|
|
70
|
+
// Daytona snapshots carry fixed resource allocations. The API rejects resource
|
|
71
|
+
// fields on snapshot creates, so select the provider snapshot that matches each
|
|
72
|
+
// Deepline profile instead of trying to resize after creation.
|
|
73
|
+
export const DAYTONA_SNAPSHOT_BY_PLAY_SANDBOX_SIZE = {
|
|
74
|
+
standard: 'daytona-small',
|
|
75
|
+
large: 'daytona-medium',
|
|
76
|
+
xlarge: 'daytona-large',
|
|
77
|
+
} as const satisfies Record<PlaySandboxSize, string>;
|
|
78
|
+
|
|
70
79
|
export const DAYTONA_SANDBOX_CPU = STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS.cpu;
|
|
71
80
|
export const DAYTONA_SANDBOX_MEMORY_GIB =
|
|
72
81
|
STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS.memoryGiB;
|
|
@@ -98,6 +107,7 @@ export type DaytonaClient = {
|
|
|
98
107
|
timeoutMs: number,
|
|
99
108
|
): { sandbox: Sandbox; dispose(): void };
|
|
100
109
|
};
|
|
110
|
+
|
|
101
111
|
export type DaytonaSandbox = Awaited<ReturnType<DaytonaClient['create']>>;
|
|
102
112
|
export type DaytonaExecutionContext = PlayRunnerExecutionConfig['context'];
|
|
103
113
|
export type DaytonaStageEmitter = (
|
|
@@ -569,6 +579,12 @@ async function createOneShotDaytonaSandbox(input: {
|
|
|
569
579
|
...STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS,
|
|
570
580
|
},
|
|
571
581
|
);
|
|
582
|
+
const sandboxSize = playSandboxSizeForLimits(limits);
|
|
583
|
+
if (!sandboxSize) {
|
|
584
|
+
throw new Error(
|
|
585
|
+
'Validated Daytona sandbox profile has no snapshot mapping.',
|
|
586
|
+
);
|
|
587
|
+
}
|
|
572
588
|
const orgId = normalizeLabelValue(input.orgId);
|
|
573
589
|
const workflowId = normalizeLabelValue(input.context.workflowId);
|
|
574
590
|
const playId = normalizeLabelValue(input.context.playId);
|
|
@@ -596,6 +612,7 @@ async function createOneShotDaytonaSandbox(input: {
|
|
|
596
612
|
const commonParams = {
|
|
597
613
|
name: input.sandboxName,
|
|
598
614
|
labels,
|
|
615
|
+
snapshot: DAYTONA_SNAPSHOT_BY_PLAY_SANDBOX_SIZE[sandboxSize],
|
|
599
616
|
// This is also the provider-owned backstop for an HTTP create timeout
|
|
600
617
|
// whose named sandbox never becomes lookup-addressable to this process:
|
|
601
618
|
// Daytona deletes an ephemeral sandbox immediately when it stops.
|
|
@@ -1227,8 +1244,8 @@ async function acquireOneShotDaytonaSandbox(input: {
|
|
|
1227
1244
|
cancellationSignal: input.cancellationSignal,
|
|
1228
1245
|
});
|
|
1229
1246
|
if (
|
|
1230
|
-
granted.cpu
|
|
1231
|
-
granted.memoryGiB
|
|
1247
|
+
granted.cpu > limits.cpu ||
|
|
1248
|
+
granted.memoryGiB > limits.memoryGiB ||
|
|
1232
1249
|
granted.diskGiB !== limits.diskGiB ||
|
|
1233
1250
|
granted.gpu !== DAYTONA_SANDBOX_GPU
|
|
1234
1251
|
) {
|
|
@@ -1298,10 +1315,9 @@ async function acquireOneShotDaytonaSandbox(input: {
|
|
|
1298
1315
|
elapsedMs: billingStartedAt - input.startedAt,
|
|
1299
1316
|
admissionWaitMs,
|
|
1300
1317
|
attemptElapsedMs: result.attemptElapsedMs,
|
|
1301
|
-
//
|
|
1302
|
-
//
|
|
1303
|
-
//
|
|
1304
|
-
// logging provider credentials or customer-code details.
|
|
1318
|
+
// Record the resolved immutable snapshot identifier so slow acquisition
|
|
1319
|
+
// can be distinguished from a bad profile snapshot without logging
|
|
1320
|
+
// provider credentials or customer-code details.
|
|
1305
1321
|
snapshot: sandbox.snapshot?.trim() || null,
|
|
1306
1322
|
cpu: granted.cpu,
|
|
1307
1323
|
memoryGiB: granted.memoryGiB,
|
|
@@ -383,17 +383,21 @@ async function main() {
|
|
|
383
383
|
runtimeLimitMarkerPath && fs.existsSync(runtimeLimitMarkerPath),
|
|
384
384
|
);
|
|
385
385
|
// 137 is SIGKILL, not proof of an OOM. A watchdog, platform eviction, or
|
|
386
|
-
// operator action can produce the same status.
|
|
387
|
-
//
|
|
386
|
+
// operator action can produce the same status. OOM requires an explicit V8
|
|
387
|
+
// allocation signature or the sandbox's cgroup OOM-kill evidence.
|
|
388
388
|
// The shell sees the watchdog's exit code, not necessarily the nested
|
|
389
389
|
// runner child's signal. Read the watchdog's strict marker so a child
|
|
390
390
|
// SIGKILL does not collapse into the wrapper's generic exit code 1.
|
|
391
391
|
const sandboxKilled = exitCode === 137 || watchdogObservedChildSigkill();
|
|
392
392
|
const memoryAbort = watchdogMemoryAbortDiagnostic();
|
|
393
|
+
const explicitOomSignature =
|
|
394
|
+
(sandboxKilled || exitCode === 134) && outputHasExplicitOomSignature();
|
|
393
395
|
const sandboxOom =
|
|
394
396
|
!memoryAbort &&
|
|
395
|
-
sandboxKilled &&
|
|
396
|
-
|
|
397
|
+
((sandboxKilled && (explicitOomSignature || cgroupOomKillObserved())) ||
|
|
398
|
+
// V8 aborts itself on heap exhaustion. SIGABRT alone is also authored
|
|
399
|
+
// program output, so 134 needs the explicit allocation signature.
|
|
400
|
+
(exitCode === 134 && explicitOomSignature));
|
|
397
401
|
const synthesizedError = runtimeLimitExceeded
|
|
398
402
|
? 'RUNTIME_LIMIT_EXCEEDED: ' + ${JSON.stringify(runtimeLimitMessage)}
|
|
399
403
|
: memoryAbort
|
|
@@ -580,6 +584,8 @@ export async function stageRunnerPayload(input: {
|
|
|
580
584
|
sandbox: RemoteRunnerPayloadSandbox;
|
|
581
585
|
bundlePromise: Promise<string>;
|
|
582
586
|
config: PlayRunnerExecutionConfig;
|
|
587
|
+
/** Provider-selected burst ceiling; the stored profile remains a reservation. */
|
|
588
|
+
memoryLimitMiB?: number;
|
|
583
589
|
workDir: string;
|
|
584
590
|
startedAt: number;
|
|
585
591
|
emitStage: DaytonaStageEmitter;
|
|
@@ -674,11 +680,12 @@ export async function stageRunnerPayload(input: {
|
|
|
674
680
|
materializedFiles: remoteMaterializedFiles,
|
|
675
681
|
context: remoteRuntimeContextForDaytona(input.config.context),
|
|
676
682
|
};
|
|
677
|
-
const
|
|
683
|
+
const sandboxRuntimeLimits = validatePlaySandboxRuntimeLimits(
|
|
678
684
|
input.config.context.sandboxRuntimeLimits ?? {
|
|
679
685
|
...STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS,
|
|
680
686
|
},
|
|
681
|
-
)
|
|
687
|
+
);
|
|
688
|
+
const runtimeLimitSeconds = sandboxRuntimeLimits.timeoutSeconds;
|
|
682
689
|
|
|
683
690
|
const envelopeUpload = input.bundlePromise.then((bundle) =>
|
|
684
691
|
timedRunnerPayloadUpload({
|
|
@@ -732,7 +739,12 @@ export async function stageRunnerPayload(input: {
|
|
|
732
739
|
const watchedRunnerCommand = [
|
|
733
740
|
'node',
|
|
734
741
|
'-e',
|
|
735
|
-
shellQuote(
|
|
742
|
+
shellQuote(
|
|
743
|
+
buildDaytonaRuntimeWatchdogSource(
|
|
744
|
+
sandboxRuntimeLimits,
|
|
745
|
+
input.memoryLimitMiB,
|
|
746
|
+
),
|
|
747
|
+
),
|
|
736
748
|
shellQuote(runnerPath),
|
|
737
749
|
shellQuote(configPath),
|
|
738
750
|
shellQuote(runtimeStartedPath),
|