deepline 0.3.247 → 0.3.249
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 +177 -13
- package/dist/bundling-sources/sdk/src/index.ts +8 -0
- package/dist/bundling-sources/sdk/src/plays/input-example.ts +40 -0
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/runs/overview.ts +457 -0
- package/dist/bundling-sources/sdk/src/runs/receipts.ts +23 -0
- package/dist/bundling-sources/sdk/src/tool-calls.ts +21 -1
- package/dist/bundling-sources/sdk/src/types.ts +16 -1
- package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +19 -1
- package/dist/bundling-sources/shared_libs/play-data-plane/column-names.ts +17 -3
- package/dist/bundling-sources/shared_libs/play-data-plane/sheet-contract.ts +40 -8
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +26 -1
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +144 -14
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +2 -1
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-runtime-config.ts +6 -3
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-janitor.ts +26 -21
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-reaper.ts +23 -21
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-machines.ts +17 -0
- package/dist/bundling-sources/shared_libs/play-runtime/log-context.ts +105 -0
- package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +8 -1
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/job.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/ports.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +9 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger-event-transport.ts +40 -4
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +50 -5
- package/dist/bundling-sources/shared_libs/play-runtime/run-lifecycle-policy.ts +3 -1
- package/dist/bundling-sources/shared_libs/play-runtime/run-log-buffer.ts +28 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +14 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-terminal-push.ts +56 -16
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-control-transport.ts +184 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-launch-transport.ts +327 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +87 -30
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-session-execution.ts +24 -13
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-start-admission.ts +23 -6
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +76 -33
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +90 -35
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-pool.ts +16 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-progress.ts +112 -50
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +447 -77
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +22 -4
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +105 -121
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +1648 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-queue-health.ts +16 -19
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-receipt-value-storage.ts +14 -6
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +16 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +40 -0
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +5 -2
- package/dist/bundling-sources/shared_libs/plays/dataset-summary.ts +11 -7
- package/dist/bundling-sources/shared_libs/plays/static-pipeline-storage-codec.ts +5 -2
- package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +11 -2
- package/dist/cli/index.js +3504 -2368
- package/dist/cli/index.mjs +3188 -2052
- package/dist/{compiler-manifest-n8ZtPv2h.d.mts → compiler-manifest-DavmLa8y.d.mts} +1 -0
- package/dist/{compiler-manifest-n8ZtPv2h.d.ts → compiler-manifest-DavmLa8y.d.ts} +1 -0
- package/dist/index.d.mts +97 -5
- package/dist/index.d.ts +97 -5
- package/dist/index.js +135 -15
- package/dist/index.mjs +135 -15
- package/dist/install-integrity.json +9 -2
- package/dist/plays/bundle-play-file.d.mts +2 -2
- package/dist/plays/bundle-play-file.d.ts +2 -2
- package/dist/plays/bundle-play-file.mjs +1 -1
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +1 -1
- package/dist/release.mjs +1 -1
- package/package.json +1 -1
package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts
CHANGED
|
@@ -361,13 +361,21 @@ function requireReceiptScope(
|
|
|
361
361
|
if (!scope.orgId || !scope.playName || !scope.runId) {
|
|
362
362
|
return receiptGatewayJsonResponse(
|
|
363
363
|
{ error: 'Executor token is missing org/run/play scope.' },
|
|
364
|
-
{
|
|
364
|
+
{
|
|
365
|
+
status: 403,
|
|
366
|
+
headers: { 'x-deepline-error-code': 'runtime_receipt_scope_missing' },
|
|
367
|
+
},
|
|
365
368
|
);
|
|
366
369
|
}
|
|
367
370
|
if (body.playName !== scope.playName) {
|
|
368
371
|
return receiptGatewayJsonResponse(
|
|
369
372
|
{ error: 'Receipt request playName does not match executor token.' },
|
|
370
|
-
{
|
|
373
|
+
{
|
|
374
|
+
status: 403,
|
|
375
|
+
headers: {
|
|
376
|
+
'x-deepline-error-code': 'runtime_receipt_play_scope_mismatch',
|
|
377
|
+
},
|
|
378
|
+
},
|
|
371
379
|
);
|
|
372
380
|
}
|
|
373
381
|
if (body.runId && body.runId !== scope.runId) {
|
|
@@ -378,7 +386,12 @@ function requireReceiptScope(
|
|
|
378
386
|
});
|
|
379
387
|
return receiptGatewayJsonResponse(
|
|
380
388
|
{ error: 'Receipt request runId does not match executor token.' },
|
|
381
|
-
{
|
|
389
|
+
{
|
|
390
|
+
status: 403,
|
|
391
|
+
headers: {
|
|
392
|
+
'x-deepline-error-code': 'runtime_receipt_run_scope_mismatch',
|
|
393
|
+
},
|
|
394
|
+
},
|
|
382
395
|
);
|
|
383
396
|
}
|
|
384
397
|
return null;
|
|
@@ -403,7 +416,12 @@ function requireSameRunReceipts(
|
|
|
403
416
|
return invalid
|
|
404
417
|
? receiptGatewayJsonResponse(
|
|
405
418
|
{ error: 'Receipt runId does not match executor token scope.' },
|
|
406
|
-
{
|
|
419
|
+
{
|
|
420
|
+
status: 403,
|
|
421
|
+
headers: {
|
|
422
|
+
'x-deepline-error-code': 'runtime_receipt_run_scope_mismatch',
|
|
423
|
+
},
|
|
424
|
+
},
|
|
407
425
|
)
|
|
408
426
|
: null;
|
|
409
427
|
}
|
|
@@ -41,7 +41,7 @@ const MAX_TIMEOUT_MS = 2_147_483_647;
|
|
|
41
41
|
* therefore a network/projection concurrency budget, deliberately independent
|
|
42
42
|
* of the projector's much smaller Postgres pool.
|
|
43
43
|
*
|
|
44
|
-
* A single successful probe
|
|
44
|
+
* A single successful probe fills bounded delivery slots; an idle projector still
|
|
45
45
|
* performs only one indexed head read per safety wake. `SKIP LOCKED` leases
|
|
46
46
|
* distinct runs, retaining strict causal ordering within every run.
|
|
47
47
|
*/
|
|
@@ -125,12 +125,12 @@ export function startRunLedgerOutboxRecovery(
|
|
|
125
125
|
let failureCount = 0;
|
|
126
126
|
let timer: RecoveryTimer | null = null;
|
|
127
127
|
let drainPromise: Promise<void> | null = null;
|
|
128
|
+
let wakeActiveDrain: (() => void) | null = null;
|
|
128
129
|
let cooldownUntilMs: number | null = null;
|
|
129
130
|
let hubLease: PgNotifyHubLease | null = null;
|
|
130
131
|
let unsubscribeNotify: (() => void) | undefined;
|
|
131
132
|
let unsubscribeState: (() => void) | undefined;
|
|
132
133
|
let requestDrain: (reason: string) => void = () => undefined;
|
|
133
|
-
let wakeDrainer: (() => void) | null = null;
|
|
134
134
|
|
|
135
135
|
const clearWakeTimer = () => {
|
|
136
136
|
if (!timer) return;
|
|
@@ -164,7 +164,7 @@ export function startRunLedgerOutboxRecovery(
|
|
|
164
164
|
if (cooldownUntilMs !== null && now() < cooldownUntilMs) return;
|
|
165
165
|
clearWakeTimer();
|
|
166
166
|
if (drainPromise) {
|
|
167
|
-
|
|
167
|
+
wakeActiveDrain?.();
|
|
168
168
|
return;
|
|
169
169
|
}
|
|
170
170
|
drainPromise = drain(reason)
|
|
@@ -251,135 +251,119 @@ export function startRunLedgerOutboxRecovery(
|
|
|
251
251
|
timer.unref?.();
|
|
252
252
|
};
|
|
253
253
|
|
|
254
|
-
type DeliveryOutcome = {
|
|
255
|
-
delivery: Promise<DeliveryOutcome>;
|
|
256
|
-
} & (
|
|
257
|
-
| { status: 'fulfilled'; value: PostgresSchedulerOutboxProjectionResult }
|
|
258
|
-
| { status: 'rejected' | 'skipped' }
|
|
259
|
-
);
|
|
260
|
-
|
|
261
254
|
const drain = async (reason: string): Promise<void> => {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
logger.info('[run-ledger-outbox.recovery_wave]', {
|
|
266
|
-
reason,
|
|
267
|
-
parallelism,
|
|
268
|
-
...volume,
|
|
269
|
-
});
|
|
270
|
-
volume.attempted = 0;
|
|
271
|
-
volume.projected = 0;
|
|
272
|
-
volume.retrying = 0;
|
|
273
|
-
volume.blocked = 0;
|
|
274
|
-
};
|
|
275
|
-
const recordResult = (
|
|
276
|
-
result: PostgresSchedulerOutboxProjectionResult,
|
|
277
|
-
resetFailures = true,
|
|
278
|
-
) => {
|
|
279
|
-
volume.attempted += result.attempted;
|
|
280
|
-
volume.projected += result.projected;
|
|
281
|
-
volume.retrying += result.retrying;
|
|
282
|
-
volume.blocked += result.failed;
|
|
283
|
-
if (result.retrying > 0) {
|
|
284
|
-
// Each retrying run owns its durable retry clock. Independent runs
|
|
285
|
-
// remain eligible; this is not a controller-wide delivery cooldown.
|
|
286
|
-
recordProjectionRetry(result.retrying);
|
|
287
|
-
} else if (resetFailures) {
|
|
288
|
-
failureCount = 0;
|
|
289
|
-
}
|
|
290
|
-
// Streaming delivery has no wave barrier at which to report progress.
|
|
291
|
-
// Keep logs bounded per committed volume, and flush at idle/shutdown.
|
|
292
|
-
if (volume.attempted >= parallelism) reportVolume();
|
|
255
|
+
type Delivery = {
|
|
256
|
+
id: symbol;
|
|
257
|
+
result: PromiseSettledResult<PostgresSchedulerOutboxProjectionResult> | { status: 'skipped' };
|
|
293
258
|
};
|
|
259
|
+
const pending = new Set<symbol>();
|
|
260
|
+
const deliveries: Delivery[] = [];
|
|
261
|
+
let refill = false;
|
|
262
|
+
let dispatchFailed = false;
|
|
263
|
+
let completed = 0;
|
|
264
|
+
let attempted = 0;
|
|
265
|
+
let projected = 0;
|
|
266
|
+
let retrying = 0;
|
|
267
|
+
let blocked = 0;
|
|
294
268
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
if (first.attempted === 0) {
|
|
310
|
-
await scheduleNextDue();
|
|
311
|
-
continue;
|
|
269
|
+
const reportDeliveries = () => {
|
|
270
|
+
if (retrying > 0) recordProjectionRetry(retrying);
|
|
271
|
+
else if (!dispatchFailed) failureCount = 0;
|
|
272
|
+
if (attempted > 0) {
|
|
273
|
+
// Retain the existing throughput event, aggregated over at most one
|
|
274
|
+
// slot-set of completions without making that set a delivery barrier.
|
|
275
|
+
logger.info('[run-ledger-outbox.recovery_wave]', {
|
|
276
|
+
reason,
|
|
277
|
+
parallelism,
|
|
278
|
+
attempted,
|
|
279
|
+
projected,
|
|
280
|
+
retrying,
|
|
281
|
+
blocked,
|
|
282
|
+
});
|
|
312
283
|
}
|
|
284
|
+
completed = attempted = projected = retrying = blocked = 0;
|
|
285
|
+
};
|
|
313
286
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
try {
|
|
322
|
-
return {
|
|
323
|
-
delivery,
|
|
324
|
-
status: 'fulfilled',
|
|
325
|
-
value: await deps.dispatchOnce(),
|
|
326
|
-
};
|
|
327
|
-
} catch (error) {
|
|
328
|
-
// Stop refills as soon as this rejection is observed, including
|
|
329
|
-
// when another already-completed slot wins Promise.race first.
|
|
330
|
-
if (!dispatchFailed) {
|
|
331
|
-
dispatchFailed = true;
|
|
332
|
-
scheduleFailureRetry('dispatch', error);
|
|
333
|
-
}
|
|
334
|
-
return { delivery, status: 'rejected' };
|
|
335
|
-
}
|
|
336
|
-
},
|
|
337
|
-
);
|
|
338
|
-
active.add(delivery);
|
|
339
|
-
};
|
|
340
|
-
const fillSlots = () => {
|
|
341
|
-
if (closed || dispatchFailed) return;
|
|
342
|
-
while (active.size < parallelism) {
|
|
343
|
-
startDelivery();
|
|
287
|
+
const launch = () => {
|
|
288
|
+
const id = Symbol();
|
|
289
|
+
pending.add(id);
|
|
290
|
+
const settle = (result: Delivery['result']) => {
|
|
291
|
+
if (result.status === 'rejected' && !dispatchFailed) {
|
|
292
|
+
dispatchFailed = true;
|
|
293
|
+
scheduleFailureRetry('dispatch', result.reason);
|
|
344
294
|
}
|
|
295
|
+
deliveries.push({ id, result });
|
|
296
|
+
wakeActiveDrain?.();
|
|
345
297
|
};
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
wakeDrainer = null;
|
|
353
|
-
if (outcome !== null) {
|
|
354
|
-
active.delete(outcome.delivery);
|
|
355
|
-
if (outcome.status === 'fulfilled') {
|
|
356
|
-
recordResult(outcome.value, !dispatchFailed);
|
|
357
|
-
if (outcome.value.attempted > 0 && !closed && !dispatchFailed) {
|
|
358
|
-
// Refill this completed slot immediately. A slower independent
|
|
359
|
-
// run never owns another run's delivery capacity.
|
|
360
|
-
startDelivery();
|
|
361
|
-
}
|
|
362
|
-
}
|
|
298
|
+
// Subscribe once per delivery. Repeated Promise.race calls would retain
|
|
299
|
+
// a new reaction on a slow callback every time a faster slot completes.
|
|
300
|
+
void Promise.resolve().then(async () => {
|
|
301
|
+
if (closed || dispatchFailed) {
|
|
302
|
+
settle({ status: 'skipped' });
|
|
303
|
+
return;
|
|
363
304
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
305
|
+
try {
|
|
306
|
+
settle({ status: 'fulfilled', value: await deps.dispatchOnce() });
|
|
307
|
+
} catch (reason) {
|
|
308
|
+
settle({ status: 'rejected', reason });
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
for (;;) {
|
|
314
|
+
if (!closed && !dispatchFailed) {
|
|
315
|
+
// A wake grants one indexed probe, including when other slots are
|
|
316
|
+
// still delivering. Keep it pending when full so an empty result
|
|
317
|
+
// cannot consume a notification that arrived after its query began.
|
|
318
|
+
if (requested && pending.size < parallelism) {
|
|
374
319
|
requested = false;
|
|
375
|
-
|
|
320
|
+
launch();
|
|
321
|
+
}
|
|
322
|
+
// Productive completion permits immediate use of every free slot.
|
|
323
|
+
// Empty results grant no refill, so idle work cannot spin on scans.
|
|
324
|
+
if (refill) {
|
|
325
|
+
while (pending.size < parallelism) launch();
|
|
326
|
+
refill = false;
|
|
376
327
|
}
|
|
377
328
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
329
|
+
if (pending.size === 0) {
|
|
330
|
+
reportDeliveries();
|
|
331
|
+
if (!closed && !dispatchFailed) await scheduleNextDue();
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
await new Promise<void>((resolve) => {
|
|
336
|
+
// Register before checking queued completions and notifications.
|
|
337
|
+
wakeActiveDrain = resolve;
|
|
338
|
+
if (
|
|
339
|
+
deliveries.length > 0 ||
|
|
340
|
+
(requested &&
|
|
341
|
+
!closed &&
|
|
342
|
+
!dispatchFailed &&
|
|
343
|
+
pending.size < parallelism)
|
|
344
|
+
)
|
|
345
|
+
resolve();
|
|
346
|
+
});
|
|
347
|
+
wakeActiveDrain = null;
|
|
348
|
+
const delivery = deliveries.shift();
|
|
349
|
+
if (!delivery) continue;
|
|
350
|
+
pending.delete(delivery.id);
|
|
351
|
+
if (delivery.result.status !== 'fulfilled') {
|
|
352
|
+
// Stop new claims but settle every already-started delivery before
|
|
353
|
+
// cooldown or close can hand ownership to another drain.
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
const result = delivery.result.value;
|
|
357
|
+
completed += 1;
|
|
358
|
+
attempted += result.attempted;
|
|
359
|
+
projected += result.projected;
|
|
360
|
+
retrying += result.retrying;
|
|
361
|
+
blocked += result.failed;
|
|
362
|
+
if (completed >= parallelism) reportDeliveries();
|
|
363
|
+
// Retryable rows own durable retry clocks. The SQL claim keeps their
|
|
364
|
+
// run ordered while successful slots keep unrelated runs moving.
|
|
365
|
+
refill = result.attempted > 0;
|
|
381
366
|
}
|
|
382
|
-
reportVolume();
|
|
383
367
|
};
|
|
384
368
|
|
|
385
369
|
// Subscribe first, then scan. Notifications are lossy by design, so every
|
|
@@ -393,7 +377,7 @@ export function startRunLedgerOutboxRecovery(
|
|
|
393
377
|
close: async () => {
|
|
394
378
|
if (closed) return;
|
|
395
379
|
closed = true;
|
|
396
|
-
|
|
380
|
+
wakeActiveDrain?.();
|
|
397
381
|
clearWakeTimer();
|
|
398
382
|
cooldownUntilMs = null;
|
|
399
383
|
unsubscribeNotify?.();
|