deepline 0.3.333 → 0.3.335
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundling-sources/sdk/src/play.ts +1 -1
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +227 -61
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +18 -0
- package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +8 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +64 -7
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-deadline.ts +14 -14
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +12 -5
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-shared.ts +6 -1
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +55 -6
- package/dist/bundling-sources/shared_libs/play-runtime/suspension.ts +1 -0
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +7 -0
- package/dist/cli/auth-7K5HVWDU.js +31 -0
- package/dist/cli/{auth-OQ356CEE.mjs → auth-UAPR5UHG.mjs} +4 -4
- package/dist/cli/{billing-7YVHLDMO.mjs → billing-2M2MOKZ2.mjs} +4 -4
- package/dist/cli/{billing-3APFTHNY.js → billing-7MFJB4YT.js} +71 -71
- package/dist/cli/{chunk-DROPDYOD.js → chunk-2BKBPQYB.js} +1 -1
- package/dist/cli/{chunk-N5KGBQPG.mjs → chunk-5CYUDMCR.mjs} +3 -3
- package/dist/cli/{chunk-H5SORD7Q.mjs → chunk-BC5OUOUV.mjs} +2 -2
- package/dist/cli/{chunk-KREEYWVL.mjs → chunk-DPTGX6LJ.mjs} +23 -10
- package/dist/cli/{chunk-JNNOCMQY.js → chunk-EBU7LQ64.js} +18 -6
- package/dist/cli/{chunk-NI4FJRFJ.mjs → chunk-F67PGWBO.mjs} +5 -5
- package/dist/cli/{chunk-HNX3RC6V.mjs → chunk-FTX3SMNS.mjs} +1 -1
- package/dist/cli/{chunk-2CLENWOQ.mjs → chunk-G7YDITCA.mjs} +1 -1
- package/dist/cli/{chunk-AFVETOG3.js → chunk-GP5TSYAJ.js} +15 -15
- package/dist/cli/{chunk-F2QKAGST.js → chunk-H2QPAGD4.js} +9 -9
- package/dist/cli/{chunk-V77J5ISS.js → chunk-H3ZK3C4S.js} +4 -4
- package/dist/cli/{chunk-AGGDEQDF.mjs → chunk-H6HO3EX2.mjs} +1 -1
- package/dist/cli/{chunk-KBXHB5P3.js → chunk-HNWBP7F4.js} +26 -26
- package/dist/cli/{chunk-3WQJWQ5T.js → chunk-L45TG5XU.js} +60 -60
- package/dist/cli/{chunk-F2XAQHQC.mjs → chunk-LD5NKLNP.mjs} +4 -4
- package/dist/cli/{chunk-64CZWDWT.js → chunk-MGQODOU7.js} +8 -8
- package/dist/cli/{chunk-6JPZJ5W7.mjs → chunk-NFZEBZN5.mjs} +2 -2
- package/dist/cli/{chunk-ABVOFJAE.mjs → chunk-OYWLA5NH.mjs} +1 -1
- package/dist/cli/{chunk-4DUEB2WO.mjs → chunk-R6HWDMKH.mjs} +2 -2
- package/dist/cli/{chunk-STVJ7ZPD.js → chunk-ROTTZP5Y.js} +6 -6
- package/dist/cli/{chunk-UHHTRBJF.js → chunk-T4A2PPAD.js} +45 -45
- package/dist/cli/{chunk-PRZ4S4NU.js → chunk-TMGNPDHK.js} +6 -6
- package/dist/cli/{chunk-SXX4ST3D.mjs → chunk-U5MMLE2K.mjs} +1 -1
- package/dist/cli/{chunk-IYFKFNEB.js → chunk-V67UHLXQ.js} +327 -314
- package/dist/cli/{chunk-SFLARO4Y.mjs → chunk-WIYWSYDS.mjs} +18 -6
- package/dist/cli/{chunk-5A44CWQE.js → chunk-YJWCFMIA.js} +48 -48
- package/dist/cli/{chunk-5UN6KLD2.mjs → chunk-Z3KXO6AE.mjs} +1 -1
- package/dist/cli/{chunk-IDEK4DND.js → chunk-ZY6VIQF3.js} +2 -2
- package/dist/cli/client-JEP4W4GO.js +20 -0
- package/dist/cli/{client-WKS7HQRP.mjs → client-O7SUBEWH.mjs} +3 -3
- package/dist/cli/{csv-ZFY2LD2K.mjs → csv-3QEFBKVA.mjs} +3 -3
- package/dist/cli/{csv-MMW6EKKD.js → csv-RKCZ32SM.js} +12 -12
- package/dist/cli/{db-FMOQU6QW.js → db-6NL2DXCZ.js} +29 -29
- package/dist/cli/{db-Q2NJVILC.mjs → db-YA77SZH2.mjs} +4 -4
- package/dist/cli/{describe-4KG2JAQV.js → describe-3T6SY4OF.js} +15 -15
- package/dist/cli/{describe-EWP7DMNU.mjs → describe-WRGAPAY4.mjs} +8 -8
- package/dist/cli/{executions-Y4XSGKN6.js → executions-4QH4WOAS.js} +6 -6
- package/dist/cli/{executions-UOD7FWEE.mjs → executions-QAXAJTVH.mjs} +4 -4
- package/dist/cli/{feedback-3F3EURZC.mjs → feedback-27PPTJMV.mjs} +3 -3
- package/dist/cli/{feedback-TEJJUXDI.js → feedback-LE2I5YC6.js} +6 -6
- package/dist/cli/getting-started.d.mts +47 -9
- package/dist/cli/getting-started.d.ts +47 -9
- package/dist/cli/getting-started.js +2 -2
- package/dist/cli/getting-started.mjs +1 -1
- package/dist/cli/{git-5YM22RGA.mjs → git-C7WLGDRA.mjs} +4 -4
- package/dist/cli/git-PY2E4CUB.js +23 -0
- package/dist/cli/index.js +79 -79
- package/dist/cli/index.mjs +31 -31
- package/dist/cli/{legacy-noops-T5OUSXMR.js → legacy-noops-LK44HVCZ.js} +7 -7
- package/dist/cli/{legacy-noops-D5XBVUHS.mjs → legacy-noops-MENMLXEB.mjs} +4 -4
- package/dist/cli/{monitors-VI7VBQRP.js → monitors-D2MOP24X.js} +85 -85
- package/dist/cli/{monitors-LPZNYNQW.mjs → monitors-EPYJCNDI.mjs} +4 -4
- package/dist/cli/{org-BYIDOMJB.mjs → org-N5YSFPOM.mjs} +4 -4
- package/dist/cli/{org-OBGIV5QE.js → org-ZEXEZJWX.js} +60 -60
- package/dist/cli/{play-Y5PQQRBO.mjs → play-EJJKDHUY.mjs} +7 -7
- package/dist/cli/play-ZLRJLPLS.js +153 -0
- package/dist/cli/{providers-GEGIGKOL.mjs → providers-5UPKT6WL.mjs} +4 -4
- package/dist/cli/{providers-VH6J7FFY.js → providers-BE7A6VON.js} +7 -7
- package/dist/cli/{quickstart-GHITFT27.mjs → quickstart-FPBWZ3XR.mjs} +4 -4
- package/dist/cli/{quickstart-ZQX5XNHG.js → quickstart-QYWCXL3Z.js} +12 -12
- package/dist/cli/{search-AFX3DYAC.mjs → search-WN6UAW3I.mjs} +5 -5
- package/dist/cli/search-XM4JURG3.js +26 -0
- package/dist/cli/{secrets-F37M7D7R.js → secrets-2NBEJSA7.js} +13 -13
- package/dist/cli/{secrets-4EOVXQJM.mjs → secrets-DGY65IAZ.mjs} +4 -4
- package/dist/cli/{sessions-T57Q72GD.js → sessions-EPSCU52L.js} +5 -5
- package/dist/cli/{sessions-RX5SFHDI.mjs → sessions-FQTEUX6Q.mjs} +4 -4
- package/dist/cli/{settings-764O5ZEH.mjs → settings-AVW7W6KG.mjs} +7 -7
- package/dist/cli/{settings-3FVWW7GL.js → settings-QWUYZKVG.js} +74 -74
- package/dist/cli/{setup-X7OAHFTO.mjs → setup-D3ZMOSVR.mjs} +7 -7
- package/dist/cli/{setup-FQVRVTR6.js → setup-G7F5LIFR.js} +49 -49
- package/dist/cli/{skills-O6ILHPV5.mjs → skills-744HOKKT.mjs} +4 -4
- package/dist/cli/skills-FNGT3DEV.js +28 -0
- package/dist/cli/tools-CPNEQIQP.js +40 -0
- package/dist/cli/{tools-HL4SQG35.mjs → tools-DJRG7RTC.mjs} +6 -6
- package/dist/cli/update-K7FVDY7F.js +28 -0
- package/dist/cli/{update-A3P2RSIB.mjs → update-ORTHR3FA.mjs} +6 -6
- package/dist/cli/{workflow-62AGKI6T.js → workflow-5IIN7CW2.js} +15 -15
- package/dist/cli/{workflow-44424AVE.mjs → workflow-XD7CRWCQ.mjs} +5 -5
- package/dist/{client-l-IoLh8Z.d.ts → client-DkoxT4wF.d.ts} +1 -1
- package/dist/{client-D5XOQKsA.d.mts → client-PDAfbylh.d.mts} +1 -1
- package/dist/{compiler-manifest-82q4jtfQ.d.ts → compiler-manifest-CButyeZ8.d.mts} +7 -0
- package/dist/{compiler-manifest-82q4jtfQ.d.mts → compiler-manifest-CButyeZ8.d.ts} +7 -0
- package/dist/{index-BPbW2XHF.d.mts → index-BMsNUoL5.d.mts} +1 -1
- package/dist/{index-k0rquHIm.d.ts → index-LDRzwo09.d.ts} +1 -1
- package/dist/index.d.mts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +6 -6
- package/dist/index.mjs +3 -3
- package/dist/install-integrity.json +82 -82
- package/dist/plays/bundle-play-file.d.mts +3 -3
- package/dist/plays/bundle-play-file.d.ts +3 -3
- 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/package.json +1 -1
- package/dist/cli/auth-26GA3RM6.js +0 -31
- package/dist/cli/client-IZRTEBU4.js +0 -20
- package/dist/cli/git-GNEZSTVF.js +0 -23
- package/dist/cli/play-5JYRSXAL.js +0 -153
- package/dist/cli/search-YIXGQFXA.js +0 -26
- package/dist/cli/skills-DPGB67XX.js +0 -28
- package/dist/cli/tools-WZCXSXER.js +0 -40
- package/dist/cli/update-63MANY7U.js +0 -28
|
@@ -477,7 +477,7 @@ export type CsvOptions = PlayAuthoringCsvOptions;
|
|
|
477
477
|
* // Emit a log line (visible in `play tail`)
|
|
478
478
|
* ctx.log(`Loaded ${await leads.count()} leads`);
|
|
479
479
|
*
|
|
480
|
-
* //
|
|
480
|
+
* // Wait at least one second before continuing.
|
|
481
481
|
* await ctx.sleep(1000);
|
|
482
482
|
*
|
|
483
483
|
* // Access submitted input through the handler's second argument.
|
|
@@ -200,7 +200,7 @@ export const SDK_RELEASE = {
|
|
|
200
200
|
// getters keep their established compatibility behavior.
|
|
201
201
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
202
202
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
203
|
-
version: '0.3.
|
|
203
|
+
version: '0.3.335',
|
|
204
204
|
updateSummary:
|
|
205
205
|
'Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.',
|
|
206
206
|
packageCapabilities: {
|
|
@@ -493,6 +493,7 @@ import {
|
|
|
493
493
|
createRuntimeSheetDatasetPageReader,
|
|
494
494
|
readRuntimeSheetDatasetRowKeys,
|
|
495
495
|
RuntimeSheetAttemptSupersededError,
|
|
496
|
+
type RuntimeSheetDatasetPageReader,
|
|
496
497
|
} from './runtime-api';
|
|
497
498
|
import { executionGatewayDecodedBodyBytes } from './execution-gateway-response-size';
|
|
498
499
|
import {
|
|
@@ -654,6 +655,7 @@ const TOOL_RETRY_AFTER_FALLBACK_MS = 1_000;
|
|
|
654
655
|
export const TOOL_EXECUTE_RESPONSE_BODY_TIMEOUT_MS = 30_000;
|
|
655
656
|
const TOOL_RETRY_HEARTBEAT_INTERVAL_MS = 30_000;
|
|
656
657
|
const TOOL_PROVIDER_RESIDENT_WAIT_BUDGET_MS = 5_000;
|
|
658
|
+
const AUTHORED_SLEEP_RESIDENT_LIMIT_MS = 10_000;
|
|
657
659
|
const DEEPLINEAGENT_TOOL_RUNTIME_TIMEOUT_MS = 15 * 60 * 1000;
|
|
658
660
|
// Every runtime-API tool fetch needs a client-side deadline. Without one, a
|
|
659
661
|
// stalled execute request (e.g. a credential-less call whose gateway connection
|
|
@@ -2929,6 +2931,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
2929
2931
|
*/
|
|
2930
2932
|
private readonly persistenceLatch: RuntimePersistenceLatch =
|
|
2931
2933
|
createRuntimePersistenceLatch();
|
|
2934
|
+
private sleepMetadataPersistenceFailed = false;
|
|
2932
2935
|
/**
|
|
2933
2936
|
* The single source of every concurrency, budget, and pacing decision for this
|
|
2934
2937
|
* run-attempt. Tool/play/row slots are blocking semaphores; budgets are charged
|
|
@@ -3154,6 +3157,9 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
3154
3157
|
*/
|
|
3155
3158
|
assertNoPendingDurableSuspension(): void {
|
|
3156
3159
|
this.#options.executionSignal?.throwIfAborted();
|
|
3160
|
+
if (this.sleepMetadataPersistenceFailed) {
|
|
3161
|
+
throw new RuntimePersistenceCircuitOpenError(this.persistenceLatch);
|
|
3162
|
+
}
|
|
3157
3163
|
this.assertNoSlackHitlTimeoutFailure();
|
|
3158
3164
|
this.assertNoRowProviderBackpressure();
|
|
3159
3165
|
if (this.pendingDurableSuspension) {
|
|
@@ -3299,6 +3305,35 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
3299
3305
|
base64: (value: SecretValue): SecretValue => createBase64SecretValue(value),
|
|
3300
3306
|
};
|
|
3301
3307
|
|
|
3308
|
+
private createRuntimeSheetDatasetPageReader(
|
|
3309
|
+
tableNamespace: string,
|
|
3310
|
+
rowMode?: 'output' | 'all',
|
|
3311
|
+
): RuntimeSheetDatasetPageReader {
|
|
3312
|
+
if (this.#options.createRuntimeSheetDatasetPageReader) {
|
|
3313
|
+
return this.#options.createRuntimeSheetDatasetPageReader({
|
|
3314
|
+
orgId: this.#options.orgId,
|
|
3315
|
+
executorToken: this.#options.executorToken!,
|
|
3316
|
+
playName: this.#options.playName!,
|
|
3317
|
+
runId: this.#options.runId!,
|
|
3318
|
+
tableNamespace,
|
|
3319
|
+
rowMode,
|
|
3320
|
+
});
|
|
3321
|
+
}
|
|
3322
|
+
return createRuntimeSheetDatasetPageReader({
|
|
3323
|
+
context: {
|
|
3324
|
+
baseUrl: this.#options.baseUrl!,
|
|
3325
|
+
executorToken: this.#options.executorToken!,
|
|
3326
|
+
dbSessionStrategy: this.#options.dbSessionStrategy,
|
|
3327
|
+
playName: this.#options.playName!,
|
|
3328
|
+
userEmail: this.#options.userEmail,
|
|
3329
|
+
runId: this.#options.runId!,
|
|
3330
|
+
},
|
|
3331
|
+
tableNamespace,
|
|
3332
|
+
runId: this.#options.runId!,
|
|
3333
|
+
rowMode,
|
|
3334
|
+
});
|
|
3335
|
+
}
|
|
3336
|
+
|
|
3302
3337
|
constructor(options: ContextOptions) {
|
|
3303
3338
|
this.rootRuntimeContract =
|
|
3304
3339
|
options.artifactRuntimeContract ??
|
|
@@ -6235,7 +6270,10 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
6235
6270
|
runningReceiptWaitMaxAttempts?: number;
|
|
6236
6271
|
runningReceiptWaitDelayMs?: number;
|
|
6237
6272
|
reclaimRunning?: boolean;
|
|
6238
|
-
markSkipped?: (
|
|
6273
|
+
markSkipped?: (
|
|
6274
|
+
output: T,
|
|
6275
|
+
receipt: RuntimeStepReceipt,
|
|
6276
|
+
) => Promise<void> | void;
|
|
6239
6277
|
onRecovered?: (
|
|
6240
6278
|
output: T,
|
|
6241
6279
|
receipt: RuntimeStepReceipt,
|
|
@@ -9009,18 +9047,8 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
9009
9047
|
at: Date.now(),
|
|
9010
9048
|
});
|
|
9011
9049
|
|
|
9012
|
-
const runtimeBackedMapPageReader =
|
|
9013
|
-
|
|
9014
|
-
baseUrl: this.#options.baseUrl!,
|
|
9015
|
-
executorToken: this.#options.executorToken!,
|
|
9016
|
-
dbSessionStrategy: this.#options.dbSessionStrategy,
|
|
9017
|
-
playName: this.#options.playName!,
|
|
9018
|
-
userEmail: this.#options.userEmail,
|
|
9019
|
-
runId: this.#options.runId!,
|
|
9020
|
-
},
|
|
9021
|
-
tableNamespace: resolvedTableNamespace,
|
|
9022
|
-
runId: this.#options.runId!,
|
|
9023
|
-
});
|
|
9050
|
+
const runtimeBackedMapPageReader =
|
|
9051
|
+
this.createRuntimeSheetDatasetPageReader(resolvedTableNamespace);
|
|
9024
9052
|
const readRuntimeBackedMapRows = async (input: {
|
|
9025
9053
|
limit: number;
|
|
9026
9054
|
offset: number;
|
|
@@ -9750,19 +9778,10 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
9750
9778
|
// Output mode selects enriched rows when this replay's earlier
|
|
9751
9779
|
// invocation also persisted isolated failures.
|
|
9752
9780
|
const finalizationRowMode = resumedPendingRowsOnly ? 'output' : 'all';
|
|
9753
|
-
const finalizationPageReader = createRuntimeSheetDatasetPageReader(
|
|
9754
|
-
|
|
9755
|
-
|
|
9756
|
-
|
|
9757
|
-
dbSessionStrategy: this.#options.dbSessionStrategy,
|
|
9758
|
-
playName: this.#options.playName!,
|
|
9759
|
-
userEmail: this.#options.userEmail,
|
|
9760
|
-
runId: this.#options.runId!,
|
|
9761
|
-
},
|
|
9762
|
-
tableNamespace: resolvedTableNamespace,
|
|
9763
|
-
runId: this.#options.runId!,
|
|
9764
|
-
rowMode: finalizationRowMode,
|
|
9765
|
-
});
|
|
9781
|
+
const finalizationPageReader = this.createRuntimeSheetDatasetPageReader(
|
|
9782
|
+
resolvedTableNamespace,
|
|
9783
|
+
finalizationRowMode,
|
|
9784
|
+
);
|
|
9766
9785
|
results = await reconcileNodeRuntimeMapResultsWithPersistedSheet({
|
|
9767
9786
|
mapName: normalizedMapNamespace,
|
|
9768
9787
|
tableNamespace: resolvedTableNamespace,
|
|
@@ -9833,18 +9852,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
9833
9852
|
this.#options.runId,
|
|
9834
9853
|
);
|
|
9835
9854
|
const fullPersistedPageReader = runtimeSheetBacked
|
|
9836
|
-
? createRuntimeSheetDatasetPageReader(
|
|
9837
|
-
context: {
|
|
9838
|
-
baseUrl: this.#options.baseUrl!,
|
|
9839
|
-
executorToken: this.#options.executorToken!,
|
|
9840
|
-
dbSessionStrategy: this.#options.dbSessionStrategy,
|
|
9841
|
-
playName: this.#options.playName!,
|
|
9842
|
-
userEmail: this.#options.userEmail,
|
|
9843
|
-
runId: this.#options.runId!,
|
|
9844
|
-
},
|
|
9845
|
-
tableNamespace: resolvedTableNamespace,
|
|
9846
|
-
runId: this.#options.runId!,
|
|
9847
|
-
})
|
|
9855
|
+
? this.createRuntimeSheetDatasetPageReader(resolvedTableNamespace)
|
|
9848
9856
|
: null;
|
|
9849
9857
|
const materializeFullPersistedMapRows = async (limit?: number) => {
|
|
9850
9858
|
if (!runtimeSheetBacked) {
|
|
@@ -10744,9 +10752,14 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
10744
10752
|
return [
|
|
10745
10753
|
{
|
|
10746
10754
|
inputIndex: executionRowIndex(index),
|
|
10747
|
-
|
|
10748
|
-
|
|
10749
|
-
|
|
10755
|
+
// Checkpoint replay must keep the admitted identity even
|
|
10756
|
+
// when restored output columns change the default row hash.
|
|
10757
|
+
data: {
|
|
10758
|
+
...this.toPersistedOutputRow(
|
|
10759
|
+
this.toOutputRow(item as Record<string, unknown>),
|
|
10760
|
+
),
|
|
10761
|
+
...mapRowOutcomeRuntimeFields({ key: rowKey }),
|
|
10762
|
+
},
|
|
10750
10763
|
...(runtimeOptions?.authoredInputDigests?.[index]
|
|
10751
10764
|
? {
|
|
10752
10765
|
authoredInputDigest:
|
|
@@ -11147,7 +11160,14 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
11147
11160
|
return [
|
|
11148
11161
|
{
|
|
11149
11162
|
inputIndex: executionRowIndex(index),
|
|
11150
|
-
|
|
11163
|
+
// Preserve the admitted key rather than rehashing the
|
|
11164
|
+
// waiting row after persisted output fields are restored.
|
|
11165
|
+
data: {
|
|
11166
|
+
...this.toPersistedOutputRow(baseRow),
|
|
11167
|
+
...mapRowOutcomeRuntimeFields({
|
|
11168
|
+
key: keyForIndex(index),
|
|
11169
|
+
}),
|
|
11170
|
+
},
|
|
11151
11171
|
...(runtimeOptions?.authoredInputDigests?.[index]
|
|
11152
11172
|
? {
|
|
11153
11173
|
authoredInputDigest:
|
|
@@ -14581,6 +14601,111 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
14581
14601
|
this.suspendDurably({ kind: 'sleep', boundaryId, delayMs });
|
|
14582
14602
|
}
|
|
14583
14603
|
|
|
14604
|
+
private sleepMetadataReceiptKey(
|
|
14605
|
+
boundaryId: string,
|
|
14606
|
+
intent: 'wake' | 'count',
|
|
14607
|
+
): string {
|
|
14608
|
+
return durableCtxKey({
|
|
14609
|
+
orgId: this.#options.orgId,
|
|
14610
|
+
playId: this.currentExecutionScope.receipt.namespace,
|
|
14611
|
+
operation: 'step',
|
|
14612
|
+
id: `__deepline_sleep_${intent}__`,
|
|
14613
|
+
semanticKey: stableStringify({
|
|
14614
|
+
runId: this.currentReceiptOwnerRunId,
|
|
14615
|
+
boundaryId,
|
|
14616
|
+
}),
|
|
14617
|
+
});
|
|
14618
|
+
}
|
|
14619
|
+
|
|
14620
|
+
private async readStepSleepCount(boundaryId: string): Promise<number | null> {
|
|
14621
|
+
try {
|
|
14622
|
+
const receipt = await this.getRuntimeStepReceipt(
|
|
14623
|
+
this.sleepMetadataReceiptKey(boundaryId, 'count'),
|
|
14624
|
+
);
|
|
14625
|
+
if (receipt?.status !== 'completed') return null;
|
|
14626
|
+
const output = receipt.output;
|
|
14627
|
+
const sleepCount =
|
|
14628
|
+
output && typeof output === 'object' && 'sleepCount' in output
|
|
14629
|
+
? output.sleepCount
|
|
14630
|
+
: undefined;
|
|
14631
|
+
if (
|
|
14632
|
+
typeof sleepCount !== 'number' ||
|
|
14633
|
+
!Number.isSafeInteger(sleepCount) ||
|
|
14634
|
+
sleepCount < 0
|
|
14635
|
+
) {
|
|
14636
|
+
throw new Error(`Durable step ${boundaryId} has no valid sleep count.`);
|
|
14637
|
+
}
|
|
14638
|
+
return sleepCount;
|
|
14639
|
+
} catch (error) {
|
|
14640
|
+
this.sleepMetadataPersistenceFailed = true;
|
|
14641
|
+
tripRuntimePersistenceLatch(this.persistenceLatch, error);
|
|
14642
|
+
throw error;
|
|
14643
|
+
}
|
|
14644
|
+
}
|
|
14645
|
+
|
|
14646
|
+
private async persistStepSleepCount(
|
|
14647
|
+
boundaryId: string,
|
|
14648
|
+
sleepCount: number,
|
|
14649
|
+
): Promise<void> {
|
|
14650
|
+
try {
|
|
14651
|
+
await this.completeRuntimeStepReceipt(
|
|
14652
|
+
this.sleepMetadataReceiptKey(boundaryId, 'count'),
|
|
14653
|
+
this.currentReceiptOwnerRunId,
|
|
14654
|
+
{ sleepCount },
|
|
14655
|
+
COMPLETED_RECEIPT_CACHE_INSERT_LEASE_ID,
|
|
14656
|
+
);
|
|
14657
|
+
if ((await this.readStepSleepCount(boundaryId)) === null) {
|
|
14658
|
+
throw new Error(
|
|
14659
|
+
`Durable step ${boundaryId} did not persist its sleep count.`,
|
|
14660
|
+
);
|
|
14661
|
+
}
|
|
14662
|
+
} catch (error) {
|
|
14663
|
+
this.sleepMetadataPersistenceFailed = true;
|
|
14664
|
+
tripRuntimePersistenceLatch(this.persistenceLatch, error);
|
|
14665
|
+
throw error;
|
|
14666
|
+
}
|
|
14667
|
+
}
|
|
14668
|
+
|
|
14669
|
+
private async resolveCanonicalSleepWakeAtMs(
|
|
14670
|
+
boundaryId: string,
|
|
14671
|
+
delayMs: number,
|
|
14672
|
+
): Promise<number> {
|
|
14673
|
+
const key = this.sleepMetadataReceiptKey(boundaryId, 'wake');
|
|
14674
|
+
const proposedWakeAtMs = Date.now() + delayMs;
|
|
14675
|
+
try {
|
|
14676
|
+
let receipt = await this.getRuntimeStepReceipt(key);
|
|
14677
|
+
if (receipt?.status !== 'completed') {
|
|
14678
|
+
await this.completeRuntimeStepReceipt(
|
|
14679
|
+
key,
|
|
14680
|
+
this.currentReceiptOwnerRunId,
|
|
14681
|
+
{ wakeAtMs: proposedWakeAtMs },
|
|
14682
|
+
COMPLETED_RECEIPT_CACHE_INSERT_LEASE_ID,
|
|
14683
|
+
);
|
|
14684
|
+
receipt = await this.getRuntimeStepReceipt(key);
|
|
14685
|
+
}
|
|
14686
|
+
const output = receipt?.output;
|
|
14687
|
+
const wakeAtMs =
|
|
14688
|
+
output && typeof output === 'object' && 'wakeAtMs' in output
|
|
14689
|
+
? output.wakeAtMs
|
|
14690
|
+
: undefined;
|
|
14691
|
+
if (
|
|
14692
|
+
receipt?.status !== 'completed' ||
|
|
14693
|
+
typeof wakeAtMs !== 'number' ||
|
|
14694
|
+
!Number.isSafeInteger(wakeAtMs) ||
|
|
14695
|
+
wakeAtMs < 0
|
|
14696
|
+
) {
|
|
14697
|
+
throw new Error(
|
|
14698
|
+
`Durable sleep intent ${boundaryId} has no valid wake timestamp.`,
|
|
14699
|
+
);
|
|
14700
|
+
}
|
|
14701
|
+
return wakeAtMs;
|
|
14702
|
+
} catch (error) {
|
|
14703
|
+
this.sleepMetadataPersistenceFailed = true;
|
|
14704
|
+
tripRuntimePersistenceLatch(this.persistenceLatch, error);
|
|
14705
|
+
throw error;
|
|
14706
|
+
}
|
|
14707
|
+
}
|
|
14708
|
+
|
|
14584
14709
|
async sleep(ms: number): Promise<void> {
|
|
14585
14710
|
if (!rowContext.getStore()) this.assertRowAdmissionOpen();
|
|
14586
14711
|
this.assertNoPendingDurableSuspension();
|
|
@@ -14654,17 +14779,49 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
14654
14779
|
if (existing?.kind === 'sleep' && existing.completedAt !== undefined) {
|
|
14655
14780
|
return;
|
|
14656
14781
|
}
|
|
14782
|
+
const wakeAtMs =
|
|
14783
|
+
existing?.kind === 'sleep' && existing.wakeAtMs !== undefined
|
|
14784
|
+
? existing.wakeAtMs
|
|
14785
|
+
: this.durableDirectToolResultsBackedByReceipts
|
|
14786
|
+
? await this.resolveCanonicalSleepWakeAtMs(boundaryId, delayMs)
|
|
14787
|
+
: undefined;
|
|
14788
|
+
this.assertNoPendingDurableSuspension();
|
|
14657
14789
|
this.checkpoint.resolvedBoundaries = {
|
|
14658
14790
|
...(this.checkpoint.resolvedBoundaries ?? {}),
|
|
14659
14791
|
[boundaryId]: {
|
|
14792
|
+
...existing,
|
|
14660
14793
|
kind: 'sleep',
|
|
14661
14794
|
delayMs,
|
|
14795
|
+
...(wakeAtMs !== undefined ? { wakeAtMs } : {}),
|
|
14662
14796
|
},
|
|
14663
14797
|
};
|
|
14798
|
+
if (
|
|
14799
|
+
wakeAtMs !== undefined &&
|
|
14800
|
+
!rowStore &&
|
|
14801
|
+
this.durableDirectToolResultsBackedByReceipts &&
|
|
14802
|
+
(wakeAtMs <= Date.now() ||
|
|
14803
|
+
(delayMs <= AUTHORED_SLEEP_RESIDENT_LIMIT_MS &&
|
|
14804
|
+
wakeAtMs < (this.#options.executionDrainAtMs ?? Infinity)))
|
|
14805
|
+
) {
|
|
14806
|
+
const remainingMs = Math.max(0, wakeAtMs - Date.now());
|
|
14807
|
+
if (remainingMs > 0)
|
|
14808
|
+
await this.sleepWithCheckpointHeartbeat(remainingMs);
|
|
14809
|
+
this.assertNoPendingDurableSuspension();
|
|
14810
|
+
this.checkpoint.resolvedBoundaries[boundaryId] = {
|
|
14811
|
+
...this.checkpoint.resolvedBoundaries[boundaryId],
|
|
14812
|
+
kind: 'sleep',
|
|
14813
|
+
delayMs,
|
|
14814
|
+
wakeAtMs,
|
|
14815
|
+
completedAt: Date.now(),
|
|
14816
|
+
};
|
|
14817
|
+
this.#options.onBatchComplete?.(this.checkpoint);
|
|
14818
|
+
return;
|
|
14819
|
+
}
|
|
14664
14820
|
this.suspendDurably({
|
|
14665
14821
|
kind: 'sleep',
|
|
14666
14822
|
boundaryId,
|
|
14667
14823
|
delayMs,
|
|
14824
|
+
...(wakeAtMs !== undefined ? { wakeAtMs } : {}),
|
|
14668
14825
|
});
|
|
14669
14826
|
}
|
|
14670
14827
|
return new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
@@ -15001,30 +15158,33 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
15001
15158
|
const boundaryId = this.durableBoundaryId(
|
|
15002
15159
|
`step-${scope}:${normalizedKey}${boundarySuffix}`,
|
|
15003
15160
|
);
|
|
15161
|
+
const advanceRecoveredSleepCursor = async (
|
|
15162
|
+
receipt?: RuntimeStepReceipt,
|
|
15163
|
+
) => {
|
|
15164
|
+
if (rowStore?.replayCallIndexes?.recoverStep(boundaryId)) return;
|
|
15165
|
+
const existing = assertKnownResolvedBoundary(
|
|
15166
|
+
boundaryId,
|
|
15167
|
+
this.checkpoint.resolvedBoundaries?.[boundaryId],
|
|
15168
|
+
);
|
|
15169
|
+
const sleepCount =
|
|
15170
|
+
existing?.kind === 'step' && existing.sleepCount !== undefined
|
|
15171
|
+
? existing.sleepCount
|
|
15172
|
+
: receipt?.runId === this.currentReceiptOwnerRunId
|
|
15173
|
+
? ((await this.readStepSleepCount(boundaryId)) ?? 0)
|
|
15174
|
+
: 0;
|
|
15175
|
+
if (Number.isSafeInteger(sleepCount) && sleepCount > 0)
|
|
15176
|
+
this.sleepBoundaryIndex += sleepCount;
|
|
15177
|
+
};
|
|
15004
15178
|
const executeStep = async (): Promise<T> => {
|
|
15005
15179
|
const existing = assertKnownResolvedBoundary(
|
|
15006
15180
|
boundaryId,
|
|
15007
15181
|
this.checkpoint.resolvedBoundaries?.[boundaryId],
|
|
15008
15182
|
);
|
|
15009
15183
|
if (existing?.kind === 'step' && 'output' in existing) {
|
|
15010
|
-
const replayedCalls =
|
|
15011
|
-
rowStore?.replayCallIndexes?.recoverStep(boundaryId) ?? false;
|
|
15012
15184
|
this.runtimeLog(
|
|
15013
15185
|
`ctx.step(${normalizedKey}): recovered result from checkpoint`,
|
|
15014
15186
|
);
|
|
15015
|
-
|
|
15016
|
-
// contained would otherwise disappear from the positional sleep
|
|
15017
|
-
// cursor. Preserve the authored boundary sequence before evaluating
|
|
15018
|
-
// the next sibling operation. This is deliberately run-local state;
|
|
15019
|
-
// it is not a cross-run sleep cache or an input-derived identity.
|
|
15020
|
-
if (
|
|
15021
|
-
!replayedCalls &&
|
|
15022
|
-
Number.isSafeInteger(existing.sleepCount) &&
|
|
15023
|
-
existing.sleepCount !== undefined &&
|
|
15024
|
-
existing.sleepCount > 0
|
|
15025
|
-
) {
|
|
15026
|
-
this.sleepBoundaryIndex += existing.sleepCount;
|
|
15027
|
-
}
|
|
15187
|
+
await advanceRecoveredSleepCursor();
|
|
15028
15188
|
return existing.output as T;
|
|
15029
15189
|
}
|
|
15030
15190
|
|
|
@@ -15047,15 +15207,20 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
15047
15207
|
// publish an enclosing step fallback that would make a later resume skip
|
|
15048
15208
|
// the suspended work.
|
|
15049
15209
|
this.assertNoPendingDurableSuspension();
|
|
15210
|
+
const sleepCount = rowStore?.replayCallIndexes
|
|
15211
|
+
? (callAdvances.get('sleep:legacy') ?? 0)
|
|
15212
|
+
: this.sleepBoundaryIndex - sleepBoundaryIndexBefore;
|
|
15213
|
+
if (sleepCount > 0 && this.durableDirectToolResultsBackedByReceipts) {
|
|
15214
|
+
await this.persistStepSleepCount(boundaryId, sleepCount);
|
|
15215
|
+
}
|
|
15216
|
+
this.assertNoPendingDurableSuspension();
|
|
15050
15217
|
this.checkpoint.resolvedBoundaries = {
|
|
15051
15218
|
...(this.checkpoint.resolvedBoundaries ?? {}),
|
|
15052
15219
|
[boundaryId]: {
|
|
15053
15220
|
kind: 'step',
|
|
15054
15221
|
stepId: normalizedKey,
|
|
15055
15222
|
output,
|
|
15056
|
-
sleepCount
|
|
15057
|
-
? (callAdvances.get('sleep:legacy') ?? 0)
|
|
15058
|
-
: this.sleepBoundaryIndex - sleepBoundaryIndexBefore,
|
|
15223
|
+
sleepCount,
|
|
15059
15224
|
completedAt: Date.now(),
|
|
15060
15225
|
},
|
|
15061
15226
|
};
|
|
@@ -15100,8 +15265,9 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
15100
15265
|
: options?.semanticKey,
|
|
15101
15266
|
staleAfterSeconds: options?.staleAfterSeconds,
|
|
15102
15267
|
force: this.#options.cachePolicy?.forceStepRefresh === true,
|
|
15103
|
-
markSkipped: (output) => {
|
|
15268
|
+
markSkipped: async (output, receipt) => {
|
|
15104
15269
|
assertJsonSerializableStepOutput(normalizedKey, output);
|
|
15270
|
+
await advanceRecoveredSleepCursor(receipt);
|
|
15105
15271
|
},
|
|
15106
15272
|
execute: executeStep,
|
|
15107
15273
|
},
|
|
@@ -12,6 +12,7 @@ import type { PlayDatasetColumnTypes } from '../play-data-plane/contracts';
|
|
|
12
12
|
import type { PlayStructuredDefinition } from '../plays/definition';
|
|
13
13
|
import type { PlayStaticPipeline } from '../plays/static-pipeline';
|
|
14
14
|
import type { PlayLogContext, PlayLogMetadata } from './log-context';
|
|
15
|
+
import type { RuntimeSheetDatasetPageReader } from './runtime-api';
|
|
15
16
|
import type {
|
|
16
17
|
AsyncPlayRunRef,
|
|
17
18
|
DurableCallStaleAfterSeconds,
|
|
@@ -772,6 +773,15 @@ export type IntegrationEventWaitHandler = {
|
|
|
772
773
|
suspendAfterTimeoutMs?: number;
|
|
773
774
|
};
|
|
774
775
|
|
|
776
|
+
export type RuntimeSheetDatasetPageReaderScope = {
|
|
777
|
+
orgId?: string;
|
|
778
|
+
executorToken: string;
|
|
779
|
+
playName: string;
|
|
780
|
+
runId: string;
|
|
781
|
+
tableNamespace: string;
|
|
782
|
+
rowMode?: 'output' | 'all';
|
|
783
|
+
};
|
|
784
|
+
|
|
775
785
|
export interface ContextOptions {
|
|
776
786
|
/**
|
|
777
787
|
* Immutable worker projection resolved once from the admitted Play artifact.
|
|
@@ -815,11 +825,17 @@ export interface ContextOptions {
|
|
|
815
825
|
rowAdmissionSignal?: AbortSignal;
|
|
816
826
|
/** Local runner cancellation; never serialized into a Play artifact. */
|
|
817
827
|
executionSignal?: AbortSignal;
|
|
828
|
+
/** Runner-local deadline for stopping new work, captured when its timer arms. */
|
|
829
|
+
executionDrainAtMs?: number;
|
|
818
830
|
/**
|
|
819
831
|
* Runtime-sheet transport selected by the runner. Daytona sandboxes use the
|
|
820
832
|
* execution gateway and must never fall back to minting direct DB sessions.
|
|
821
833
|
*/
|
|
822
834
|
dbSessionStrategy?: 'preloaded' | 'gateway_only' | 'trusted_dynamic';
|
|
835
|
+
/** Runner-owned reader; scoped database authority stays outside authored code. */
|
|
836
|
+
createRuntimeSheetDatasetPageReader?: (
|
|
837
|
+
scope: RuntimeSheetDatasetPageReaderScope,
|
|
838
|
+
) => RuntimeSheetDatasetPageReader;
|
|
823
839
|
vercelProtectionBypassToken?: string | null;
|
|
824
840
|
/** Optional per-run integration execution mode for provider calls. */
|
|
825
841
|
integrationMode?: 'live' | 'eval_stub' | 'fixture';
|
|
@@ -1244,6 +1260,8 @@ export interface PlayCheckpoint {
|
|
|
1244
1260
|
| {
|
|
1245
1261
|
kind: 'sleep';
|
|
1246
1262
|
delayMs: number;
|
|
1263
|
+
/** Original wake deadline. Historical boundaries retain relative waits. */
|
|
1264
|
+
wakeAtMs?: number;
|
|
1247
1265
|
completedAt?: number;
|
|
1248
1266
|
scope?: {
|
|
1249
1267
|
type: 'workflow' | 'map_row';
|
|
@@ -777,7 +777,10 @@ export async function executeWithDurableRuntimeReceipt<T>(input: {
|
|
|
777
777
|
runningReceiptWaitMaxAttempts?: number;
|
|
778
778
|
runningReceiptWaitDelayMs?: number;
|
|
779
779
|
reclaimRunning?: boolean;
|
|
780
|
-
markSkipped?: (
|
|
780
|
+
markSkipped?: (
|
|
781
|
+
output: T,
|
|
782
|
+
receipt: RuntimeStepReceipt,
|
|
783
|
+
) => Promise<void> | void;
|
|
781
784
|
onRecovered?: (
|
|
782
785
|
output: T,
|
|
783
786
|
receipt: RuntimeStepReceipt,
|
|
@@ -812,6 +815,9 @@ export async function executeWithDurableRuntimeReceipt<T>(input: {
|
|
|
812
815
|
): Promise<T> => {
|
|
813
816
|
input.log(`ctx.${input.operation}(${input.id}): reused completed work`);
|
|
814
817
|
if (receipt.output === undefined) {
|
|
818
|
+
if (input.operation === 'step' && input.markSkipped) {
|
|
819
|
+
await input.markSkipped(receipt.output as T, receipt);
|
|
820
|
+
}
|
|
815
821
|
return receipt.output as T;
|
|
816
822
|
}
|
|
817
823
|
const output = runtimeReceiptOutput<T>(receipt);
|
|
@@ -819,7 +825,7 @@ export async function executeWithDurableRuntimeReceipt<T>(input: {
|
|
|
819
825
|
? input.onRecovered(output, receipt, 'cache')
|
|
820
826
|
: output;
|
|
821
827
|
if (input.markSkipped) {
|
|
822
|
-
await input.markSkipped(recovered);
|
|
828
|
+
await input.markSkipped(recovered, receipt);
|
|
823
829
|
}
|
|
824
830
|
return recovered;
|
|
825
831
|
};
|
|
@@ -87,6 +87,7 @@ import { getPlayRuntimeBatchStrategy } from '../play-runtime-batching-registry';
|
|
|
87
87
|
import type { ToolResultMetadataInput } from '../tool-result';
|
|
88
88
|
import type {
|
|
89
89
|
ContextOptions,
|
|
90
|
+
RuntimeSheetDatasetPageReaderScope,
|
|
90
91
|
IntegrationEventWaitBoundary,
|
|
91
92
|
IntegrationEventWaitHandler,
|
|
92
93
|
IntegrationEventWaitRuntimeContext,
|
|
@@ -121,6 +122,8 @@ import {
|
|
|
121
122
|
import {
|
|
122
123
|
resolveRuntimeReferencedPlay,
|
|
123
124
|
createCompleteRuntimeMapRowsOperation,
|
|
125
|
+
createRuntimeSheetDatasetPageReader,
|
|
126
|
+
type RuntimeSheetDatasetPageReader,
|
|
124
127
|
readRuntimeSheetDatasetRowKeys,
|
|
125
128
|
readRuntimeSheetDatasetRows,
|
|
126
129
|
releaseRuntimeWorkReceipts,
|
|
@@ -1159,6 +1162,7 @@ export interface ExecutePlayRunnerOptions {
|
|
|
1159
1162
|
signal?: AbortSignal;
|
|
1160
1163
|
/** Stops future row admission while already admitted rows can persist. */
|
|
1161
1164
|
rowAdmissionSignal?: AbortSignal;
|
|
1165
|
+
executionDrainAtMs?: number;
|
|
1162
1166
|
/** Runner-local terminal state made available to the deadline drain. */
|
|
1163
1167
|
onRuntimeReady?: (runtime: {
|
|
1164
1168
|
log: (line: string) => void;
|
|
@@ -1318,6 +1322,48 @@ export function assertPlayRunnerRuntimeSheetPersistenceContext(
|
|
|
1318
1322
|
}
|
|
1319
1323
|
}
|
|
1320
1324
|
|
|
1325
|
+
/** Keep launch-scoped database authority in the runner that admitted it. */
|
|
1326
|
+
export function createPlayRunnerRuntimeSheetDatasetPageReader(input: {
|
|
1327
|
+
context: PlayRunnerExecutionConfig['context'];
|
|
1328
|
+
preloadedDbSessions: PlayRunnerExecutionConfig['context']['preloadedDbSessions'];
|
|
1329
|
+
postgresSessionUnwrapKey: string | null;
|
|
1330
|
+
abortSignal: AbortSignal;
|
|
1331
|
+
scope: RuntimeSheetDatasetPageReaderScope;
|
|
1332
|
+
}): RuntimeSheetDatasetPageReader {
|
|
1333
|
+
const { context, scope } = input;
|
|
1334
|
+
assertPlayRunnerRuntimeSheetPersistenceContext(context);
|
|
1335
|
+
const rootRunId = context.runId ?? context.workflowId;
|
|
1336
|
+
if (
|
|
1337
|
+
scope.orgId !== context.orgId ||
|
|
1338
|
+
scope.playName !== context.playName ||
|
|
1339
|
+
scope.runId !== rootRunId ||
|
|
1340
|
+
scope.executorToken !== context.executorToken
|
|
1341
|
+
) {
|
|
1342
|
+
throw new Error(
|
|
1343
|
+
'Runtime Sheet reader scope does not match the run launch authority.',
|
|
1344
|
+
);
|
|
1345
|
+
}
|
|
1346
|
+
return createRuntimeSheetDatasetPageReader({
|
|
1347
|
+
context: {
|
|
1348
|
+
baseUrl: context.baseUrl,
|
|
1349
|
+
executorToken: scope.executorToken,
|
|
1350
|
+
orgId: scope.orgId,
|
|
1351
|
+
playName: scope.playName,
|
|
1352
|
+
runId: scope.runId,
|
|
1353
|
+
userEmail: context.userEmail,
|
|
1354
|
+
dbSessionStrategy: context.dbSessionStrategy,
|
|
1355
|
+
preloadedDbSessions: input.preloadedDbSessions,
|
|
1356
|
+
postgresSessionUnwrapKey: input.postgresSessionUnwrapKey,
|
|
1357
|
+
vercelProtectionBypassToken: context.vercelProtectionBypassToken,
|
|
1358
|
+
runtimeTestFaultHeader: context.runtimeTestFaultHeader ?? null,
|
|
1359
|
+
abortSignal: input.abortSignal,
|
|
1360
|
+
},
|
|
1361
|
+
tableNamespace: scope.tableNamespace,
|
|
1362
|
+
runId: scope.runId,
|
|
1363
|
+
rowMode: scope.rowMode,
|
|
1364
|
+
});
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1321
1367
|
function collectReturnedDatasets(value: unknown): unknown[] {
|
|
1322
1368
|
const datasets: unknown[] = [];
|
|
1323
1369
|
const seen = new Set<unknown>();
|
|
@@ -2036,14 +2082,15 @@ async function run(
|
|
|
2036
2082
|
runnerRunAttempt,
|
|
2037
2083
|
);
|
|
2038
2084
|
const workCounterSegmentId = randomUUID();
|
|
2085
|
+
const runtimeLimitMs =
|
|
2086
|
+
validatePlaySandboxRuntimeLimits(
|
|
2087
|
+
config.context.sandboxRuntimeLimits ??
|
|
2088
|
+
STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS,
|
|
2089
|
+
).timeoutSeconds * 1_000;
|
|
2039
2090
|
const persistenceSignal =
|
|
2040
|
-
options?.signal ??
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
config.context.sandboxRuntimeLimits ??
|
|
2044
|
-
STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS,
|
|
2045
|
-
).timeoutSeconds * 1_000,
|
|
2046
|
-
);
|
|
2091
|
+
options?.signal ?? AbortSignal.timeout(runtimeLimitMs);
|
|
2092
|
+
const executionDrainAtMs =
|
|
2093
|
+
options?.executionDrainAtMs ?? runStartedAt + runtimeLimitMs;
|
|
2047
2094
|
const contextSetupStartedAt = Date.now();
|
|
2048
2095
|
const getRuntimeToolMetadata = createRuntimeToolMetadataResolver(config);
|
|
2049
2096
|
const getRuntimeToolAuthScopeDigest =
|
|
@@ -2225,6 +2272,7 @@ async function run(
|
|
|
2225
2272
|
artifactRuntimeContract,
|
|
2226
2273
|
rowAdmissionSignal: options?.rowAdmissionSignal,
|
|
2227
2274
|
executionSignal: persistenceSignal,
|
|
2275
|
+
executionDrainAtMs,
|
|
2228
2276
|
executorToken: config.context.executorToken,
|
|
2229
2277
|
baseUrl: config.context.baseUrl,
|
|
2230
2278
|
// Runtime control stays on baseUrl (the receipt gateway); provider calls
|
|
@@ -2274,6 +2322,14 @@ async function run(
|
|
|
2274
2322
|
}
|
|
2275
2323
|
},
|
|
2276
2324
|
dbSessionStrategy: config.context.dbSessionStrategy,
|
|
2325
|
+
createRuntimeSheetDatasetPageReader: (scope) =>
|
|
2326
|
+
createPlayRunnerRuntimeSheetDatasetPageReader({
|
|
2327
|
+
context: config.context,
|
|
2328
|
+
preloadedDbSessions: runtimePreloadedDbSessions,
|
|
2329
|
+
postgresSessionUnwrapKey: runtimePostgresSessionUnwrapKey,
|
|
2330
|
+
abortSignal: persistenceSignal,
|
|
2331
|
+
scope,
|
|
2332
|
+
}),
|
|
2277
2333
|
fetchImpl: safeNodeStreamingOutboundFetch,
|
|
2278
2334
|
vercelProtectionBypassToken: config.context.vercelProtectionBypassToken,
|
|
2279
2335
|
orgId: config.context.orgId,
|
|
@@ -3894,6 +3950,7 @@ async function main() {
|
|
|
3894
3950
|
result = await executePlayRunner(config, {
|
|
3895
3951
|
signal: executionController.signal,
|
|
3896
3952
|
rowAdmissionSignal: rowAdmissionController.signal,
|
|
3953
|
+
executionDrainAtMs: runtimeDeadline.drainAtMs,
|
|
3897
3954
|
onRuntimeReady: (runtime) => {
|
|
3898
3955
|
runtimeState = runtime;
|
|
3899
3956
|
},
|