deepline 0.3.451 → 0.3.453
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.ts +65 -0
- package/dist/bundling-sources/sdk/src/http.ts +2 -1
- package/dist/bundling-sources/sdk/src/index.ts +2 -0
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-capability.ts +63 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +5 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +49 -11
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/contract.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/runner-backend-adapter.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +3 -1
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +17 -2
- package/dist/cli/{auth-YLBWEMRW.mjs → auth-6CXS55CN.mjs} +4 -4
- package/dist/cli/auth-AICIA232.js +40 -0
- package/dist/cli/{billing-GWG5D3P6.js → billing-QC52XTAD.js} +87 -74
- package/dist/cli/{billing-DUFOEOPT.mjs → billing-SWLTV6PV.mjs} +18 -5
- package/dist/cli/{chunk-37CPEQBE.mjs → chunk-2LDU5BMG.mjs} +3 -3
- package/dist/cli/{chunk-JUCEEIEC.mjs → chunk-43HOSM2F.mjs} +1 -1
- package/dist/cli/{chunk-E7V5CRA2.mjs → chunk-6CTVXF6X.mjs} +8 -8
- package/dist/cli/{chunk-BJOVX7EB.mjs → chunk-7557D4FM.mjs} +2 -2
- package/dist/cli/chunk-BX343KU7.mjs +155 -0
- package/dist/cli/{chunk-7VRWERTM.js → chunk-DMTAFWMS.js} +84 -50
- package/dist/cli/{chunk-XLOXUW5Y.mjs → chunk-FS2RMEJ7.mjs} +1 -1
- package/dist/cli/{chunk-EJ6YI46S.js → chunk-HUDUN4AR.js} +2 -2
- package/dist/cli/{chunk-OKTCLFKM.mjs → chunk-IFBLLSGH.mjs} +5 -5
- package/dist/cli/{chunk-33EM4SMH.mjs → chunk-IWFI6FTJ.mjs} +4 -153
- package/dist/cli/{chunk-ZPV7DMAA.mjs → chunk-IXVABCNA.mjs} +1 -1
- package/dist/cli/{chunk-O3KVUHCG.js → chunk-JOF3B22H.js} +20 -20
- package/dist/cli/{chunk-6TFACCXN.js → chunk-KFKM5J2N.js} +2 -2
- package/dist/cli/{chunk-WLVGRU5A.mjs → chunk-KQD6EFPD.mjs} +2 -2
- package/dist/cli/{chunk-HSKLAPMD.js → chunk-MP35NE55.js} +26 -26
- package/dist/cli/chunk-NOHA3SZJ.js +155 -0
- package/dist/cli/{chunk-Z3DBS4IB.js → chunk-NSQZUUYB.js} +81 -81
- package/dist/cli/{chunk-BQQLTSGC.mjs → chunk-P4UQCYKH.mjs} +4 -4
- package/dist/cli/{chunk-CH2WDSBC.js → chunk-PJWXEUUH.js} +8 -8
- package/dist/cli/{chunk-L2IUGWV5.js → chunk-RG644LJU.js} +1 -1
- package/dist/cli/{chunk-5DUMNKQG.js → chunk-RNCIPLU5.js} +50 -50
- package/dist/cli/{chunk-WDOWAOYB.js → chunk-RTR2KUU6.js} +10 -10
- package/dist/cli/{chunk-4C7HPD57.mjs → chunk-SQUJHT7O.mjs} +1 -1
- package/dist/cli/{chunk-ZNDE2BTH.js → chunk-V6AZQ4JH.js} +16 -16
- package/dist/cli/{chunk-F2DW7DFE.js → chunk-V7S2RUVE.js} +8 -8
- package/dist/cli/{chunk-C4NPWUZY.js → chunk-VG6WESY7.js} +73 -222
- package/dist/cli/{chunk-6G6KX7I7.js → chunk-WTTHH2K3.js} +6 -6
- package/dist/cli/{chunk-JRPNCMMN.js → chunk-WWZ4YJ6J.js} +35 -35
- package/dist/cli/{chunk-PJYTV24I.mjs → chunk-X2LUT22I.mjs} +2 -2
- package/dist/cli/{chunk-YXXIFMXI.mjs → chunk-XH4QC5ZX.mjs} +2 -2
- package/dist/cli/{chunk-3HT47QPJ.mjs → chunk-XNN3OTGT.mjs} +2 -2
- package/dist/cli/{chunk-LPPAJJJN.mjs → chunk-XV4463XW.mjs} +35 -1
- package/dist/cli/{chunk-TFCLUWDQ.js → chunk-YU6IE234.js} +6 -6
- package/dist/cli/{chunk-RFPP4Q66.mjs → chunk-ZVBLECZX.mjs} +3 -3
- package/dist/cli/{csv-RL7WQD6Y.mjs → csv-FON4ZQKC.mjs} +3 -3
- package/dist/cli/{csv-4CHXZQXO.js → csv-WIQB5XWZ.js} +12 -12
- package/dist/cli/{db-ZDBAWV7B.mjs → db-3KA62DOQ.mjs} +4 -4
- package/dist/cli/{db-MRI5IM2A.js → db-VMDDODCN.js} +25 -25
- package/dist/cli/{describe-RRQUUJQ3.mjs → describe-LGDK77QI.mjs} +13 -12
- package/dist/cli/{describe-2FYKXM5B.js → describe-NTAAHCCX.js} +17 -16
- package/dist/cli/describe-core.d.mts +1 -1
- package/dist/cli/describe-core.d.ts +1 -1
- package/dist/cli/{executions-KDBD47A5.js → executions-OT2KNJDO.js} +6 -6
- package/dist/cli/{executions-RJL76TJS.mjs → executions-TM6AMTQ7.mjs} +4 -4
- package/dist/cli/{feedback-2CE24NHD.js → feedback-4HQGY3TO.js} +7 -7
- package/dist/cli/{feedback-KOYLXHYE.mjs → feedback-HWLUVFE2.mjs} +3 -3
- package/dist/cli/git-QIZWO5BA.js +24 -0
- package/dist/cli/{git-RDUHU6L6.mjs → git-TDJVSPE6.mjs} +4 -4
- package/dist/cli/index.js +133 -131
- package/dist/cli/index.mjs +39 -37
- package/dist/cli/{legacy-noops-7FOMGBMN.js → legacy-noops-XH3FDLWT.js} +7 -7
- package/dist/cli/{legacy-noops-4HS2LYP6.mjs → legacy-noops-YB2PES43.mjs} +4 -4
- package/dist/cli/{monitors-IJXNK5BL.js → monitors-E3QFEJKF.js} +276 -124
- package/dist/cli/{monitors-JLBTNBVU.mjs → monitors-KQDDMSDR.mjs} +156 -4
- package/dist/cli/{org-OWP6K4AA.mjs → org-7X2C7YKA.mjs} +4 -4
- package/dist/cli/{org-JL7SW6VY.js → org-PMTLR7VP.js} +66 -66
- package/dist/cli/{play-FNOVKU74.mjs → play-7FNEPSVR.mjs} +11 -10
- package/dist/cli/{play-LLNZWHT6.js → play-RH22Z3D6.js} +284 -283
- package/dist/cli/{providers-WBOEOKE7.mjs → providers-HOEDJNUK.mjs} +4 -4
- package/dist/cli/{providers-E4XIEUC7.js → providers-X5NY5IQH.js} +7 -7
- package/dist/cli/{quickstart-3FUHKGEY.js → quickstart-FI4A6VTV.js} +5 -5
- package/dist/cli/{quickstart-6G5G3BVA.mjs → quickstart-NCL7P2US.mjs} +3 -3
- package/dist/cli/search-6FUMJBIY.js +30 -0
- package/dist/cli/{search-CNMB4Z6M.mjs → search-UHT7ZNPO.mjs} +5 -5
- package/dist/cli/{secrets-5FY5APVK.mjs → secrets-D4ZB5RKB.mjs} +4 -4
- package/dist/cli/{secrets-BDSWOYAT.js → secrets-TT6J3SZJ.js} +13 -13
- package/dist/cli/{sessions-PMIKVPQN.mjs → sessions-HRLJ6SLL.mjs} +4 -4
- package/dist/cli/{sessions-B7T2CHYK.js → sessions-SRQQZMM7.js} +5 -5
- package/dist/cli/{settings-RXQJRRLR.js → settings-EJIKXLC7.js} +76 -75
- package/dist/cli/{settings-4TAYLTPR.mjs → settings-PJJYPWU3.mjs} +9 -8
- package/dist/cli/{setup-ZTMETGSO.js → setup-3FL77Z33.js} +43 -42
- package/dist/cli/{setup-LVUISLVO.mjs → setup-DNI6ENFD.mjs} +8 -7
- package/dist/cli/skills-DEKOSL7F.js +30 -0
- package/dist/cli/{skills-NSJ43Z5Q.mjs → skills-FO7MY2OE.mjs} +6 -5
- package/dist/cli/tools-E6XRW6PW.js +45 -0
- package/dist/cli/{tools-CFCKIGDY.mjs → tools-F72WONN3.mjs} +13 -12
- package/dist/cli/update-6M3CAS4T.js +32 -0
- package/dist/cli/{update-HYOCBXJO.mjs → update-JZU33TC5.mjs} +8 -7
- package/dist/cli/{workflow-U6S4SWTF.js → workflow-BGKC73V2.js} +15 -15
- package/dist/cli/{workflow-RKX45RJ4.mjs → workflow-PQYQXQPH.mjs} +5 -5
- package/dist/{client-CPRaigLC.d.ts → client-D6XhrO0f.d.ts} +26 -1
- package/dist/{client-DstDI5TV.d.mts → client-mRA_esYI.d.mts} +26 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -6
- package/dist/index.mjs +3 -3
- package/dist/install-integrity.json +82 -80
- package/dist/plays/play-description.d.mts +1 -1
- package/dist/plays/play-description.d.ts +1 -1
- package/dist/plays/run-request.d.mts +1 -1
- package/dist/plays/run-request.d.ts +1 -1
- 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/package.json +1 -1
- package/dist/cli/auth-WPQBEOES.js +0 -40
- package/dist/cli/git-DZ5GROPH.js +0 -24
- package/dist/cli/search-4ECC773X.js +0 -30
- package/dist/cli/skills-MIENPTOD.js +0 -29
- package/dist/cli/tools-CXJO5XSH.js +0 -44
- package/dist/cli/update-B2LQGEXF.js +0 -31
|
@@ -1285,6 +1285,18 @@ export type MonitorsListOptions = {
|
|
|
1285
1285
|
* plans, dependents) and it must not require an SDK bump to evolve.
|
|
1286
1286
|
*/
|
|
1287
1287
|
export type MonitorCheckResult = Record<string, unknown>;
|
|
1288
|
+
|
|
1289
|
+
export type MonitorPreviewOptions = {
|
|
1290
|
+
/** Sample size, 1-3. The server default is 3. */
|
|
1291
|
+
limit?: number;
|
|
1292
|
+
/** Reuse to recover one preview's result; a new key is a new, paid preview. */
|
|
1293
|
+
idempotencyKey?: string;
|
|
1294
|
+
};
|
|
1295
|
+
|
|
1296
|
+
/** A preview's sample and charge, plus the key that identifies it. */
|
|
1297
|
+
export type MonitorPreviewResult = Record<string, unknown> & {
|
|
1298
|
+
idempotency_key: string;
|
|
1299
|
+
};
|
|
1288
1300
|
export type MonitorDeployResult = Record<string, unknown>;
|
|
1289
1301
|
/** Field-level monitor capability spec returned by `client.monitors.get(...)`. */
|
|
1290
1302
|
export type MonitorSpec = {
|
|
@@ -1868,6 +1880,15 @@ export type MonitorsNamespace = {
|
|
|
1868
1880
|
) => Promise<MonitorsAvailableResult>;
|
|
1869
1881
|
/** Validate a monitor definition without deploying it (no spend). */
|
|
1870
1882
|
check: (definition: MonitorDefinition) => Promise<MonitorCheckResult>;
|
|
1883
|
+
/**
|
|
1884
|
+
* Sample a few recent matches for a definition before deploying it. Spends
|
|
1885
|
+
* Deepline credits per returned update. Reuse `idempotencyKey` to recover a
|
|
1886
|
+
* lost result without paying again; omit it for a new preview.
|
|
1887
|
+
*/
|
|
1888
|
+
preview: (
|
|
1889
|
+
definition: MonitorDefinition,
|
|
1890
|
+
options?: MonitorPreviewOptions,
|
|
1891
|
+
) => Promise<MonitorPreviewResult>;
|
|
1871
1892
|
/** Deploy a monitor from a definition. May spend Deepline credits. */
|
|
1872
1893
|
deploy: (
|
|
1873
1894
|
definition: MonitorDefinition,
|
|
@@ -2850,6 +2871,8 @@ export class DeeplineClient {
|
|
|
2850
2871
|
available: (toolIdOrOptions, options) =>
|
|
2851
2872
|
this.getMonitorsAvailable(toolIdOrOptions, options),
|
|
2852
2873
|
check: (definition) => this.checkMonitor(definition),
|
|
2874
|
+
preview: (definition, options) =>
|
|
2875
|
+
this.previewMonitor(definition, options),
|
|
2853
2876
|
deploy: (definition, options) => this.deployMonitor(definition, options),
|
|
2854
2877
|
sync: (definition, options) =>
|
|
2855
2878
|
options?.dryRun
|
|
@@ -6686,6 +6709,48 @@ export class DeeplineClient {
|
|
|
6686
6709
|
});
|
|
6687
6710
|
}
|
|
6688
6711
|
|
|
6712
|
+
/**
|
|
6713
|
+
* Run one paid preview. Prefer `client.monitors.preview(...)`.
|
|
6714
|
+
*
|
|
6715
|
+
* The key is fixed before the request is sent and returned on the result
|
|
6716
|
+
* and on any error (`error.idempotencyKey`), so a caller that loses the
|
|
6717
|
+
* response can repeat the call with it and get the original result without
|
|
6718
|
+
* a second charge. The submission is never replayed automatically.
|
|
6719
|
+
*/
|
|
6720
|
+
async previewMonitor(
|
|
6721
|
+
definition: MonitorDefinition,
|
|
6722
|
+
options?: MonitorPreviewOptions,
|
|
6723
|
+
): Promise<MonitorPreviewResult> {
|
|
6724
|
+
const idempotencyKey =
|
|
6725
|
+
options?.idempotencyKey ??
|
|
6726
|
+
`monitor-preview-${
|
|
6727
|
+
globalThis.crypto?.randomUUID?.() ??
|
|
6728
|
+
`${Date.now()}-${Math.random().toString(36).slice(2)}`
|
|
6729
|
+
}`;
|
|
6730
|
+
try {
|
|
6731
|
+
const result = await this.http.request<Record<string, unknown>>(
|
|
6732
|
+
'/api/v2/monitors/preview',
|
|
6733
|
+
{
|
|
6734
|
+
method: 'POST',
|
|
6735
|
+
body: {
|
|
6736
|
+
...definition,
|
|
6737
|
+
...(options?.limit === undefined ? {} : { limit: options.limit }),
|
|
6738
|
+
},
|
|
6739
|
+
headers: { 'Idempotency-Key': idempotencyKey },
|
|
6740
|
+
maxRetries: 0,
|
|
6741
|
+
exactUrlOnly: true,
|
|
6742
|
+
preserveRateLimitResponse: true,
|
|
6743
|
+
},
|
|
6744
|
+
);
|
|
6745
|
+
return { ...result, idempotency_key: idempotencyKey };
|
|
6746
|
+
} catch (error) {
|
|
6747
|
+
if (error && typeof error === 'object') {
|
|
6748
|
+
Object.assign(error, { idempotencyKey });
|
|
6749
|
+
}
|
|
6750
|
+
throw error;
|
|
6751
|
+
}
|
|
6752
|
+
}
|
|
6753
|
+
|
|
6689
6754
|
/**
|
|
6690
6755
|
* Deploy a monitor from a definition. `dryRun` validates via the check
|
|
6691
6756
|
* endpoint and returns the plan without deploying. Prefer
|
|
@@ -1036,7 +1036,8 @@ function isMonitorRateLimitEnvelope(parsed: unknown): boolean {
|
|
|
1036
1036
|
const response = asRecord(parsed);
|
|
1037
1037
|
const error = asRecord(response?.error);
|
|
1038
1038
|
return (
|
|
1039
|
-
error?.code === 'monitor_upstream_rate_limited'
|
|
1039
|
+
(error?.code === 'monitor_upstream_rate_limited' ||
|
|
1040
|
+
error?.code === 'monitor_preview_rate_limited') &&
|
|
1040
1041
|
typeof error.message === 'string'
|
|
1041
1042
|
);
|
|
1042
1043
|
}
|
|
@@ -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.453',
|
|
209
209
|
updateSummary: {
|
|
210
210
|
introducedIn: '0.3.90',
|
|
211
211
|
summary:
|
|
@@ -286,6 +286,15 @@ export type ProviderMonitorCapabilityDefinition = {
|
|
|
286
286
|
maxIds: number;
|
|
287
287
|
rateLimitId: string;
|
|
288
288
|
};
|
|
289
|
+
/**
|
|
290
|
+
* Optional paid sample: a few recent matches for the definition being
|
|
291
|
+
* considered, with nothing created. Only payloads whose `payloadField`
|
|
292
|
+
* value is listed can be previewed; every other payload of this capability,
|
|
293
|
+
* and every capability without this field, has no preview. `action` must
|
|
294
|
+
* also appear in `supportActions`, which is what registers it for
|
|
295
|
+
* execution.
|
|
296
|
+
*/
|
|
297
|
+
preview?: ProviderMonitorPreviewDescriptor;
|
|
289
298
|
// Declares that this monitor delivers data to Deepline via an inbound
|
|
290
299
|
// webhook callback (handled by the provider-callbacks route). Webhook
|
|
291
300
|
// subscription monitors are inherently inbound; native monitors must set
|
|
@@ -349,6 +358,43 @@ const UNLOCKED_ENTITLEMENT_STATUS: ProviderMonitorCapabilityEntitlementStatus =
|
|
|
349
358
|
locked: false,
|
|
350
359
|
};
|
|
351
360
|
|
|
361
|
+
export type ProviderMonitorPreviewDescriptor = {
|
|
362
|
+
action: string;
|
|
363
|
+
payloadField: string;
|
|
364
|
+
supportedValues: readonly string[];
|
|
365
|
+
defaultLimit: number;
|
|
366
|
+
maxLimit: number;
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
export type ProviderMonitorPreviewResolution =
|
|
370
|
+
| { available: true; descriptor: ProviderMonitorPreviewDescriptor }
|
|
371
|
+
| { available: false; reason: string };
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Whether this payload of this capability can be previewed. `null` means the
|
|
375
|
+
* capability declares no preview at all, so callers omit preview entirely
|
|
376
|
+
* rather than saying "unavailable" for every monitor.
|
|
377
|
+
*/
|
|
378
|
+
export function resolveProviderMonitorPreview(input: {
|
|
379
|
+
capability: Pick<
|
|
380
|
+
ProviderMonitorCapabilityDefinition,
|
|
381
|
+
'providerCapability' | 'runtime'
|
|
382
|
+
>;
|
|
383
|
+
payload: Record<string, unknown>;
|
|
384
|
+
}): ProviderMonitorPreviewResolution | null {
|
|
385
|
+
const descriptor = input.capability.runtime.preview;
|
|
386
|
+
if (!descriptor) return null;
|
|
387
|
+
const value = input.payload[descriptor.payloadField];
|
|
388
|
+
if (typeof value === 'string' && descriptor.supportedValues.includes(value)) {
|
|
389
|
+
return { available: true, descriptor };
|
|
390
|
+
}
|
|
391
|
+
const label = typeof value === 'string' && value ? value : 'this payload';
|
|
392
|
+
return {
|
|
393
|
+
available: false,
|
|
394
|
+
reason: `Preview isn't available for ${label} yet. Run monitors check, then deploy.`,
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
|
|
352
398
|
export type ProviderMonitorCapabilitySerializable = {
|
|
353
399
|
provider: string;
|
|
354
400
|
tool: string;
|
|
@@ -381,6 +427,11 @@ export type ProviderMonitorCapabilitySerializable = {
|
|
|
381
427
|
included_active_monitors?: number | null;
|
|
382
428
|
reason?: string;
|
|
383
429
|
};
|
|
430
|
+
/** Present only when the capability declares a paid preview. */
|
|
431
|
+
preview?: {
|
|
432
|
+
available_for: Record<string, string[]>;
|
|
433
|
+
max_limit: number;
|
|
434
|
+
};
|
|
384
435
|
next_commands: string[];
|
|
385
436
|
};
|
|
386
437
|
|
|
@@ -604,6 +655,18 @@ export function serializeProviderMonitorCapability(
|
|
|
604
655
|
: {}),
|
|
605
656
|
...(entitlement.reason ? { reason: entitlement.reason } : {}),
|
|
606
657
|
},
|
|
658
|
+
...(capability.runtime.preview
|
|
659
|
+
? {
|
|
660
|
+
preview: {
|
|
661
|
+
available_for: {
|
|
662
|
+
[capability.runtime.preview.payloadField]: [
|
|
663
|
+
...capability.runtime.preview.supportedValues,
|
|
664
|
+
],
|
|
665
|
+
},
|
|
666
|
+
max_limit: capability.runtime.preview.maxLimit,
|
|
667
|
+
},
|
|
668
|
+
}
|
|
669
|
+
: {}),
|
|
607
670
|
next_commands: [],
|
|
608
671
|
};
|
|
609
672
|
}
|
|
@@ -303,7 +303,11 @@ function createPlayRuntimeRequire(): ReturnType<typeof createRequire> {
|
|
|
303
303
|
}
|
|
304
304
|
const WAIT_CONFIG_POLL_MS = 25;
|
|
305
305
|
const WAIT_CONFIG_TIMEOUT_MS = 120_000;
|
|
306
|
-
|
|
306
|
+
// Outlasts the claim lease, because an unanswered heartbeat says nothing about
|
|
307
|
+
// the park. A stall shorter than the lease keeps this sandbox, and a longer one
|
|
308
|
+
// reaches the heartbeat loop's own guard and is reported as an outage.
|
|
309
|
+
export const RUNNER_EXECUTION_ACK_TIMEOUT_MS =
|
|
310
|
+
(RUNTIME_RELIABILITY_POLICY.worker.claimLeaseSeconds + 30) * 1_000;
|
|
307
311
|
const RUNNER_RUNTIME_CONTROL_MAX_ATTEMPTS =
|
|
308
312
|
RUNTIME_RELIABILITY_POLICY.gateway.runnerControlMaxAttempts;
|
|
309
313
|
const RUNNER_RUNTIME_CONTROL_RETRY_DELAYS_MS = [100, 250] as const;
|
package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts
CHANGED
|
@@ -37,6 +37,12 @@ const DAYTONA_CREATE_RETRY_DELAYS_MS = [0, 500, 1_500] as const;
|
|
|
37
37
|
const DAYTONA_TIMED_OUT_CREATE_RECONCILE_DELAYS_MS = [
|
|
38
38
|
0, 1_000, 3_000, 6_000, 12_000, 24_000, 36_000,
|
|
39
39
|
] as const;
|
|
40
|
+
// A reservation can outlive a create that was refused, or one never sent because
|
|
41
|
+
// the scheduler stalled between committing the reservation and acknowledging it.
|
|
42
|
+
// This delay lets a healthy owner finish its create and reconcile ladder first.
|
|
43
|
+
// It is not a fence: a stalled owner can outlast it, so name uniqueness and the
|
|
44
|
+
// attempt fences on abandon and promotion keep custody safe.
|
|
45
|
+
const DAYTONA_ABSENT_OPERATION_RECREATE_AFTER_MS = 3 * 60_000;
|
|
40
46
|
// Explicit runner deadline + scheduler GC own the normal lifecycle. Daytona's
|
|
41
47
|
// inactivity stop is a wider crash backstop measured from sandbox creation, so
|
|
42
48
|
// setup time cannot consume the terminal-flush grace.
|
|
@@ -671,6 +677,7 @@ async function createRetriedOneShotDaytonaSandbox(input: {
|
|
|
671
677
|
leaseId: string;
|
|
672
678
|
providerOperationToken: string | null;
|
|
673
679
|
resumeExistingProviderOperation?: boolean;
|
|
680
|
+
existingProviderOperationAgeMs?: number;
|
|
674
681
|
}>;
|
|
675
682
|
releaseSandboxCapacity?: (leaseId: string) => Promise<void>;
|
|
676
683
|
nextProviderAttempt: () => number;
|
|
@@ -700,6 +707,7 @@ async function createRetriedOneShotDaytonaSandbox(input: {
|
|
|
700
707
|
});
|
|
701
708
|
const reservation = await input.reserveSandboxCapacity?.(attempt);
|
|
702
709
|
const sandboxName = daytonaSandboxName(reservation?.providerOperationToken);
|
|
710
|
+
let recreatedAfter: TimedOutDaytonaSandboxReconcileObserved | null = null;
|
|
703
711
|
if (reservation?.resumeExistingProviderOperation) {
|
|
704
712
|
if (!reservation.providerOperationToken) {
|
|
705
713
|
throw new DaytonaSandboxTransitionPendingError(sandboxName);
|
|
@@ -740,17 +748,32 @@ async function createRetriedOneShotDaytonaSandbox(input: {
|
|
|
740
748
|
);
|
|
741
749
|
}
|
|
742
750
|
// Neither absence nor an ongoing transition proves that create cannot
|
|
743
|
-
// commit
|
|
744
|
-
// detail only records which of the two
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
751
|
+
// commit, so inside the create window retain the durable identity and
|
|
752
|
+
// its capacity reservation. The detail only records which of the two
|
|
753
|
+
// Daytona reported, for the log.
|
|
754
|
+
const operationAgeMs = reservation.existingProviderOperationAgeMs ?? 0;
|
|
755
|
+
if (
|
|
756
|
+
reconciliation.observed.last.lookup !== 'not_found' ||
|
|
757
|
+
operationAgeMs < DAYTONA_ABSENT_OPERATION_RECREATE_AFTER_MS
|
|
758
|
+
) {
|
|
759
|
+
throw new DaytonaSandboxTransitionPendingError(
|
|
760
|
+
sandboxName,
|
|
761
|
+
daytonaTransitionPendingLogDetail({
|
|
762
|
+
phase: 'resume',
|
|
763
|
+
observed: reconciliation.observed,
|
|
764
|
+
providerAttempt: attempt,
|
|
765
|
+
launchOutcome: null,
|
|
766
|
+
}),
|
|
767
|
+
);
|
|
768
|
+
}
|
|
769
|
+
// Daytona's own name uniqueness fences this: the same identity under the
|
|
770
|
+
// same reservation cannot become a second sandbox. A create that lands
|
|
771
|
+
// first surfaces as a conflict, which the reconcile below adopts by name.
|
|
772
|
+
input.emitStage('create:recreate_absent_operation', {
|
|
773
|
+
attempt,
|
|
774
|
+
operationAgeMs,
|
|
775
|
+
});
|
|
776
|
+
recreatedAfter = reconciliation.observed;
|
|
754
777
|
}
|
|
755
778
|
let sandbox: DaytonaSandbox;
|
|
756
779
|
try {
|
|
@@ -895,6 +918,20 @@ async function createRetriedOneShotDaytonaSandbox(input: {
|
|
|
895
918
|
{ cause: error },
|
|
896
919
|
);
|
|
897
920
|
}
|
|
921
|
+
if (recreatedAfter) {
|
|
922
|
+
// Refusing this send says nothing about an earlier send of the identity,
|
|
923
|
+
// so keep its reservation and resume the same name.
|
|
924
|
+
await recordCreateFailure();
|
|
925
|
+
throw new DaytonaSandboxTransitionPendingError(
|
|
926
|
+
sandboxName,
|
|
927
|
+
daytonaTransitionPendingLogDetail({
|
|
928
|
+
phase: 'resume',
|
|
929
|
+
observed: recreatedAfter,
|
|
930
|
+
providerAttempt: attempt,
|
|
931
|
+
launchOutcome: null,
|
|
932
|
+
}),
|
|
933
|
+
);
|
|
934
|
+
}
|
|
898
935
|
if (reservation) {
|
|
899
936
|
await input.releaseSandboxCapacity?.(reservation.leaseId);
|
|
900
937
|
}
|
|
@@ -1098,6 +1135,7 @@ export function createOneShotDaytonaSandboxLifecycle(input: {
|
|
|
1098
1135
|
leaseId: string;
|
|
1099
1136
|
providerOperationToken: string | null;
|
|
1100
1137
|
resumeExistingProviderOperation?: boolean;
|
|
1138
|
+
existingProviderOperationAgeMs?: number;
|
|
1101
1139
|
}>;
|
|
1102
1140
|
releaseSandboxCapacity?: (leaseId: string) => Promise<void>;
|
|
1103
1141
|
startAdmission?: DaytonaSandboxStartAdmission;
|
|
@@ -245,6 +245,8 @@ export type SandboxExecutionAdmission = {
|
|
|
245
245
|
providerOperationToken?: string | null;
|
|
246
246
|
/** Resume the existing durable provider operation before any new create. */
|
|
247
247
|
resumeExistingProviderOperation?: boolean;
|
|
248
|
+
/** Scheduler-clock age of the operation being resumed. */
|
|
249
|
+
existingProviderOperationAgeMs?: number;
|
|
248
250
|
}
|
|
249
251
|
| { kind: 'pre_code_deferred'; reason: SandboxPreCodeDeferralReason }
|
|
250
252
|
>;
|
|
@@ -310,6 +312,8 @@ export type SandboxExecutionLifecycle = {
|
|
|
310
312
|
providerOperationToken?: string | null;
|
|
311
313
|
/** Resume the existing durable provider operation before any new create. */
|
|
312
314
|
resumeExistingProviderOperation?: boolean;
|
|
315
|
+
/** Scheduler-clock age of the operation being resumed. */
|
|
316
|
+
existingProviderOperationAgeMs?: number;
|
|
313
317
|
}
|
|
314
318
|
| { kind: 'pre_code_deferred'; reason: SandboxPreCodeDeferralReason }
|
|
315
319
|
>;
|
package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/runner-backend-adapter.ts
CHANGED
|
@@ -188,6 +188,12 @@ function createRunnerCallbacks(input: {
|
|
|
188
188
|
...(outcome.resumeExistingProviderOperation === true
|
|
189
189
|
? { resumeExistingProviderOperation: true }
|
|
190
190
|
: {}),
|
|
191
|
+
...(outcome.existingProviderOperationAgeMs === undefined
|
|
192
|
+
? {}
|
|
193
|
+
: {
|
|
194
|
+
existingProviderOperationAgeMs:
|
|
195
|
+
outcome.existingProviderOperationAgeMs,
|
|
196
|
+
}),
|
|
191
197
|
};
|
|
192
198
|
},
|
|
193
199
|
releaseSandboxCapacity: async (leaseId) => {
|
package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts
CHANGED
|
@@ -4338,13 +4338,15 @@ async function executeAssignedAbsurdAttempt(input: {
|
|
|
4338
4338
|
providerOperationToken: reserved.providerOperationToken,
|
|
4339
4339
|
resumeExistingProviderOperation:
|
|
4340
4340
|
reserved.resumeExistingProviderOperation,
|
|
4341
|
+
existingProviderOperationAgeMs:
|
|
4342
|
+
reserved.existingProviderOperationAgeMs,
|
|
4341
4343
|
};
|
|
4342
4344
|
},
|
|
4343
4345
|
async releaseCapacity({ leaseId }) {
|
|
4344
4346
|
await deps.runWithClient((client) =>
|
|
4345
4347
|
abandonRuntimeSandboxOperationReservation(
|
|
4346
4348
|
client,
|
|
4347
|
-
{ operationKey: leaseId },
|
|
4349
|
+
{ operationKey: leaseId, attempt: generation },
|
|
4348
4350
|
options,
|
|
4349
4351
|
),
|
|
4350
4352
|
);
|
|
@@ -286,6 +286,11 @@ export async function reserveRuntimeSandboxCapacityLease(
|
|
|
286
286
|
activeLeases: number;
|
|
287
287
|
wouldDefer: boolean;
|
|
288
288
|
resumeExistingProviderOperation: boolean;
|
|
289
|
+
/**
|
|
290
|
+
* Database-clock age of a resumed operation. Absent on a same-key race and
|
|
291
|
+
* once the lease expires, when a new sandbox could no longer be promoted.
|
|
292
|
+
*/
|
|
293
|
+
existingProviderOperationAgeMs?: number;
|
|
289
294
|
}
|
|
290
295
|
| { granted: false; limit: number; activeLeases: number }
|
|
291
296
|
> {
|
|
@@ -316,6 +321,7 @@ export async function reserveRuntimeSandboxCapacityLease(
|
|
|
316
321
|
provider_operation_token: string | null;
|
|
317
322
|
attempt: number;
|
|
318
323
|
environment: 'preview' | 'production';
|
|
324
|
+
age_ms: number | null;
|
|
319
325
|
}>;
|
|
320
326
|
existing_operation: {
|
|
321
327
|
org_id: string;
|
|
@@ -361,7 +367,10 @@ export async function reserveRuntimeSandboxCapacityLease(
|
|
|
361
367
|
SELECT jsonb_agg(pending)
|
|
362
368
|
FROM (
|
|
363
369
|
SELECT lease.lease_id, operation.provider_operation_token,
|
|
364
|
-
operation.attempt, operation.environment
|
|
370
|
+
operation.attempt, operation.environment,
|
|
371
|
+
CASE WHEN lease.expires_at > clock_timestamp() THEN
|
|
372
|
+
extract(epoch FROM clock_timestamp() - operation.created_at) * 1000
|
|
373
|
+
END AS age_ms
|
|
365
374
|
FROM ${operations} AS operation
|
|
366
375
|
JOIN ${leases} AS lease ON lease.lease_id = operation.operation_key
|
|
367
376
|
WHERE $6::boolean
|
|
@@ -503,6 +512,9 @@ export async function reserveRuntimeSandboxCapacityLease(
|
|
|
503
512
|
activeLeases,
|
|
504
513
|
wouldDefer,
|
|
505
514
|
resumeExistingProviderOperation: true,
|
|
515
|
+
...(pendingOperation.age_ms === null
|
|
516
|
+
? {}
|
|
517
|
+
: { existingProviderOperationAgeMs: Number(pendingOperation.age_ms) }),
|
|
506
518
|
};
|
|
507
519
|
}
|
|
508
520
|
}
|
|
@@ -874,7 +886,8 @@ export async function releaseRuntimeSandboxCapacityLease(
|
|
|
874
886
|
*/
|
|
875
887
|
export async function abandonRuntimeSandboxOperationReservation(
|
|
876
888
|
client: PostgresSchedulerQueryClient,
|
|
877
|
-
|
|
889
|
+
/** With `attempt`, an operation a newer attempt has adopted is left alone. */
|
|
890
|
+
input: { operationKey: string; attempt?: number },
|
|
878
891
|
options?: Pick<PostgresSchedulerOptions, 'schema'>,
|
|
879
892
|
): Promise<boolean> {
|
|
880
893
|
const { leases, operations, runs } = schemaTables(options);
|
|
@@ -899,6 +912,7 @@ export async function abandonRuntimeSandboxOperationReservation(
|
|
|
899
912
|
updated_at = clock_timestamp()
|
|
900
913
|
WHERE operation.operation_key = $1
|
|
901
914
|
AND operation.state = $3
|
|
915
|
+
AND ($4::integer IS NULL OR operation.attempt <= $4)
|
|
902
916
|
AND EXISTS (SELECT 1 FROM eligible_lease)
|
|
903
917
|
RETURNING operation.operation_key
|
|
904
918
|
), released AS (
|
|
@@ -915,6 +929,7 @@ export async function abandonRuntimeSandboxOperationReservation(
|
|
|
915
929
|
assertId(input.operationKey, 'operationKey'),
|
|
916
930
|
RuntimeSandboxOperationState.Abandoned,
|
|
917
931
|
RuntimeSandboxOperationState.Reserved,
|
|
932
|
+
input.attempt ?? null,
|
|
918
933
|
],
|
|
919
934
|
);
|
|
920
935
|
return result.rows.length === 1;
|
|
@@ -13,13 +13,13 @@ import {
|
|
|
13
13
|
reportSetupCompleted,
|
|
14
14
|
resolvePendingAuthClaimForResume,
|
|
15
15
|
statusBannerLine
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-7557D4FM.mjs";
|
|
17
|
+
import "./chunk-FS2RMEJ7.mjs";
|
|
18
|
+
import "./chunk-X2LUT22I.mjs";
|
|
19
19
|
import "./chunk-4QF2K7TM.mjs";
|
|
20
20
|
import "./chunk-DLIRSHV6.mjs";
|
|
21
21
|
import "./chunk-HBL4PM5Q.mjs";
|
|
22
|
-
import "./chunk-
|
|
22
|
+
import "./chunk-IXVABCNA.mjs";
|
|
23
23
|
import "./chunk-WZYKRD7T.mjs";
|
|
24
24
|
import "./chunk-KRD6H754.mjs";
|
|
25
25
|
export {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
var _chunkRNCIPLU5js = require('./chunk-RNCIPLU5.js');
|
|
17
|
+
require('./chunk-WTTHH2K3.js');
|
|
18
|
+
require('./chunk-RTR2KUU6.js');
|
|
19
|
+
require('./chunk-ALJJRZNJ.js');
|
|
20
|
+
require('./chunk-XNYIZMNQ.js');
|
|
21
|
+
require('./chunk-DIAWYWT5.js');
|
|
22
|
+
require('./chunk-RG644LJU.js');
|
|
23
|
+
require('./chunk-OG64RBAC.js');
|
|
24
|
+
require('./chunk-COGTRVWW.js');
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
exports.EXIT_WORKSPACE_MISMATCH = _chunkRNCIPLU5js.EXIT_WORKSPACE_MISMATCH; exports.authStatusLine = _chunkRNCIPLU5js.authStatusLine; exports.clearPendingClaim = _chunkRNCIPLU5js.clearPendingClaim; exports.clearSatisfiedPendingClaim = _chunkRNCIPLU5js.clearSatisfiedPendingClaim; exports.handleRegister = _chunkRNCIPLU5js.handleRegister; exports.handleStatus = _chunkRNCIPLU5js.handleStatus; exports.handleWait = _chunkRNCIPLU5js.handleWait; exports.httpJson = _chunkRNCIPLU5js.httpJson; exports.readPendingAuthClaim = _chunkRNCIPLU5js.readPendingAuthClaim; exports.readStatusBanner = _chunkRNCIPLU5js.readStatusBanner; exports.registerAuthCommands = _chunkRNCIPLU5js.registerAuthCommands; exports.reportSetupCompleted = _chunkRNCIPLU5js.reportSetupCompleted; exports.resolvePendingAuthClaimForResume = _chunkRNCIPLU5js.resolvePendingAuthClaimForResume; exports.statusBannerLine = _chunkRNCIPLU5js.statusBannerLine;
|