deepline 0.3.452 → 0.3.454
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/sdk/src/types.ts +2 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-capability.ts +63 -0
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +13 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-launch-transport.ts +83 -4
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +11 -3
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +16 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-runtime-watchdog.ts +20 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +77 -12
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/modal.ts +5 -2
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +254 -64
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +11 -0
- package/dist/cli/auth-GUZWKNXM.js +40 -0
- package/dist/cli/{auth-DKZLB6GN.mjs → auth-YNPT3IER.mjs} +4 -4
- package/dist/cli/{billing-DOFXWAZR.mjs → billing-TLRVAOXB.mjs} +18 -5
- package/dist/cli/{billing-CN3XSVER.js → billing-VXIIND6T.js} +87 -74
- package/dist/cli/{chunk-TXN27XQQ.mjs → chunk-27NNEBIS.mjs} +2 -2
- package/dist/cli/chunk-2I7GE7KB.mjs +155 -0
- package/dist/cli/{chunk-M4FFNUF4.js → chunk-33FEF4RH.js} +50 -50
- package/dist/cli/{chunk-FIQ2F5LA.mjs → chunk-5GJH2BYN.mjs} +2 -2
- package/dist/cli/{chunk-ELULDUX3.mjs → chunk-5OQMUDPM.mjs} +1 -1
- package/dist/cli/{chunk-5DRGDSJL.js → chunk-6JY2NGJN.js} +26 -26
- package/dist/cli/chunk-7ICOQRW5.js +155 -0
- package/dist/cli/{chunk-7JSZOUNU.js → chunk-7V3OKSB2.js} +1 -1
- package/dist/cli/{chunk-74BPYDDG.js → chunk-BUYQU7TB.js} +8 -8
- package/dist/cli/{chunk-RNM4HG3W.mjs → chunk-CPXT4KPC.mjs} +3 -3
- package/dist/cli/{chunk-KQUDU3ZE.mjs → chunk-DCZSJON4.mjs} +2 -2
- package/dist/cli/{chunk-2GMAPSJU.mjs → chunk-EXWKHMMP.mjs} +5 -5
- package/dist/cli/{chunk-ZH6HFV7Y.js → chunk-FKGXZXRP.js} +8 -8
- package/dist/cli/{chunk-UGPGB4C6.mjs → chunk-G6ZOZQXT.mjs} +4 -153
- package/dist/cli/{chunk-L2GATUZK.js → chunk-IJ5WCZ32.js} +20 -20
- package/dist/cli/{chunk-JT4ZSWBK.js → chunk-KPPL2WNH.js} +16 -16
- package/dist/cli/{chunk-X4IMX5AO.mjs → chunk-LVHRP7XM.mjs} +4 -4
- package/dist/cli/{chunk-RFDIXLRX.mjs → chunk-LWYOJG66.mjs} +1 -1
- package/dist/cli/{chunk-L6YCGSL4.js → chunk-P5IQ6LIK.js} +35 -35
- package/dist/cli/{chunk-2VERHTKO.js → chunk-QLMQ2NAQ.js} +2 -2
- package/dist/cli/{chunk-PBQSX6ES.mjs → chunk-RDAUQGPG.mjs} +1 -1
- package/dist/cli/{chunk-7OI33KE5.js → chunk-S2PO3X5R.js} +2 -2
- package/dist/cli/{chunk-ZKGK2JU3.js → chunk-SJH66N73.js} +6 -6
- package/dist/cli/{chunk-SM5RZ5JC.mjs → chunk-TECW24CR.mjs} +2 -2
- package/dist/cli/{chunk-R7YZKHN5.mjs → chunk-THJ7ORNM.mjs} +3 -3
- package/dist/cli/{chunk-POSAVPQZ.mjs → chunk-U72KDMYJ.mjs} +2 -2
- package/dist/cli/{chunk-JJOSUZMS.mjs → chunk-UT6W675P.mjs} +1 -1
- package/dist/cli/{chunk-G5BMPTZD.js → chunk-VHGGHRGY.js} +81 -81
- package/dist/cli/{chunk-ETFVH7PO.js → chunk-VXBEHDM6.js} +10 -10
- package/dist/cli/{chunk-WW63S4RC.js → chunk-WONLZMDF.js} +6 -6
- package/dist/cli/{chunk-QK65KBWN.mjs → chunk-YETNOEAZ.mjs} +8 -8
- package/dist/cli/{chunk-YWL4ULLT.js → chunk-YPYR4ACF.js} +73 -222
- package/dist/cli/{chunk-2SICEJBN.mjs → chunk-YXCLG3KB.mjs} +35 -1
- package/dist/cli/{chunk-J5O4AXSO.js → chunk-Z5PQSTYX.js} +84 -50
- package/dist/cli/{csv-N25FMDZQ.js → csv-BSKJR3CR.js} +12 -12
- package/dist/cli/{csv-QUNUQZYC.mjs → csv-I4CAAV6A.mjs} +3 -3
- package/dist/cli/{db-WYWDUYXS.mjs → db-EQP24K3B.mjs} +4 -4
- package/dist/cli/{db-2SGG56WR.js → db-RA3IL6MC.js} +25 -25
- package/dist/cli/{describe-QQ2XL6PV.js → describe-62KPTIFH.js} +17 -16
- package/dist/cli/{describe-4RBUIHR7.mjs → describe-EZDVJDPQ.mjs} +13 -12
- package/dist/cli/describe-core.d.mts +1 -1
- package/dist/cli/describe-core.d.ts +1 -1
- package/dist/cli/{executions-YLJHAHHX.js → executions-2HBBXRPM.js} +6 -6
- package/dist/cli/{executions-WOBIMQ7H.mjs → executions-W5KR56KP.mjs} +4 -4
- package/dist/cli/{feedback-VCGVROTY.mjs → feedback-6UTOLSFP.mjs} +3 -3
- package/dist/cli/{feedback-D653FAXY.js → feedback-CVYS7ZPV.js} +7 -7
- package/dist/cli/{git-SZ6RSLFN.mjs → git-JXH64LI4.mjs} +4 -4
- package/dist/cli/git-U6FMVAAM.js +24 -0
- package/dist/cli/index.js +133 -131
- package/dist/cli/index.mjs +39 -37
- package/dist/cli/{legacy-noops-TXZ75CWS.js → legacy-noops-5XTXIPU2.js} +7 -7
- package/dist/cli/{legacy-noops-UGLTI2ZY.mjs → legacy-noops-NYMLGQNX.mjs} +4 -4
- package/dist/cli/{monitors-HLIW4AIL.mjs → monitors-CEU6SP2B.mjs} +156 -4
- package/dist/cli/{monitors-VC6YSBYX.js → monitors-J6HAQLX2.js} +276 -124
- package/dist/cli/{org-I3VQDIGZ.js → org-CYE3DCIT.js} +66 -66
- package/dist/cli/{org-X4MVTSKM.mjs → org-RRKAJM5V.mjs} +4 -4
- package/dist/cli/{play-7TLGGN66.js → play-NJDW74YH.js} +284 -283
- package/dist/cli/{play-EAYGEAMI.mjs → play-PXISXZ2P.mjs} +11 -10
- package/dist/cli/{providers-MBTMUEGX.mjs → providers-6QGGDOWK.mjs} +4 -4
- package/dist/cli/{providers-IZ3YWZ4E.js → providers-JE3MUBYK.js} +7 -7
- package/dist/cli/{quickstart-MBDEV4RJ.js → quickstart-AQBBOFQL.js} +5 -5
- package/dist/cli/{quickstart-MDW2NMAS.mjs → quickstart-MKJ7TYQZ.mjs} +3 -3
- package/dist/cli/{search-4PQZYRQO.mjs → search-6PKFZ2JD.mjs} +5 -5
- package/dist/cli/search-EJGRNQQK.js +30 -0
- package/dist/cli/{secrets-3S7KUS2H.js → secrets-IKGJYESD.js} +13 -13
- package/dist/cli/{secrets-S55UCYYR.mjs → secrets-QBWRVZCT.mjs} +4 -4
- package/dist/cli/{sessions-UEHVIB6W.js → sessions-462I5YEQ.js} +5 -5
- package/dist/cli/{sessions-T6XVN737.mjs → sessions-SVYTBNRJ.mjs} +4 -4
- package/dist/cli/{settings-CGP7XMJZ.mjs → settings-FH4XZ7FE.mjs} +9 -8
- package/dist/cli/{settings-MYAUWNTF.js → settings-WHLTLPXZ.js} +76 -75
- package/dist/cli/{setup-5Z5HAWEG.js → setup-IKTCP3QB.js} +43 -42
- package/dist/cli/{setup-U66NZQXB.mjs → setup-ISCNCB4W.mjs} +8 -7
- package/dist/cli/{skills-2JS3SNFA.mjs → skills-HITZS5EJ.mjs} +6 -5
- package/dist/cli/skills-LC2YKUSO.js +30 -0
- package/dist/cli/{tools-G3VYZKTO.mjs → tools-SQUTVLPO.mjs} +13 -12
- package/dist/cli/tools-Y55OXE72.js +45 -0
- package/dist/cli/{update-C7CLWWIW.mjs → update-AFYEREBX.mjs} +8 -7
- package/dist/cli/update-Q3I6MSEQ.js +32 -0
- package/dist/cli/{workflow-TBKVIN4S.js → workflow-AAOOROIR.js} +15 -15
- package/dist/cli/{workflow-EUMRVXU7.mjs → workflow-VBCZPKVF.mjs} +5 -5
- package/dist/{client-CPRaigLC.d.ts → client-BV7tC6oq.d.ts} +28 -1
- package/dist/{client-DstDI5TV.d.mts → client-Ct6OBj9Y.d.mts} +28 -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-36DQP46D.js +0 -40
- package/dist/cli/git-T6LBJEY6.js +0 -24
- package/dist/cli/search-5B4ZM7VS.js +0 -30
- package/dist/cli/skills-JXPQFJAJ.js +0 -29
- package/dist/cli/tools-RHRJ4SLY.js +0 -44
- package/dist/cli/update-5YBPJ3EQ.js +0 -31
|
@@ -24,7 +24,10 @@ import {
|
|
|
24
24
|
} from '../../modal-runtime-config';
|
|
25
25
|
import type { PlaySandboxRuntimeLimits } from '../../../plays/sandbox-runtime-limits';
|
|
26
26
|
import { validateDaytonaExecutionContext } from './daytona-lifecycle';
|
|
27
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
stageRunnerPayload,
|
|
29
|
+
withRunnerSandboxProvider,
|
|
30
|
+
} from './daytona-payload-transport';
|
|
28
31
|
import { captureDetachedDaytonaRunnerReadinessBaseline } from './daytona-session-execution';
|
|
29
32
|
import {
|
|
30
33
|
isPlayRunRecoveryError,
|
|
@@ -594,7 +597,7 @@ export const modalPlayRunnerBackend: PlayRunnerBackend = {
|
|
|
594
597
|
}),
|
|
595
598
|
},
|
|
596
599
|
bundlePromise: buildPlayRunnerBundle(),
|
|
597
|
-
config,
|
|
600
|
+
config: withRunnerSandboxProvider(config, 'modal'),
|
|
598
601
|
workDir: modalConfig.workdir,
|
|
599
602
|
startedAt,
|
|
600
603
|
emitStage: (stage, extra) =>
|
package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts
CHANGED
|
@@ -839,12 +839,9 @@ export type AbsurdRuntimeWorkerDeps = {
|
|
|
839
839
|
* detached runner that lost its gateway. This never executes customer code:
|
|
840
840
|
* it can only recover the result the sandbox already emitted before exit.
|
|
841
841
|
*/
|
|
842
|
-
inspectDetachedRunner?: (
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
// Written by the runner, possibly an older build: readers default it.
|
|
846
|
-
diagnosis?: { stage: string; detail: string | null };
|
|
847
|
-
} | null>;
|
|
842
|
+
inspectDetachedRunner?: (
|
|
843
|
+
suspension: DetachedRunnerSuspension,
|
|
844
|
+
) => Promise<DetachedRunnerInspection | null>;
|
|
848
845
|
readSandboxCrashDiagnostic?: (
|
|
849
846
|
request: PostgresSchedulerSandboxCrashDiagnosticRequest,
|
|
850
847
|
routingDomain: string | null,
|
|
@@ -1332,6 +1329,49 @@ function signalData(
|
|
|
1332
1329
|
}
|
|
1333
1330
|
|
|
1334
1331
|
const LIVENESS_CONFIRMATION_SLICES_PER_CADENCE = 4;
|
|
1332
|
+
const LIVENESS_RECHECK_INTERVAL_CADENCES = 2;
|
|
1333
|
+
const LIVENESS_RECHECK_MIN_INTERVAL_MS = 1_000;
|
|
1334
|
+
const LIVENESS_PARK_MAX_REARMS_PER_WAKE = 8;
|
|
1335
|
+
const LIVENESS_REPLAY_READ_REUSE_MS = 100;
|
|
1336
|
+
|
|
1337
|
+
/**
|
|
1338
|
+
* Suspensions the park proved gone in this handler invocation, with the
|
|
1339
|
+
* inspection that proved it when this leg made one. The resolver reuses it
|
|
1340
|
+
* rather than asking the provider twice, and honors it rather than re-deciding:
|
|
1341
|
+
* re-parking on a disagreeing inspection would meet the same cached proof and
|
|
1342
|
+
* spin.
|
|
1343
|
+
*/
|
|
1344
|
+
const detachedRunnerProvenGone = new WeakMap<
|
|
1345
|
+
DetachedRunnerSuspension,
|
|
1346
|
+
DetachedRunnerInspection | null
|
|
1347
|
+
>();
|
|
1348
|
+
|
|
1349
|
+
type DetachedRunnerInspection = {
|
|
1350
|
+
exitCode: number | null;
|
|
1351
|
+
result: PlayRunnerResult | null;
|
|
1352
|
+
// Written by the runner, possibly an older build: readers default it.
|
|
1353
|
+
diagnosis?: { stage: string; detail: string | null };
|
|
1354
|
+
};
|
|
1355
|
+
|
|
1356
|
+
/**
|
|
1357
|
+
* Whether a provider inspection proves the runner can no longer act. A stale
|
|
1358
|
+
* heartbeat alone never does: the gateway can lose heartbeats from a healthy
|
|
1359
|
+
* runner, and the provider can be unreachable while the sandbox still runs.
|
|
1360
|
+
* Only a recoverable result, a recorded process exit, or a missing or stopped
|
|
1361
|
+
* sandbox counts. Anything else leaves the run parked, bounded by its hard
|
|
1362
|
+
* ceiling.
|
|
1363
|
+
*/
|
|
1364
|
+
export function detachedRunnerInspectionProvesGone(
|
|
1365
|
+
inspection: DetachedRunnerInspection | null,
|
|
1366
|
+
): boolean {
|
|
1367
|
+
if (!inspection) return false;
|
|
1368
|
+
if (inspection.result && inspection.result.status !== 'suspended') {
|
|
1369
|
+
return true;
|
|
1370
|
+
}
|
|
1371
|
+
if (inspection.exitCode !== null) return true;
|
|
1372
|
+
const stage = inspection.diagnosis?.stage;
|
|
1373
|
+
return stage === 'sandbox_missing' || stage === 'sandbox_stopped';
|
|
1374
|
+
}
|
|
1335
1375
|
|
|
1336
1376
|
/**
|
|
1337
1377
|
* A stale heartbeat proves a lost runner only if the runner could have renewed
|
|
@@ -1340,8 +1380,11 @@ const LIVENESS_CONFIRMATION_SLICES_PER_CADENCE = 4;
|
|
|
1340
1380
|
* counts only short sleep slices that woke on time, and decides after two
|
|
1341
1381
|
* heartbeat cadences of such observed availability. A late slice counts for
|
|
1342
1382
|
* nothing. Slice times and lateness are checkpointed, so replay is
|
|
1343
|
-
* deterministic.
|
|
1344
|
-
*
|
|
1383
|
+
* deterministic.
|
|
1384
|
+
*
|
|
1385
|
+
* Silence is still not loss, so the worker then asks the provider, and keeps
|
|
1386
|
+
* asking on a paced schedule until the provider proves the runner gone, the
|
|
1387
|
+
* runner responds, or the hard ceiling arrives.
|
|
1345
1388
|
*/
|
|
1346
1389
|
async function confirmDetachedRunnerSilence(input: {
|
|
1347
1390
|
ctx: AbsurdSuspensionContext;
|
|
@@ -1349,6 +1392,79 @@ async function confirmDetachedRunnerSilence(input: {
|
|
|
1349
1392
|
cadenceMs: number;
|
|
1350
1393
|
ceilingDeadlineMs: number;
|
|
1351
1394
|
runnerResponded: () => Promise<boolean>;
|
|
1395
|
+
inspectDetachedRunner?: (
|
|
1396
|
+
suspension: DetachedRunnerSuspension,
|
|
1397
|
+
) => Promise<DetachedRunnerInspection | null>;
|
|
1398
|
+
suspension: DetachedRunnerSuspension;
|
|
1399
|
+
}): Promise<'responded' | 'gone' | 'ceiling'> {
|
|
1400
|
+
if (!(await confirmSilenceWindow(input))) return 'responded';
|
|
1401
|
+
if (Date.now() >= input.ceilingDeadlineMs) return 'ceiling';
|
|
1402
|
+
const inspect = input.inspectDetachedRunner;
|
|
1403
|
+
if (!inspect) {
|
|
1404
|
+
detachedRunnerProvenGone.set(input.suspension, null);
|
|
1405
|
+
return 'gone';
|
|
1406
|
+
}
|
|
1407
|
+
const recheckMs = Math.max(
|
|
1408
|
+
LIVENESS_RECHECK_MIN_INTERVAL_MS,
|
|
1409
|
+
LIVENESS_RECHECK_INTERVAL_CADENCES * input.cadenceMs,
|
|
1410
|
+
);
|
|
1411
|
+
for (let round = 1; ; round += 1) {
|
|
1412
|
+
const stepName = `${input.stepPrefix}:evidence:${round}`;
|
|
1413
|
+
let inspected: DetachedRunnerInspection | null = null;
|
|
1414
|
+
const gone = await input.ctx.step(`${stepName}:gone`, async () => {
|
|
1415
|
+
// Deferred so a synchronous throw, such as an unreadable persisted
|
|
1416
|
+
// sandbox ref, is an unproven inspection rather than a failed park.
|
|
1417
|
+
const inspection = await Promise.resolve()
|
|
1418
|
+
.then(() => inspect(input.suspension))
|
|
1419
|
+
.catch((error: unknown) => {
|
|
1420
|
+
console.warn(
|
|
1421
|
+
'[absurd-runtime.worker] detached_runner_liveness_evidence_failed',
|
|
1422
|
+
JSON.stringify({
|
|
1423
|
+
sandboxId: input.suspension.sandboxId,
|
|
1424
|
+
round,
|
|
1425
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1426
|
+
}),
|
|
1427
|
+
);
|
|
1428
|
+
return null;
|
|
1429
|
+
});
|
|
1430
|
+
inspected = inspection;
|
|
1431
|
+
const proved = detachedRunnerInspectionProvesGone(inspection);
|
|
1432
|
+
if (!proved) {
|
|
1433
|
+
console.warn(
|
|
1434
|
+
'[absurd-runtime.worker] detached_runner_liveness_unproven',
|
|
1435
|
+
JSON.stringify({
|
|
1436
|
+
runnerAttempt: input.suspension.runnerAttempt,
|
|
1437
|
+
sandboxId: input.suspension.sandboxId,
|
|
1438
|
+
round,
|
|
1439
|
+
diagnosis: inspection?.diagnosis?.stage ?? 'unavailable',
|
|
1440
|
+
}),
|
|
1441
|
+
);
|
|
1442
|
+
}
|
|
1443
|
+
return proved;
|
|
1444
|
+
});
|
|
1445
|
+
if (gone) {
|
|
1446
|
+
detachedRunnerProvenGone.set(input.suspension, inspected);
|
|
1447
|
+
return 'gone';
|
|
1448
|
+
}
|
|
1449
|
+
// Jitter stops runners silenced together from being inspected together.
|
|
1450
|
+
const wakeAtMs = await input.ctx.step(`${stepName}:at`, async () =>
|
|
1451
|
+
Math.min(
|
|
1452
|
+
input.ceilingDeadlineMs,
|
|
1453
|
+
Date.now() + recheckMs * (1 + Math.random() / 2),
|
|
1454
|
+
),
|
|
1455
|
+
);
|
|
1456
|
+
await input.ctx.sleepUntil(stepName, new Date(wakeAtMs));
|
|
1457
|
+
if (await input.runnerResponded()) return 'responded';
|
|
1458
|
+
if (wakeAtMs >= input.ceilingDeadlineMs) return 'ceiling';
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
async function confirmSilenceWindow(input: {
|
|
1463
|
+
ctx: AbsurdSuspensionContext;
|
|
1464
|
+
stepPrefix: string;
|
|
1465
|
+
cadenceMs: number;
|
|
1466
|
+
ceilingDeadlineMs: number;
|
|
1467
|
+
runnerResponded: () => Promise<boolean>;
|
|
1352
1468
|
}): Promise<boolean> {
|
|
1353
1469
|
const sliceMs = Math.floor(
|
|
1354
1470
|
input.cadenceMs / LIVENESS_CONFIRMATION_SLICES_PER_CADENCE,
|
|
@@ -1398,6 +1514,11 @@ export async function parkAndResolveSuspension(input: {
|
|
|
1398
1514
|
updatedAt: string | null;
|
|
1399
1515
|
status: string;
|
|
1400
1516
|
} | null>;
|
|
1517
|
+
/** Provider evidence the park requires before it reports a silent runner as
|
|
1518
|
+
* gone. Without it, silence alone ends the park. */
|
|
1519
|
+
inspectDetachedRunner?: (
|
|
1520
|
+
suspension: DetachedRunnerSuspension,
|
|
1521
|
+
) => Promise<DetachedRunnerInspection | null>;
|
|
1401
1522
|
}): Promise<PlayCheckpoint> {
|
|
1402
1523
|
const { ctx, suspension, checkpoint, runId } = input;
|
|
1403
1524
|
|
|
@@ -1430,8 +1551,11 @@ export async function parkAndResolveSuspension(input: {
|
|
|
1430
1551
|
? configuredHeartbeatTimeoutMs
|
|
1431
1552
|
: RUNTIME_CLAIM_LEASE_SECONDS * 1000;
|
|
1432
1553
|
const ceilingDeadlineMs = suspension.startedAtMs + suspension.ceilingMs;
|
|
1554
|
+
const readRunnerTerminal = input.readRunnerTerminal;
|
|
1555
|
+
const readRunnerLiveness = input.readRunnerLiveness;
|
|
1556
|
+
let rearms = 0;
|
|
1433
1557
|
for (;;) {
|
|
1434
|
-
const liveness = await
|
|
1558
|
+
const liveness = await readRunnerLiveness(suspension.runnerAttempt);
|
|
1435
1559
|
const heartbeatAtMs = liveness?.heartbeatAt
|
|
1436
1560
|
? Date.parse(liveness.heartbeatAt)
|
|
1437
1561
|
: Number.NaN;
|
|
@@ -1441,26 +1565,33 @@ export async function parkAndResolveSuspension(input: {
|
|
|
1441
1565
|
: suspension.startedAtMs) + heartbeatTimeoutMs;
|
|
1442
1566
|
const deadlineMs = Math.min(ceilingDeadlineMs, heartbeatDeadlineMs);
|
|
1443
1567
|
const remainingMs = Math.max(0, deadlineMs - Date.now());
|
|
1568
|
+
let timedOut = false;
|
|
1444
1569
|
try {
|
|
1445
1570
|
// The deadline is part of the durable step identity. A new persisted
|
|
1446
1571
|
// heartbeat produces a new deadline/step and parks again without
|
|
1447
1572
|
// allocating a new scheduler attempt; the live sandbox keeps its
|
|
1448
1573
|
// original attempt-scoped executor token and heartbeat identity.
|
|
1574
|
+
// Absurd floors this to whole seconds, so round up: a timer that
|
|
1575
|
+
// fires early must not reach the liveness decision below.
|
|
1449
1576
|
await ctx.awaitEvent(
|
|
1450
1577
|
absurdRunnerTerminalEventName(runId, suspension.runnerAttempt),
|
|
1451
1578
|
{
|
|
1452
1579
|
stepName: `${suspension.boundaryId}:deadline:${deadlineMs}`,
|
|
1453
|
-
timeout: remainingMs / 1000,
|
|
1580
|
+
timeout: Math.ceil(remainingMs / 1000),
|
|
1454
1581
|
},
|
|
1455
1582
|
);
|
|
1456
|
-
break;
|
|
1457
1583
|
} catch (error) {
|
|
1458
1584
|
if (!(error instanceof TimeoutError)) {
|
|
1459
1585
|
// SuspendTask (park) and any real error propagate.
|
|
1460
1586
|
throw error;
|
|
1461
1587
|
}
|
|
1588
|
+
timedOut = true;
|
|
1462
1589
|
}
|
|
1463
|
-
|
|
1590
|
+
// A returned wait proves nothing. After a timed-out wake the run row
|
|
1591
|
+
// keeps its wake_event, so the next wait on this event returns null
|
|
1592
|
+
// instead of suspending. Only the persisted terminal ends the park.
|
|
1593
|
+
if (await readRunnerTerminal(suspension.runnerAttempt)) break;
|
|
1594
|
+
const renewed = await readRunnerLiveness(suspension.runnerAttempt);
|
|
1464
1595
|
const renewedAtMs = renewed?.heartbeatAt
|
|
1465
1596
|
? Date.parse(renewed.heartbeatAt)
|
|
1466
1597
|
: Number.NaN;
|
|
@@ -1470,29 +1601,45 @@ export async function parkAndResolveSuspension(input: {
|
|
|
1470
1601
|
heartbeatTimeoutMs,
|
|
1471
1602
|
);
|
|
1472
1603
|
if (renewedDeadlineMs > Date.now()) {
|
|
1473
|
-
|
|
1604
|
+
// This deadline's step has already timed out, so waiting on it again
|
|
1605
|
+
// here would be a different step. The resolver re-parks from a new leg.
|
|
1606
|
+
if (timedOut && renewedDeadlineMs === deadlineMs) break;
|
|
1607
|
+
rearms += 1;
|
|
1608
|
+
if (rearms > LIVENESS_PARK_MAX_REARMS_PER_WAKE) {
|
|
1609
|
+
throw new Error(
|
|
1610
|
+
`Detached runner park for ${runId}/${suspension.runnerAttempt} woke ${rearms} times without a terminal or an expired deadline.`,
|
|
1611
|
+
);
|
|
1612
|
+
}
|
|
1474
1613
|
continue;
|
|
1475
1614
|
}
|
|
1476
1615
|
if (ceilingDeadlineMs <= Date.now()) break;
|
|
1477
|
-
|
|
1478
|
-
const
|
|
1479
|
-
const silent = await confirmDetachedRunnerSilence({
|
|
1616
|
+
let quietUntilMs = 0;
|
|
1617
|
+
const verdict = await confirmDetachedRunnerSilence({
|
|
1480
1618
|
ctx,
|
|
1481
1619
|
stepPrefix: `${suspension.boundaryId}:liveness-confirm:${Number.isFinite(renewedAtMs) ? renewedAtMs : 'none'}`,
|
|
1482
1620
|
cadenceMs: Math.floor(
|
|
1483
1621
|
heartbeatTimeoutMs / RUNTIME_CLAIM_HEARTBEAT_DIVISOR,
|
|
1484
1622
|
),
|
|
1485
1623
|
ceilingDeadlineMs,
|
|
1624
|
+
inspectDetachedRunner: input.inspectDetachedRunner,
|
|
1625
|
+
suspension,
|
|
1486
1626
|
runnerResponded: async () => {
|
|
1627
|
+
// A wake replays every finished slice. One read per replay is enough.
|
|
1628
|
+
if (Date.now() < quietUntilMs) return false;
|
|
1487
1629
|
if (await readRunnerTerminal(suspension.runnerAttempt)) return true;
|
|
1488
1630
|
const current = await readRunnerLiveness(suspension.runnerAttempt);
|
|
1489
1631
|
const currentAtMs = current?.heartbeatAt
|
|
1490
1632
|
? Date.parse(current.heartbeatAt)
|
|
1491
1633
|
: Number.NaN;
|
|
1492
|
-
|
|
1634
|
+
if (Number.isFinite(currentAtMs) && !(currentAtMs <= renewedAtMs)) {
|
|
1635
|
+
return true;
|
|
1636
|
+
}
|
|
1637
|
+
quietUntilMs = Date.now() + LIVENESS_REPLAY_READ_REUSE_MS;
|
|
1638
|
+
return false;
|
|
1493
1639
|
},
|
|
1494
1640
|
});
|
|
1495
|
-
if (
|
|
1641
|
+
if (verdict === 'responded') continue;
|
|
1642
|
+
break;
|
|
1496
1643
|
}
|
|
1497
1644
|
// Truth is the persisted terminal (read by the caller's wake path); the
|
|
1498
1645
|
// absurd event carries no payload we trust.
|
|
@@ -1594,6 +1741,9 @@ export function createAbsurdEngineSuspensionAdapter(input: {
|
|
|
1594
1741
|
updatedAt: string | null;
|
|
1595
1742
|
status: string;
|
|
1596
1743
|
} | null>;
|
|
1744
|
+
inspectDetachedRunner?: (
|
|
1745
|
+
suspension: DetachedRunnerSuspension,
|
|
1746
|
+
) => Promise<DetachedRunnerInspection | null>;
|
|
1597
1747
|
}): PlayRunAttemptEngineSuspensionPort {
|
|
1598
1748
|
let parkedSignal: SuspendTask | null = null;
|
|
1599
1749
|
return {
|
|
@@ -1609,6 +1759,7 @@ export function createAbsurdEngineSuspensionAdapter(input: {
|
|
|
1609
1759
|
claimSignal: input.claimSignal,
|
|
1610
1760
|
readRunnerTerminal: input.readRunnerTerminal,
|
|
1611
1761
|
readRunnerLiveness: input.readRunnerLiveness,
|
|
1762
|
+
inspectDetachedRunner: input.inspectDetachedRunner,
|
|
1612
1763
|
}),
|
|
1613
1764
|
};
|
|
1614
1765
|
} catch (error) {
|
|
@@ -3376,6 +3527,7 @@ async function executeAssignedAbsurdAttempt(input: {
|
|
|
3376
3527
|
options,
|
|
3377
3528
|
),
|
|
3378
3529
|
),
|
|
3530
|
+
inspectDetachedRunner: deps.inspectDetachedRunner,
|
|
3379
3531
|
});
|
|
3380
3532
|
const finalizeSuspensionProgress = () =>
|
|
3381
3533
|
runWithAbsurdExecutionLeaseHeartbeat({
|
|
@@ -3582,6 +3734,7 @@ async function executeAssignedAbsurdAttempt(input: {
|
|
|
3582
3734
|
options,
|
|
3583
3735
|
),
|
|
3584
3736
|
),
|
|
3737
|
+
inspectDetachedRunner: deps.inspectDetachedRunner,
|
|
3585
3738
|
});
|
|
3586
3739
|
const running = await deps.runWithClient((client) =>
|
|
3587
3740
|
markPostgresSchedulerAttemptRunning(
|
|
@@ -5015,9 +5168,10 @@ export async function enforceRuntimeTrafficPolicyBeforeSandboxStart(input: {
|
|
|
5015
5168
|
* Truth ladder:
|
|
5016
5169
|
* 1. The runner's pushed terminal persisted on its attempt row.
|
|
5017
5170
|
* 2. A fresh heartbeat re-parks the same detached runner.
|
|
5018
|
-
* 3. A
|
|
5019
|
-
*
|
|
5020
|
-
*
|
|
5171
|
+
* 3. A captured result recovered from the sandbox.
|
|
5172
|
+
* 4. A hard ceiling, or a stale heartbeat the provider proves is final,
|
|
5173
|
+
* writes one failed terminal. A stale heartbeat without that proof
|
|
5174
|
+
* re-parks: a heartbeat gap alone never ends a run.
|
|
5021
5175
|
*
|
|
5022
5176
|
* A detached runner terminal is always terminal for its scheduler attempt.
|
|
5023
5177
|
* By the time a sandbox can push an outcome, customer code may have started
|
|
@@ -5035,7 +5189,7 @@ export async function enforceRuntimeTrafficPolicyBeforeSandboxStart(input: {
|
|
|
5035
5189
|
* `resolveRunnerSuspension` persists its obligation before typed waiting.
|
|
5036
5190
|
* Provider deletion never delays publishing the user's wait.
|
|
5037
5191
|
*/
|
|
5038
|
-
async function resolveDetachedRunnerOutcome(input: {
|
|
5192
|
+
export async function resolveDetachedRunnerOutcome(input: {
|
|
5039
5193
|
runId: string;
|
|
5040
5194
|
suspension: DetachedRunnerSuspension;
|
|
5041
5195
|
checkpoint: PlayCheckpoint;
|
|
@@ -5080,7 +5234,16 @@ async function resolveDetachedRunnerOutcome(input: {
|
|
|
5080
5234
|
result: PlayRunnerResult,
|
|
5081
5235
|
): Promise<PlayRunnerResult> => {
|
|
5082
5236
|
await recordWorkCompletion(result);
|
|
5083
|
-
|
|
5237
|
+
// `runtimeBackend` is the launch's selector and fallback can leave it
|
|
5238
|
+
// pointing at a provider that never ran this sandbox. Record the one that
|
|
5239
|
+
// did, including on terminals the runner never got to write.
|
|
5240
|
+
return {
|
|
5241
|
+
...result,
|
|
5242
|
+
stats: {
|
|
5243
|
+
...result.stats,
|
|
5244
|
+
sandboxProvider: suspension.sandboxProvider ?? 'daytona',
|
|
5245
|
+
},
|
|
5246
|
+
};
|
|
5084
5247
|
};
|
|
5085
5248
|
const settleFirstWriteWinner = async (
|
|
5086
5249
|
candidate: PlayRunnerResult,
|
|
@@ -5112,9 +5275,9 @@ async function resolveDetachedRunnerOutcome(input: {
|
|
|
5112
5275
|
return settle(stored);
|
|
5113
5276
|
}
|
|
5114
5277
|
|
|
5115
|
-
// No pushed terminal.
|
|
5116
|
-
//
|
|
5117
|
-
//
|
|
5278
|
+
// No pushed terminal. A provider outage must not fail a run, so only a
|
|
5279
|
+
// positive provider answer does; an unavailable provider leaves the hard
|
|
5280
|
+
// ceiling to end it. A concurrent terminal remains allowed to win below.
|
|
5118
5281
|
const now = Date.now();
|
|
5119
5282
|
// A liveness-store outage is not evidence that the sandbox died. Let the
|
|
5120
5283
|
// worker retry this read rather than producing a false terminal failure.
|
|
@@ -5138,43 +5301,47 @@ async function resolveDetachedRunnerOutcome(input: {
|
|
|
5138
5301
|
configuredHeartbeatTimeoutMs >= 0
|
|
5139
5302
|
? configuredHeartbeatTimeoutMs
|
|
5140
5303
|
: RUNTIME_CLAIM_LEASE_SECONDS * 1000;
|
|
5304
|
+
const reparkDetachedRunner = (): PlayRunnerResult => ({
|
|
5305
|
+
status: 'suspended',
|
|
5306
|
+
suspension,
|
|
5307
|
+
logs: [],
|
|
5308
|
+
stats: {},
|
|
5309
|
+
steps: [],
|
|
5310
|
+
checkpoint: input.checkpoint,
|
|
5311
|
+
tableNamespace: null,
|
|
5312
|
+
});
|
|
5141
5313
|
if (!reachedCeiling && heartbeatAgeMs !== null) {
|
|
5142
5314
|
if (heartbeatAgeMs < heartbeatTimeoutMs) {
|
|
5143
5315
|
// We woke on an older deadline while the runner renewed liveness. Park
|
|
5144
5316
|
// again from the new durable timestamp; do not touch Daytona.
|
|
5145
|
-
return
|
|
5146
|
-
status: 'suspended',
|
|
5147
|
-
suspension,
|
|
5148
|
-
logs: [],
|
|
5149
|
-
stats: {},
|
|
5150
|
-
steps: [],
|
|
5151
|
-
checkpoint: input.checkpoint,
|
|
5152
|
-
tableNamespace: null,
|
|
5153
|
-
};
|
|
5317
|
+
return reparkDetachedRunner();
|
|
5154
5318
|
}
|
|
5155
5319
|
}
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5320
|
+
const reportLivenessExpired = () => {
|
|
5321
|
+
// This event is consumed directly by the operational-health dashboard.
|
|
5322
|
+
// Keep its second argument strict JSON so Fly's text log stream remains an
|
|
5323
|
+
// executable producer contract, independent of Bun's object-inspect format.
|
|
5324
|
+
console.error(
|
|
5325
|
+
'[absurd-runtime.worker] detached_runner_liveness_expired',
|
|
5326
|
+
JSON.stringify({
|
|
5327
|
+
runId: input.runId,
|
|
5328
|
+
runnerAttempt: suspension.runnerAttempt,
|
|
5329
|
+
sandboxId: suspension.sandboxId,
|
|
5330
|
+
sessionId: suspension.sessionId,
|
|
5331
|
+
cmdId: suspension.cmdId,
|
|
5332
|
+
startedAtMs: suspension.startedAtMs,
|
|
5333
|
+
heartbeatTimeoutMs,
|
|
5334
|
+
ceilingMs: suspension.ceilingMs,
|
|
5335
|
+
observedAtMs: now,
|
|
5336
|
+
reachedCeiling,
|
|
5337
|
+
liveness,
|
|
5338
|
+
heartbeatAgeMs,
|
|
5339
|
+
pushedTerminalPresent: false,
|
|
5340
|
+
}),
|
|
5341
|
+
);
|
|
5342
|
+
};
|
|
5177
5343
|
if (reachedCeiling) {
|
|
5344
|
+
reportLivenessExpired();
|
|
5178
5345
|
return settleFirstWriteWinner({
|
|
5179
5346
|
status: 'failed',
|
|
5180
5347
|
error: `${runtimeLimitExceededCause(runtimeLimitSeconds)} Detached runner reached its hard execution ceiling without a terminal result. Sandbox ${suspension.sandboxId}. The run was stopped and was not retried; completed row state remains persisted.`,
|
|
@@ -5189,17 +5356,14 @@ async function resolveDetachedRunnerOutcome(input: {
|
|
|
5189
5356
|
// bounded terminal push. A receipt-gateway outage can exhaust that push and
|
|
5190
5357
|
// expire liveness even though the sandbox cleanly stopped itself. Recover
|
|
5191
5358
|
// only that already-written result before synthesizing RUNNER_LOST: this
|
|
5192
|
-
// does not execute customer code
|
|
5193
|
-
|
|
5194
|
-
let inspection
|
|
5195
|
-
|
|
5196
|
-
result: PlayRunnerResult | null;
|
|
5197
|
-
diagnosis?: { stage: string; detail: string | null };
|
|
5198
|
-
} | null = null;
|
|
5359
|
+
// does not execute customer code.
|
|
5360
|
+
const provenGone = detachedRunnerProvenGone.has(suspension);
|
|
5361
|
+
let inspection = detachedRunnerProvenGone.get(suspension) ?? null;
|
|
5362
|
+
detachedRunnerProvenGone.delete(suspension);
|
|
5199
5363
|
let inspectionFailed = false;
|
|
5200
5364
|
if (input.inspectDetachedRunner) {
|
|
5201
5365
|
try {
|
|
5202
|
-
inspection
|
|
5366
|
+
inspection ??= await input.inspectDetachedRunner(suspension);
|
|
5203
5367
|
if (inspection?.result && inspection.result.status !== 'suspended') {
|
|
5204
5368
|
console.info(
|
|
5205
5369
|
'[absurd-runtime.worker] detached_runner_liveness_salvaged',
|
|
@@ -5240,6 +5404,32 @@ async function resolveDetachedRunnerOutcome(input: {
|
|
|
5240
5404
|
);
|
|
5241
5405
|
}
|
|
5242
5406
|
}
|
|
5407
|
+
// Inspection takes seconds. A terminal or heartbeat that landed meanwhile
|
|
5408
|
+
// outranks everything read before it.
|
|
5409
|
+
const storedDuringInspection = parseDetachedRunnerResult(
|
|
5410
|
+
await input.readRunnerTerminal(suspension.runnerAttempt),
|
|
5411
|
+
);
|
|
5412
|
+
if (storedDuringInspection) {
|
|
5413
|
+
return settle(storedDuringInspection);
|
|
5414
|
+
}
|
|
5415
|
+
const latestLiveness = await input.readRunnerLiveness();
|
|
5416
|
+
const latestHeartbeatAtMs = latestLiveness?.heartbeatAt
|
|
5417
|
+
? Date.parse(latestLiveness.heartbeatAt)
|
|
5418
|
+
: Number.NaN;
|
|
5419
|
+
if (
|
|
5420
|
+
Number.isFinite(latestHeartbeatAtMs) &&
|
|
5421
|
+
!(latestHeartbeatAtMs <= heartbeatAtMs)
|
|
5422
|
+
) {
|
|
5423
|
+
return reparkDetachedRunner();
|
|
5424
|
+
}
|
|
5425
|
+
if (
|
|
5426
|
+
input.inspectDetachedRunner &&
|
|
5427
|
+
!provenGone &&
|
|
5428
|
+
!detachedRunnerInspectionProvesGone(inspection)
|
|
5429
|
+
) {
|
|
5430
|
+
return reparkDetachedRunner();
|
|
5431
|
+
}
|
|
5432
|
+
reportLivenessExpired();
|
|
5243
5433
|
const safeDiagnosticLabel = (value: unknown): string =>
|
|
5244
5434
|
typeof value === 'string' && /^[a-z0-9_]{1,80}$/i.test(value)
|
|
5245
5435
|
? value
|
|
@@ -15346,9 +15346,17 @@ export function attachRunnerWorkProgressMetadata(
|
|
|
15346
15346
|
...outputWarnings,
|
|
15347
15347
|
...ctxFetchHttpWarnings,
|
|
15348
15348
|
].slice(0, 16);
|
|
15349
|
+
const sandboxProvider = (
|
|
15350
|
+
runnerResult as { stats?: { sandboxProvider?: unknown } }
|
|
15351
|
+
).stats?.sandboxProvider;
|
|
15352
|
+
const provenSandboxProvider =
|
|
15353
|
+
sandboxProvider === 'daytona' || sandboxProvider === 'modal'
|
|
15354
|
+
? sandboxProvider
|
|
15355
|
+
: null;
|
|
15349
15356
|
if (
|
|
15350
15357
|
(total === null || skipped === null || metadata?.workProgress) &&
|
|
15351
15358
|
!runLogTail &&
|
|
15359
|
+
!provenSandboxProvider &&
|
|
15352
15360
|
!runtimeResources &&
|
|
15353
15361
|
!runtimeCounters &&
|
|
15354
15362
|
!metadata?.runtimeCounters &&
|
|
@@ -15390,6 +15398,9 @@ export function attachRunnerWorkProgressMetadata(
|
|
|
15390
15398
|
...(rowOutcomes ? { rowOutcomes } : {}),
|
|
15391
15399
|
...(runLogTail ? { runLogTail } : {}),
|
|
15392
15400
|
...(runtimeResources ? { runtimeResources } : {}),
|
|
15401
|
+
...(provenSandboxProvider
|
|
15402
|
+
? { sandboxProvider: provenSandboxProvider }
|
|
15403
|
+
: {}),
|
|
15393
15404
|
...(mergedOutputWarnings.length > 0
|
|
15394
15405
|
? { outputWarnings: mergedOutputWarnings }
|
|
15395
15406
|
: {}),
|
|
@@ -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 _chunk33FEF4RHjs = require('./chunk-33FEF4RH.js');
|
|
17
|
+
require('./chunk-SJH66N73.js');
|
|
18
|
+
require('./chunk-VXBEHDM6.js');
|
|
19
|
+
require('./chunk-ALJJRZNJ.js');
|
|
20
|
+
require('./chunk-XNYIZMNQ.js');
|
|
21
|
+
require('./chunk-DIAWYWT5.js');
|
|
22
|
+
require('./chunk-7V3OKSB2.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 = _chunk33FEF4RHjs.EXIT_WORKSPACE_MISMATCH; exports.authStatusLine = _chunk33FEF4RHjs.authStatusLine; exports.clearPendingClaim = _chunk33FEF4RHjs.clearPendingClaim; exports.clearSatisfiedPendingClaim = _chunk33FEF4RHjs.clearSatisfiedPendingClaim; exports.handleRegister = _chunk33FEF4RHjs.handleRegister; exports.handleStatus = _chunk33FEF4RHjs.handleStatus; exports.handleWait = _chunk33FEF4RHjs.handleWait; exports.httpJson = _chunk33FEF4RHjs.httpJson; exports.readPendingAuthClaim = _chunk33FEF4RHjs.readPendingAuthClaim; exports.readStatusBanner = _chunk33FEF4RHjs.readStatusBanner; exports.registerAuthCommands = _chunk33FEF4RHjs.registerAuthCommands; exports.reportSetupCompleted = _chunk33FEF4RHjs.reportSetupCompleted; exports.resolvePendingAuthClaimForResume = _chunk33FEF4RHjs.resolvePendingAuthClaimForResume; exports.statusBannerLine = _chunk33FEF4RHjs.statusBannerLine;
|
|
@@ -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-DCZSJON4.mjs";
|
|
17
|
+
import "./chunk-RDAUQGPG.mjs";
|
|
18
|
+
import "./chunk-TECW24CR.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-LWYOJG66.mjs";
|
|
23
23
|
import "./chunk-WZYKRD7T.mjs";
|
|
24
24
|
import "./chunk-KRD6H754.mjs";
|
|
25
25
|
export {
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
DeeplineClient,
|
|
3
3
|
iterateCursorPages,
|
|
4
4
|
requireBillingIdempotencyKey
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-YXCLG3KB.mjs";
|
|
6
6
|
import "./chunk-L2VKAASU.mjs";
|
|
7
7
|
import "./chunk-FAG4DFUC.mjs";
|
|
8
8
|
import "./chunk-EIMG75BT.mjs";
|
|
@@ -13,8 +13,8 @@ import {
|
|
|
13
13
|
openInBrowser,
|
|
14
14
|
printCommandEnvelope,
|
|
15
15
|
shouldEmitJson
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-RDAUQGPG.mjs";
|
|
17
|
+
import "./chunk-TECW24CR.mjs";
|
|
18
18
|
import {
|
|
19
19
|
AuthError,
|
|
20
20
|
ConfigError
|
|
@@ -23,7 +23,7 @@ import "./chunk-DLIRSHV6.mjs";
|
|
|
23
23
|
import {
|
|
24
24
|
DeeplineError
|
|
25
25
|
} from "./chunk-HBL4PM5Q.mjs";
|
|
26
|
-
import "./chunk-
|
|
26
|
+
import "./chunk-LWYOJG66.mjs";
|
|
27
27
|
import "./chunk-WZYKRD7T.mjs";
|
|
28
28
|
import "./chunk-KRD6H754.mjs";
|
|
29
29
|
|
|
@@ -200,13 +200,26 @@ function parseSince(raw) {
|
|
|
200
200
|
function humanize(value) {
|
|
201
201
|
return String(value || "").split("_").filter(Boolean).map((token) => token[0]?.toUpperCase() + token.slice(1)).join(" ") || "Unknown";
|
|
202
202
|
}
|
|
203
|
+
var MONITOR_CHARGE_LABELS = {
|
|
204
|
+
provider_execution: "preview",
|
|
205
|
+
webhook_event: "match",
|
|
206
|
+
create: "setup",
|
|
207
|
+
reactivate: "reactivation",
|
|
208
|
+
periodic_renewal: "renewal",
|
|
209
|
+
subscription_renewal: "renewal"
|
|
210
|
+
};
|
|
211
|
+
function usageOperationLabel(operation) {
|
|
212
|
+
const [prefix, phase, , tool] = String(operation || "").split(".");
|
|
213
|
+
const label = phase ? MONITOR_CHARGE_LABELS[phase] : void 0;
|
|
214
|
+
return prefix === "monitor" && label && tool ? `Monitor ${label}: ${humanize(tool)}` : humanize(operation);
|
|
215
|
+
}
|
|
203
216
|
function recentUsageLines(entries) {
|
|
204
217
|
if (entries.length === 0) {
|
|
205
218
|
return ["Recent activity: none yet"];
|
|
206
219
|
}
|
|
207
220
|
const lines = ["Recent activity:"];
|
|
208
221
|
for (const entry of entries) {
|
|
209
|
-
const op = `${humanize(entry.provider)} ${
|
|
222
|
+
const op = `${humanize(entry.provider)} ${usageOperationLabel(entry.operation)}`.trim();
|
|
210
223
|
const roughUsd = Number(entry.rough_usd_cost);
|
|
211
224
|
const credits = entry.credits !== null && entry.credits !== void 0 && String(entry.credits).trim().length > 0 && Number.isFinite(Number(entry.credits)) ? Number(entry.credits) : null;
|
|
212
225
|
const temporaryHold = entry.charge_state === "temporary_hold";
|