deepline 0.3.408 → 0.3.410
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/agent-runtime.ts +18 -1
- package/dist/bundling-sources/sdk/src/client.ts +212 -334
- package/dist/bundling-sources/sdk/src/compat.ts +45 -2
- package/dist/bundling-sources/sdk/src/db/query.ts +9 -10
- package/dist/bundling-sources/sdk/src/http.ts +38 -20
- package/dist/bundling-sources/sdk/src/index.ts +4 -5
- package/dist/bundling-sources/sdk/src/play.ts +10 -10
- package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +6 -4
- package/dist/bundling-sources/sdk/src/plays/check-local-play-graph.ts +114 -0
- package/dist/bundling-sources/sdk/src/plays/client.ts +431 -0
- package/dist/bundling-sources/sdk/src/plays/local-play-execution.ts +2 -2
- package/dist/bundling-sources/sdk/src/plays/run-request.ts +106 -16
- package/dist/bundling-sources/sdk/src/release.ts +13 -7
- package/dist/bundling-sources/sdk/src/runs/read-errors.ts +8 -0
- package/dist/bundling-sources/sdk/src/runs/watch-polling.ts +124 -13
- package/dist/bundling-sources/sdk/src/tool-calls.ts +108 -19
- package/dist/bundling-sources/sdk/src/types.ts +18 -0
- package/dist/bundling-sources/shared_libs/integration-contracts/execute-retry-contract.ts +37 -0
- package/dist/bundling-sources/shared_libs/integration-contracts/package.json +3 -0
- package/dist/bundling-sources/shared_libs/play-data-plane/r2.ts +3 -1
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +277 -76
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/dataset-row-input.ts +124 -0
- package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +6 -62
- package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/durable-tool-identity.ts +67 -0
- package/dist/bundling-sources/shared_libs/play-runtime/execute-server-timing.ts +64 -6
- package/dist/bundling-sources/shared_libs/play-runtime/freshness-receipt-execution.ts +1 -5
- package/dist/bundling-sources/shared_libs/play-runtime/ledger-safe-payload.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/play-artifact-runtime-contract.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-http-request.ts +10 -0
- package/dist/bundling-sources/shared_libs/play-runtime/query-result-dataset.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/egress-probe.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +26 -16
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-heartbeat.ts +36 -11
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-terminal-push.ts +35 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-launch-transport.ts +21 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +21 -6
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-session-execution.ts +11 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +85 -20
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +71 -13
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-execution-queries.ts +100 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-pool.ts +9 -5
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +337 -146
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-shared.ts +26 -12
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-state.ts +3 -1
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +425 -102
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-dispatch-authority.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +9 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +181 -124
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-worker-wake.ts +152 -0
- package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +5 -3
- package/dist/bundling-sources/shared_libs/play-runtime/tool-cache-policy.ts +31 -0
- package/dist/bundling-sources/shared_libs/play-runtime/transient-service-error.ts +10 -0
- package/dist/bundling-sources/shared_libs/plays/ambiguous-write-error.ts +25 -0
- package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +4 -0
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +63 -68
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +129 -63
- package/dist/bundling-sources/shared_libs/plays/contracts.ts +14 -0
- package/dist/bundling-sources/shared_libs/plays/enrich-play-compiler.ts +58 -16
- package/dist/bundling-sources/shared_libs/plays/fetch-http-error.ts +50 -0
- package/dist/bundling-sources/shared_libs/plays/source-authoring-edition.ts +351 -0
- package/dist/bundling-sources/shared_libs/plays/tool-list-getter-mode.ts +9 -0
- package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +1 -1
- package/dist/cli/{auth-UVD3CUBB.mjs → auth-LLXLIILR.mjs} +6 -6
- package/dist/cli/auth-UG4WOYGL.js +40 -0
- package/dist/cli/{billing-BZVTXXLM.mjs → billing-5FVXZYAC.mjs} +8 -8
- package/dist/cli/{billing-BZVYAF6T.js → billing-NFPK7GYP.js} +84 -84
- package/dist/cli/{chunk-ZAAKSJAS.js → chunk-27GJKC5Q.js} +17 -10
- package/dist/cli/{chunk-UHNDVD3P.js → chunk-2H4EY7KH.js} +100 -41
- package/dist/cli/{chunk-WTT6CLED.mjs → chunk-2YR7BIIC.mjs} +5 -2
- package/dist/cli/{chunk-3ZB6IIA7.js → chunk-36AHOWVS.js} +26 -26
- package/dist/cli/{chunk-OSDXE27V.mjs → chunk-4PG4ARL2.mjs} +17 -10
- package/dist/cli/{chunk-LOYISF7S.mjs → chunk-4XQLVUC7.mjs} +738 -512
- package/dist/cli/{chunk-J5PTX66Y.js → chunk-5MLCBXXU.js} +8 -1
- package/dist/cli/chunk-5TUGWDEB.js +313 -0
- package/dist/cli/{chunk-D6FFBSM5.js → chunk-5UUQAGJS.js} +5 -2
- package/dist/cli/{chunk-4CFULMRB.mjs → chunk-5V5Y37BC.mjs} +2 -2
- package/dist/cli/{chunk-PMVFAYL7.mjs → chunk-63ILLN5H.mjs} +2 -2
- package/dist/cli/{chunk-AUMD2VXP.js → chunk-63S7X326.js} +1032 -806
- package/dist/cli/{chunk-4QFT5LGV.mjs → chunk-6PGATQ6L.mjs} +6 -3
- package/dist/cli/{chunk-6BJK4EJ3.mjs → chunk-AARWVK4C.mjs} +2132 -65
- package/dist/cli/{chunk-FERRDNMO.js → chunk-AD47BXN2.js} +5 -5
- package/dist/cli/{chunk-4RNDKFNQ.js → chunk-D37FEBES.js} +2 -2
- package/dist/cli/{chunk-S6R3OX7B.js → chunk-E4CABWXL.js} +25 -2
- package/dist/cli/{chunk-NXGCO4JB.mjs → chunk-E4IXDAZI.mjs} +5 -0
- package/dist/cli/chunk-EQ4Z7RJW.mjs +35 -0
- package/dist/cli/chunk-FR2ILQ4G.mjs +8 -0
- package/dist/cli/{chunk-QUAQX3FQ.js → chunk-FVLNYDI4.js} +128 -376
- package/dist/cli/{chunk-BRJUESQV.js → chunk-FZJAM576.js} +50 -50
- package/dist/cli/{chunk-BZAMOCPA.mjs → chunk-IMZ56EOH.mjs} +3 -3
- package/dist/cli/{chunk-IOHRWLQE.mjs → chunk-IPG42SD2.mjs} +452 -138
- package/dist/cli/chunk-J33TSWO5.js +8 -0
- package/dist/cli/{chunk-XXLXOUUU.mjs → chunk-JNXJZ577.mjs} +1 -1
- package/dist/cli/{chunk-JI2B4RZP.mjs → chunk-KCC3FKIW.mjs} +71 -12
- package/dist/cli/{chunk-6IKARAYD.mjs → chunk-L2VKAASU.mjs} +23 -0
- package/dist/cli/{chunk-PYZZMAJQ.mjs → chunk-LFSHGNT2.mjs} +8 -1
- package/dist/cli/{chunk-2XXXFPTD.js → chunk-LTFL4JRN.js} +426 -721
- package/dist/cli/{chunk-YHPYUZZX.mjs → chunk-MAMVGOSC.mjs} +1 -1
- package/dist/cli/{chunk-URACNNLO.mjs → chunk-MN2OWLFA.mjs} +2 -2
- package/dist/cli/{chunk-Q3PUHXOY.js → chunk-NF4V5DTY.js} +12 -12
- package/dist/cli/{chunk-Q2E4E4FJ.js → chunk-NPBJI7RE.js} +8 -8
- package/dist/cli/chunk-NTVLGHFM.js +501 -0
- package/dist/cli/{chunk-HQXL5526.mjs → chunk-NUX2QHNC.mjs} +1 -1
- package/dist/cli/{chunk-E3PJF6YP.js → chunk-OBB4QXHA.js} +19 -4
- package/dist/cli/{chunk-SEFMGO3Z.js → chunk-OQQOXSYA.js} +2184 -117
- package/dist/cli/chunk-OZ6E3IRZ.js +6084 -0
- package/dist/cli/{chunk-7P5AA3SN.js → chunk-PPDBRJRW.js} +6 -1
- package/dist/cli/{chunk-IWBXJDZA.mjs → chunk-PZSLPBDA.mjs} +2 -2
- package/dist/cli/{chunk-ILHRA7AD.js → chunk-QADCFSGH.js} +7 -7
- package/dist/cli/{chunk-ECVLPS67.js → chunk-QJI5FIOW.js} +170 -49
- package/dist/cli/{chunk-I3DHIXVJ.mjs → chunk-QL22Y56M.mjs} +149 -28
- package/dist/cli/{chunk-SD7MXAJA.mjs → chunk-RFB25DSQ.mjs} +36 -284
- package/dist/cli/chunk-T44IIOT6.mjs +501 -0
- package/dist/cli/chunk-VK2LZ5IP.js +35 -0
- package/dist/cli/chunk-VKKVSFRD.js +62 -0
- package/dist/cli/{chunk-RWCY6YI2.js → chunk-VYKV5XHL.js} +644 -330
- package/dist/cli/{chunk-GSK6NHVM.js → chunk-WU4U6VSB.js} +5 -5
- package/dist/cli/chunk-XHLKJOTN.mjs +313 -0
- package/dist/cli/{chunk-MJELBQBU.mjs → chunk-XIHWSXSV.mjs} +330 -625
- package/dist/cli/chunk-XNZJKRJA.mjs +6084 -0
- package/dist/cli/chunk-ZCALLYF6.mjs +62 -0
- package/dist/cli/{chunk-ZBABPK6Y.js → chunk-ZFZ427HN.js} +11 -8
- package/dist/cli/{chunk-SJVVBWRL.mjs → chunk-ZKYEW55U.mjs} +16 -1
- package/dist/cli/command-docs.js +2 -2
- package/dist/cli/command-docs.mjs +1 -1
- package/dist/cli/{csv-XLGLHJ6P.js → csv-7U3FJYKZ.js} +14 -14
- package/dist/cli/{csv-WPSXG6ZZ.mjs → csv-ZWLDMM4A.mjs} +5 -5
- package/dist/cli/{db-5PTNJG4X.js → db-DNCGV5PC.js} +42 -47
- package/dist/cli/{db-ABS57ABJ.mjs → db-IMYXVMGI.mjs} +15 -20
- package/dist/cli/{describe-PVWQJ2PB.mjs → describe-Q23DWJUK.mjs} +20 -15
- package/dist/cli/{describe-EZS6PQXA.js → describe-S34JUX5W.js} +27 -22
- package/dist/cli/describe-core.d.mts +2 -2
- package/dist/cli/describe-core.d.ts +2 -2
- package/dist/cli/describe-core.js +6 -6
- package/dist/cli/describe-core.mjs +5 -5
- package/dist/cli/{executions-OKJGATQZ.mjs → executions-A73EUGSI.mjs} +8 -8
- package/dist/cli/{executions-FNTAFQ7Y.js → executions-XOMPX2YJ.js} +10 -10
- package/dist/cli/{feedback-W27HDMRR.mjs → feedback-N4GJ2POI.mjs} +11 -7
- package/dist/cli/{feedback-6YBOMSUA.js → feedback-QTCHNJJH.js} +13 -9
- package/dist/cli/{git-YOOUEL6M.mjs → git-4Q3JIQYZ.mjs} +6 -6
- package/dist/cli/git-I6CPBEVG.js +24 -0
- package/dist/cli/index.js +240 -352
- package/dist/cli/index.mjs +163 -275
- package/dist/cli/{legacy-noops-V6OKW7VR.mjs → legacy-noops-3SOVGFF7.mjs} +6 -6
- package/dist/cli/{legacy-noops-2VZ7XT6C.js → legacy-noops-4OSHZM34.js} +9 -9
- package/dist/cli/{monitors-FBWGVIUS.js → monitors-LVE2KZNG.js} +94 -94
- package/dist/cli/{monitors-P2YYWTWT.mjs → monitors-QP2XID2B.mjs} +8 -8
- package/dist/cli/{org-DVMG6H3C.mjs → org-IVRETVQA.mjs} +8 -8
- package/dist/cli/{org-3XUSVX5T.js → org-XFLK5IAP.js} +68 -68
- package/dist/cli/{play-GNC5CQAS.mjs → play-DE7VH6NU.mjs} +533 -98
- package/dist/cli/{play-YG5L4BWQ.js → play-XXTPPP23.js} +1067 -632
- package/dist/cli/{providers-7PSWG2OV.js → providers-DLD3I4JF.js} +11 -11
- package/dist/cli/{providers-JR33SLWL.mjs → providers-GX2NIZQQ.mjs} +8 -8
- package/dist/cli/{quickstart-VUOBQYIQ.mjs → quickstart-72B4L4PK.mjs} +5 -5
- package/dist/cli/{quickstart-FDVZ5BL3.js → quickstart-XNS3HSWC.js} +7 -7
- package/dist/cli/search-6NCH4HB5.js +30 -0
- package/dist/cli/{search-JZYLO33K.mjs → search-SUTRANJI.mjs} +9 -9
- package/dist/cli/{secrets-VS266FVA.js → secrets-6OBLOVEV.js} +17 -17
- package/dist/cli/{secrets-3MCYBT4I.mjs → secrets-FPFXXNUH.mjs} +8 -8
- package/dist/cli/sessions-235532DR.js +16 -0
- package/dist/cli/{sessions-ELLLT23E.mjs → sessions-R25I4QKN.mjs} +6 -6
- package/dist/cli/{settings-PZCKAFII.mjs → settings-AOP6F5PZ.mjs} +12 -12
- package/dist/cli/{settings-7364NMMA.js → settings-VL5FOFPN.js} +79 -79
- package/dist/cli/{setup-PMWYLCT6.js → setup-BSC67YT3.js} +45 -44
- package/dist/cli/{setup-A7GQ4KIA.mjs → setup-ZMPHBHVJ.mjs} +11 -10
- package/dist/cli/skills-3IWLYYRL.js +29 -0
- package/dist/cli/{skills-WS6BIFPQ.mjs → skills-KF65TVFO.mjs} +7 -7
- package/dist/cli/tools-LR66SPYU.js +44 -0
- package/dist/cli/{tools-BR4DOZA2.mjs → tools-SX4XIPM7.mjs} +19 -14
- package/dist/cli/{update-D2B7UNFT.mjs → update-QRMFRAQQ.mjs} +11 -9
- package/dist/cli/update-SP7UEO53.js +31 -0
- package/dist/cli/{workflow-PQXC2R47.mjs → workflow-FOEEEB7G.mjs} +44 -20
- package/dist/cli/{workflow-6ODTCYXU.js → workflow-KOCK2FLW.js} +54 -30
- package/dist/{client-Z9Pye1Wm.d.mts → client-74k4IPh6.d.mts} +137 -54
- package/dist/{client-BcvhDfJJ.d.ts → client-C1IK1f8c.d.ts} +137 -54
- package/dist/{compiler-manifest-Ycx-hoAr.d.mts → compiler-manifest-lzWpbV3w.d.mts} +83 -66
- package/dist/{compiler-manifest-Ycx-hoAr.d.ts → compiler-manifest-lzWpbV3w.d.ts} +83 -66
- package/dist/{index-CZXgiN3E.d.mts → index-C8Cy-YTm.d.ts} +5 -1
- package/dist/{index-NPG5pqxQ.d.ts → index-CtNK-0nI.d.mts} +5 -1
- package/dist/index.d.mts +47 -9
- package/dist/index.d.ts +47 -9
- package/dist/index.js +17 -14
- package/dist/index.mjs +13 -10
- package/dist/install-integrity.json +120 -104
- package/dist/plays/bundle-play-file.d.mts +3 -3
- package/dist/plays/bundle-play-file.d.ts +3 -3
- package/dist/plays/bundle-play-file.mjs +5 -4
- package/dist/plays/csv-data-input.js +3 -3
- package/dist/plays/csv-data-input.mjs +2 -2
- package/dist/plays/play-description.d.mts +2 -2
- package/dist/plays/play-description.d.ts +2 -2
- package/dist/plays/run-request.d.mts +2 -2
- package/dist/plays/run-request.d.ts +2 -2
- package/dist/plays/run-request.js +11 -3
- package/dist/plays/run-request.mjs +10 -2
- package/dist/release.d.mts +15 -6
- package/dist/release.d.ts +15 -6
- package/dist/release.js +2 -2
- package/dist/release.mjs +1 -1
- package/package.json +2 -2
- package/dist/cli/auth-3GB2K636.js +0 -40
- package/dist/cli/chunk-67RWR34T.mjs +0 -155
- package/dist/cli/chunk-CLJGSOVM.mjs +0 -1716
- package/dist/cli/chunk-HQY2SG3K.js +0 -83
- package/dist/cli/chunk-OSFWFV72.js +0 -155
- package/dist/cli/chunk-Q3LFI3VH.js +0 -392
- package/dist/cli/chunk-WPAB4DCU.mjs +0 -83
- package/dist/cli/chunk-YMOFWHGO.mjs +0 -392
- package/dist/cli/chunk-Z4VNJOF7.js +0 -1716
- package/dist/cli/git-YKUXXJOR.js +0 -24
- package/dist/cli/search-PPPYC5OZ.js +0 -30
- package/dist/cli/sessions-TEHEWW7O.js +0 -16
- package/dist/cli/skills-SYS7VRRK.js +0 -29
- package/dist/cli/tools-KK4BKVQR.js +0 -39
- package/dist/cli/update-2IV5JTX2.js +0 -29
|
@@ -481,6 +481,8 @@ export interface BatchRequest {
|
|
|
481
481
|
}
|
|
482
482
|
|
|
483
483
|
export interface MapStartResult {
|
|
484
|
+
/** Opt-in authoritative completed cells, separate from merged input rows. */
|
|
485
|
+
previousCells?: import('./dataset-row-input').DatasetPreviousCells[];
|
|
484
486
|
/** Rows that need processing for this run. Previous values may be included for context. */
|
|
485
487
|
pendingRows: Record<string, unknown>[];
|
|
486
488
|
/** Rows already terminal for this run and safe to count as completed. */
|
|
@@ -825,6 +827,8 @@ export interface ContextOptions {
|
|
|
825
827
|
authoringContractEdition?: PlayAuthoringContractEdition;
|
|
826
828
|
/** Direct/local callers may opt into the new terminal Slack HITL outcome. */
|
|
827
829
|
slackHitlTimeoutOutcome?: 'park' | 'error';
|
|
830
|
+
/** Artifact-pinned dataset input policy; missing retains legacy hydration. */
|
|
831
|
+
datasetRowInput?: 'current_run';
|
|
828
832
|
/** Error shape pinned by the immutable play artifact; missing preserves legacy schema 0. */
|
|
829
833
|
toolErrorSchemaVersion?: ToolExecutionErrorSchemaVersion;
|
|
830
834
|
/** Execute-result contract pinned by the immutable Play artifact. */
|
|
@@ -967,6 +971,8 @@ export interface ContextOptions {
|
|
|
967
971
|
executorToken?: string;
|
|
968
972
|
staticPipeline?: PlayStaticPipeline | null;
|
|
969
973
|
forceRefresh?: boolean;
|
|
974
|
+
includePreviousCells?: boolean;
|
|
975
|
+
previousCellsBudgetBytes?: number;
|
|
970
976
|
inputOffset?: number;
|
|
971
977
|
mode?: RuntimeDatasetRunOptions['mode'];
|
|
972
978
|
columnTypes?: PlayDatasetColumnTypes;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { copyPlayDatasetSourceRowIdentity } from '../plays/dataset';
|
|
2
|
+
import type { PreviousCell } from '../plays/cell-staleness';
|
|
3
|
+
import { cloneCsvAliasedRow } from './csv-rename';
|
|
4
|
+
import {
|
|
5
|
+
runtimeJsonByteLength,
|
|
6
|
+
type RuntimeMemoryLedger,
|
|
7
|
+
type RuntimeMemoryLedgerHandle,
|
|
8
|
+
} from './memory-ledger';
|
|
9
|
+
|
|
10
|
+
export type DatasetPreviousCells = {
|
|
11
|
+
key: string;
|
|
12
|
+
cells: Record<string, PreviousCell>;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// Match the ordinary runtime API decoded-response limit, including both the
|
|
16
|
+
// legacy projection and opted-in history. Never truncate a historical cell.
|
|
17
|
+
const MAX_ADMISSION_BYTES = 16 * 1024 * 1024;
|
|
18
|
+
|
|
19
|
+
export function assertDatasetAdmissionHistory(
|
|
20
|
+
result: { previousCells?: DatasetPreviousCells[] },
|
|
21
|
+
budgetBytes = MAX_ADMISSION_BYTES,
|
|
22
|
+
): Map<string, Record<string, PreviousCell>> {
|
|
23
|
+
if (!Array.isArray(result.previousCells)) {
|
|
24
|
+
throw new Error(
|
|
25
|
+
'Dataset admission did not return requested previous cells. Deploy dataset row input readers before activating new artifacts.',
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
const limit = Math.min(MAX_ADMISSION_BYTES, budgetBytes);
|
|
29
|
+
if (!Number.isFinite(limit) || limit < 1) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
'Dataset admission history requires a positive byte budget.',
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
if (runtimeJsonByteLength(result) > limit) {
|
|
35
|
+
throw new Error(
|
|
36
|
+
`Dataset admission with previous cells exceeds the ${limit} byte budget.`,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
return new Map(result.previousCells.map(({ key, cells }) => [key, cells]));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function persistedFieldsAbsentFromInputRow(
|
|
43
|
+
inputRow: Record<string, unknown>,
|
|
44
|
+
persisted: Record<string, unknown>,
|
|
45
|
+
): Record<string, unknown> {
|
|
46
|
+
return Object.fromEntries(
|
|
47
|
+
Object.entries(persisted).filter(
|
|
48
|
+
([key]) => !Object.prototype.hasOwnProperty.call(inputRow, key),
|
|
49
|
+
),
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
type RowHistory = {
|
|
54
|
+
cells: Record<string, PreviousCell>;
|
|
55
|
+
bytes: number;
|
|
56
|
+
memory?: RuntimeMemoryLedgerHandle;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/** Private execution context, copied at the runtime's row-cloning seam. */
|
|
60
|
+
export class DatasetRowInputView {
|
|
61
|
+
private readonly history = new WeakMap<object, RowHistory>();
|
|
62
|
+
|
|
63
|
+
seed(
|
|
64
|
+
input: Record<string, unknown>,
|
|
65
|
+
persisted: Record<string, unknown> | undefined,
|
|
66
|
+
policy: 'legacy' | 'current_run',
|
|
67
|
+
cells: Record<string, PreviousCell> = {},
|
|
68
|
+
): Record<string, unknown> {
|
|
69
|
+
const extra = persistedFieldsAbsentFromInputRow(input, persisted ?? {});
|
|
70
|
+
if (policy === 'legacy' && !persisted) return input;
|
|
71
|
+
const row = cloneCsvAliasedRow(
|
|
72
|
+
input,
|
|
73
|
+
policy === 'legacy'
|
|
74
|
+
? extra
|
|
75
|
+
: Object.fromEntries(
|
|
76
|
+
Object.entries(extra).filter(([key]) =>
|
|
77
|
+
key.startsWith('__deepline'),
|
|
78
|
+
),
|
|
79
|
+
),
|
|
80
|
+
);
|
|
81
|
+
if (policy === 'current_run') {
|
|
82
|
+
copyPlayDatasetSourceRowIdentity(input, row);
|
|
83
|
+
this.history.set(row, { cells, bytes: runtimeJsonByteLength(cells) });
|
|
84
|
+
}
|
|
85
|
+
return row;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
copy<T extends object>(source: object, target: T): T {
|
|
89
|
+
const history = this.history.get(source);
|
|
90
|
+
if (history) this.history.set(target, history);
|
|
91
|
+
return target;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
previous(row: object, field: string): PreviousCell | undefined {
|
|
95
|
+
const cells = this.history.get(row)?.cells;
|
|
96
|
+
return cells && Object.prototype.hasOwnProperty.call(cells, field)
|
|
97
|
+
? cells[field]
|
|
98
|
+
: undefined;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
memoryValue(row: Record<string, unknown>): unknown {
|
|
102
|
+
const history = this.history.get(row);
|
|
103
|
+
return history ? { row, previousCells: history.cells } : row;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
retain(row: object, ledger: RuntimeMemoryLedger): void {
|
|
107
|
+
const history = this.history.get(row);
|
|
108
|
+
if (history && !history.memory && history.bytes > 0) {
|
|
109
|
+
history.memory = ledger.register({
|
|
110
|
+
category: 'hydrationReadBack',
|
|
111
|
+
bytes: history.bytes,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
release(row: object): void {
|
|
117
|
+
const history = this.history.get(row);
|
|
118
|
+
if (!history) return;
|
|
119
|
+
history.memory?.release();
|
|
120
|
+
history.memory = undefined;
|
|
121
|
+
history.cells = {};
|
|
122
|
+
history.bytes = 0;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import { buildDurableToolReceiptPrefix } from './durable-tool-identity';
|
|
2
|
+
export {
|
|
3
|
+
buildDurableToolCallAuthScopeDigest,
|
|
4
|
+
buildDurableToolReceiptPrefix,
|
|
5
|
+
buildDurableToolPayloadProviderIdempotencyKey,
|
|
6
|
+
} from './durable-tool-identity';
|
|
1
7
|
import {
|
|
2
8
|
normalizeTableNamespace,
|
|
3
9
|
sha256Hex,
|
|
@@ -200,32 +206,6 @@ export function buildDurableRunPlayInvocationScope(input: {
|
|
|
200
206
|
);
|
|
201
207
|
}
|
|
202
208
|
|
|
203
|
-
export function buildDurableToolCallAuthScopeDigest(input: {
|
|
204
|
-
orgId?: string | null;
|
|
205
|
-
toolId: string;
|
|
206
|
-
executionAuthScopeDigest?: string | null;
|
|
207
|
-
}): string {
|
|
208
|
-
return sha256Hex(
|
|
209
|
-
stableStringify({
|
|
210
|
-
orgId: input.orgId?.trim() || 'org',
|
|
211
|
-
toolId: input.toolId.trim(),
|
|
212
|
-
executionAuthScopeDigest: input.executionAuthScopeDigest?.trim() || null,
|
|
213
|
-
}),
|
|
214
|
-
);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
export function buildDurableToolReceiptPrefix(input: {
|
|
218
|
-
orgId?: string | null;
|
|
219
|
-
toolId: string;
|
|
220
|
-
}): string {
|
|
221
|
-
const orgId = input.orgId?.trim() || 'org';
|
|
222
|
-
const toolId = input.toolId.trim();
|
|
223
|
-
if (!toolId) {
|
|
224
|
-
throw new Error('Durable tool receipt prefix requires a non-empty toolId.');
|
|
225
|
-
}
|
|
226
|
-
return `ctx:${orgId}:call:tool:${normalizeTableNamespace(toolId)}:`;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
209
|
/** Partition a completed-result receipt without changing its accepted wire
|
|
230
210
|
* shape. The semantic key still includes payload/auth/action/presentation. */
|
|
231
211
|
export function scopeToolReceiptToInvocation(input: {
|
|
@@ -302,39 +282,3 @@ function commonDurableToolReceiptPrefix(
|
|
|
302
282
|
}
|
|
303
283
|
return commonPrefix ?? '';
|
|
304
284
|
}
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* Provider-native batch caching is keyed by the exact compiled provider
|
|
308
|
-
* payload. Result-cache identities coordinate local publication; they never
|
|
309
|
-
* stand in for a provider operation identity.
|
|
310
|
-
*
|
|
311
|
-
* An explicit force refresh is deliberately a separate namespace: it asks for
|
|
312
|
-
* a fresh provider operation even when the payload itself is unchanged.
|
|
313
|
-
*/
|
|
314
|
-
export function buildDurableToolPayloadProviderIdempotencyKey(input: {
|
|
315
|
-
orgId?: string | null;
|
|
316
|
-
toolId: string;
|
|
317
|
-
executionAuthScopeDigest?: string | null;
|
|
318
|
-
providerActionVersion?: string | null;
|
|
319
|
-
payload: Record<string, unknown>;
|
|
320
|
-
forceRefreshIdentities?: readonly string[];
|
|
321
|
-
}): string {
|
|
322
|
-
const toolId = input.toolId.trim();
|
|
323
|
-
if (!toolId) {
|
|
324
|
-
throw new Error(
|
|
325
|
-
'Provider payload idempotency key needs a non-empty toolId.',
|
|
326
|
-
);
|
|
327
|
-
}
|
|
328
|
-
const forceRefreshIdentities = input.forceRefreshIdentities
|
|
329
|
-
?.map((identity) => identity.trim())
|
|
330
|
-
.filter(Boolean);
|
|
331
|
-
const orgId = input.orgId?.trim() || 'org';
|
|
332
|
-
return `ctx:${orgId}:operation:tool:${normalizeTableNamespace(toolId)}:payload-v1:${sha256Hex(
|
|
333
|
-
stableStringify({
|
|
334
|
-
executionAuthScopeDigest: input.executionAuthScopeDigest?.trim() || null,
|
|
335
|
-
providerActionVersion: input.providerActionVersion?.trim() || null,
|
|
336
|
-
payload: input.payload,
|
|
337
|
-
...(forceRefreshIdentities?.length ? { forceRefreshIdentities } : {}),
|
|
338
|
-
}),
|
|
339
|
-
)}`;
|
|
340
|
-
}
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
isToolExecuteResult,
|
|
5
5
|
serializeToolExecuteResult,
|
|
6
6
|
} from './tool-result';
|
|
7
|
+
export { executeWithFreshnessReceipt } from './freshness-receipt-execution';
|
|
7
8
|
import { assertNoSecretTaint } from './secret-capability';
|
|
8
9
|
import type { RuntimeStepReceipt } from './ctx-types';
|
|
9
10
|
import {
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import {
|
|
2
|
+
normalizeTableNamespace,
|
|
3
|
+
sha256Hex,
|
|
4
|
+
stableStringify,
|
|
5
|
+
} from '../plays/row-identity';
|
|
6
|
+
|
|
7
|
+
export function buildDurableToolCallAuthScopeDigest(input: {
|
|
8
|
+
orgId?: string | null;
|
|
9
|
+
toolId: string;
|
|
10
|
+
executionAuthScopeDigest?: string | null;
|
|
11
|
+
}): string {
|
|
12
|
+
return sha256Hex(
|
|
13
|
+
stableStringify({
|
|
14
|
+
orgId: input.orgId?.trim() || 'org',
|
|
15
|
+
toolId: input.toolId.trim(),
|
|
16
|
+
executionAuthScopeDigest: input.executionAuthScopeDigest?.trim() || null,
|
|
17
|
+
}),
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function buildDurableToolReceiptPrefix(input: {
|
|
22
|
+
orgId?: string | null;
|
|
23
|
+
toolId: string;
|
|
24
|
+
}): string {
|
|
25
|
+
const orgId = input.orgId?.trim() || 'org';
|
|
26
|
+
const toolId = input.toolId.trim();
|
|
27
|
+
if (!toolId) {
|
|
28
|
+
throw new Error('Durable tool receipt prefix requires a non-empty toolId.');
|
|
29
|
+
}
|
|
30
|
+
return `ctx:${orgId}:call:tool:${normalizeTableNamespace(toolId)}:`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Provider-native batch caching is keyed by the exact compiled provider
|
|
35
|
+
* payload. Result-cache identities coordinate local publication; they never
|
|
36
|
+
* stand in for a provider operation identity.
|
|
37
|
+
*
|
|
38
|
+
* An explicit force refresh is deliberately a separate namespace: it asks for
|
|
39
|
+
* a fresh provider operation even when the payload itself is unchanged.
|
|
40
|
+
*/
|
|
41
|
+
export function buildDurableToolPayloadProviderIdempotencyKey(input: {
|
|
42
|
+
orgId?: string | null;
|
|
43
|
+
toolId: string;
|
|
44
|
+
executionAuthScopeDigest?: string | null;
|
|
45
|
+
providerActionVersion?: string | null;
|
|
46
|
+
payload: Record<string, unknown>;
|
|
47
|
+
forceRefreshIdentities?: readonly string[];
|
|
48
|
+
}): string {
|
|
49
|
+
const toolId = input.toolId.trim();
|
|
50
|
+
if (!toolId) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
'Provider payload idempotency key needs a non-empty toolId.',
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
const forceRefreshIdentities = input.forceRefreshIdentities
|
|
56
|
+
?.map((identity) => identity.trim())
|
|
57
|
+
.filter(Boolean);
|
|
58
|
+
const orgId = input.orgId?.trim() || 'org';
|
|
59
|
+
return `ctx:${orgId}:operation:tool:${normalizeTableNamespace(toolId)}:payload-v1:${sha256Hex(
|
|
60
|
+
stableStringify({
|
|
61
|
+
executionAuthScopeDigest: input.executionAuthScopeDigest?.trim() || null,
|
|
62
|
+
providerActionVersion: input.providerActionVersion?.trim() || null,
|
|
63
|
+
payload: input.payload,
|
|
64
|
+
...(forceRefreshIdentities?.length ? { forceRefreshIdentities } : {}),
|
|
65
|
+
}),
|
|
66
|
+
)}`;
|
|
67
|
+
}
|
|
@@ -10,21 +10,44 @@ export const EXECUTE_SERVER_TIMING_STAGES = [
|
|
|
10
10
|
'auth',
|
|
11
11
|
'rate_limit',
|
|
12
12
|
'catalog',
|
|
13
|
+
// Local preparation accumulates compilation/hooks/pricing inside catalog
|
|
14
|
+
// and executor loading before the final provider permit. Do not add it to
|
|
15
|
+
// catalog or total. Credential selection excludes charge admission.
|
|
16
|
+
'credential_plan',
|
|
17
|
+
'provider_prepare',
|
|
13
18
|
'charge_open',
|
|
14
19
|
// Charge admission substages. `charge_open` keeps its original meaning — the
|
|
15
20
|
// TOTAL of all charge-admission work — so an existing reader is unchanged and
|
|
16
|
-
// these four explain work inside it.
|
|
17
|
-
//
|
|
21
|
+
// these four explain work inside it. The authorization action adapter splits
|
|
22
|
+
// its wall into snapshot, remaining action time and application retry gaps.
|
|
18
23
|
// Absent stages are unobserved, not confident zero durations.
|
|
19
24
|
// - `charge_eligibility` canonical wallet and cap authorization snapshot
|
|
20
25
|
// - `charge_cap_preflight` legacy standalone cap work (zero in current path)
|
|
21
|
-
// - `charge_open_mutation`
|
|
26
|
+
// - `charge_open_mutation` remaining action wall, including transport and
|
|
27
|
+
// failed attempts; legacy name, not mutation CPU
|
|
22
28
|
// - `charge_retry_wait` elapsed gaps before application RPC retries;
|
|
23
29
|
// native Convex logs attribute internal OCC retries
|
|
24
30
|
'charge_eligibility',
|
|
25
31
|
'charge_cap_preflight',
|
|
26
32
|
'charge_open_mutation',
|
|
27
33
|
'charge_retry_wait',
|
|
34
|
+
// Billing completion slices explain the full stage, including transport.
|
|
35
|
+
// Handoff headers/body are nested within billing_handoff, not additive.
|
|
36
|
+
'billing_settle',
|
|
37
|
+
'billing_price',
|
|
38
|
+
'billing_precision',
|
|
39
|
+
'billing_caps',
|
|
40
|
+
'billing_catalog',
|
|
41
|
+
'billing_witness',
|
|
42
|
+
'billing_handoff',
|
|
43
|
+
'billing_handoff_rpc',
|
|
44
|
+
'billing_handoff_headers',
|
|
45
|
+
'billing_handoff_after_headers',
|
|
46
|
+
// Process-wide activity over the RPC interval, including concurrent work.
|
|
47
|
+
// These overlap the wall clocks above; they are not request-attributed CPU.
|
|
48
|
+
'billing_handoff_process_cpu',
|
|
49
|
+
'billing_handoff_event_loop_active',
|
|
50
|
+
'billing_handoff_event_loop_idle',
|
|
28
51
|
'fixture_load',
|
|
29
52
|
'execute',
|
|
30
53
|
'identity',
|
|
@@ -78,11 +101,44 @@ export const EXECUTE_SERVER_TIMING_STAGES = [
|
|
|
78
101
|
'upstream_body',
|
|
79
102
|
] as const;
|
|
80
103
|
|
|
104
|
+
// The public recovery handler surrounds the core: its total includes durable
|
|
105
|
+
// response storage and receipt acknowledgement. Keep the core's total intact.
|
|
106
|
+
export const PUBLIC_EXECUTE_SERVER_TIMING_STAGES = [
|
|
107
|
+
// Route total includes lazy execution-module loading. The handler's
|
|
108
|
+
// public_total keeps its existing meaning so older readers remain valid.
|
|
109
|
+
'public_load',
|
|
110
|
+
'public_route',
|
|
111
|
+
// Core and recovery initialization overlap authentication. Their wall is
|
|
112
|
+
// included in public_total; these stages are not additive.
|
|
113
|
+
'public_core_load',
|
|
114
|
+
'public_recovery_load',
|
|
115
|
+
'public_auth',
|
|
116
|
+
'public_claim',
|
|
117
|
+
'public_claim_headers',
|
|
118
|
+
'public_claim_after_headers',
|
|
119
|
+
'public_core',
|
|
120
|
+
'public_prepare',
|
|
121
|
+
'public_r2',
|
|
122
|
+
'public_complete',
|
|
123
|
+
'public_complete_headers',
|
|
124
|
+
'public_complete_after_headers',
|
|
125
|
+
'public_total',
|
|
126
|
+
] as const;
|
|
127
|
+
|
|
128
|
+
export type PublicExecuteServerTimingStage =
|
|
129
|
+
(typeof PUBLIC_EXECUTE_SERVER_TIMING_STAGES)[number];
|
|
130
|
+
|
|
131
|
+
const ALL_EXECUTE_SERVER_TIMING_STAGES = /* @__PURE__ */ (() =>
|
|
132
|
+
[
|
|
133
|
+
...EXECUTE_SERVER_TIMING_STAGES,
|
|
134
|
+
...PUBLIC_EXECUTE_SERVER_TIMING_STAGES,
|
|
135
|
+
] as const)();
|
|
136
|
+
|
|
81
137
|
export type ExecuteServerTimingStage =
|
|
82
138
|
(typeof EXECUTE_SERVER_TIMING_STAGES)[number];
|
|
83
139
|
|
|
84
140
|
export type ExecuteServerTiming = Record<
|
|
85
|
-
ExecuteServerTimingStage,
|
|
141
|
+
ExecuteServerTimingStage | PublicExecuteServerTimingStage,
|
|
86
142
|
number | null
|
|
87
143
|
>;
|
|
88
144
|
|
|
@@ -118,12 +174,14 @@ export function parseExecuteServerTiming(
|
|
|
118
174
|
}
|
|
119
175
|
}
|
|
120
176
|
const timing = Object.fromEntries(
|
|
121
|
-
|
|
177
|
+
ALL_EXECUTE_SERVER_TIMING_STAGES.map((stage) => [
|
|
122
178
|
stage,
|
|
123
179
|
durations.get(stage) ?? null,
|
|
124
180
|
]),
|
|
125
181
|
) as ExecuteServerTiming;
|
|
126
|
-
return
|
|
182
|
+
return ALL_EXECUTE_SERVER_TIMING_STAGES.some(
|
|
183
|
+
(stage) => timing[stage] !== null,
|
|
184
|
+
)
|
|
127
185
|
? timing
|
|
128
186
|
: null;
|
|
129
187
|
}
|
|
@@ -17,11 +17,7 @@ import {
|
|
|
17
17
|
type CompletedCall = {
|
|
18
18
|
completedAt: number;
|
|
19
19
|
value?: unknown;
|
|
20
|
-
/**
|
|
21
|
-
* Large tool results already live in their canonical result receipt. Keep a
|
|
22
|
-
* receipt-key indirection here instead of copying the full result into each
|
|
23
|
-
* operation and reusable freshness receipt.
|
|
24
|
-
*/
|
|
20
|
+
/** Reuse a result already stored by its canonical receipt without copying it. */
|
|
25
21
|
valueReceiptKey?: string;
|
|
26
22
|
undefinedValue?: true;
|
|
27
23
|
};
|
|
@@ -15,7 +15,7 @@ export const MAX_LEDGER_RESULT_PAYLOAD_BYTES = LEDGER_TERMINAL_RESULT_MAX_BYTES;
|
|
|
15
15
|
export const MAX_LEDGER_LOG_LINES_PER_EVENT = 500;
|
|
16
16
|
export const MAX_LEDGER_LOG_LINE_LENGTH = 2_000;
|
|
17
17
|
|
|
18
|
-
const ledgerIngressRedactor = createSecretRedactionContext();
|
|
18
|
+
const ledgerIngressRedactor = /* @__PURE__ */ createSecretRedactionContext();
|
|
19
19
|
|
|
20
20
|
export function redactLedgerString(value: unknown): string | null {
|
|
21
21
|
if (typeof value !== 'string' || !value.trim()) return null;
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
*/
|
|
25
25
|
export type PlayArtifactRuntimeContract = Readonly<{
|
|
26
26
|
semantics: PlayRuntimeSemantics;
|
|
27
|
+
datasetRowInput: 'legacy' | 'current_run';
|
|
27
28
|
/** Additive artifact fact; missing persisted fields resolve to `park`. */
|
|
28
29
|
slackHitlTimeoutOutcome: 'park' | 'error';
|
|
29
30
|
toolErrorSchemaVersion: ToolExecutionErrorSchemaVersion;
|
|
@@ -33,6 +34,7 @@ export type PlayArtifactRuntimeContract = Readonly<{
|
|
|
33
34
|
|
|
34
35
|
export type PlayArtifactRuntimeContractInput = {
|
|
35
36
|
authoringContractEdition?: PlayAuthoringContractEdition | null;
|
|
37
|
+
datasetRowInput?: 'current_run';
|
|
36
38
|
slackHitlTimeoutOutcome?: 'park' | 'error' | null;
|
|
37
39
|
toolResponseContract?: ToolResponseContract | null;
|
|
38
40
|
toolResponseReceiptRevision?: string | null;
|
|
@@ -50,6 +52,7 @@ export function resolvePlayArtifactRuntimeContract(
|
|
|
50
52
|
const toolResponseReceiptRevision =
|
|
51
53
|
input.toolResponseReceiptRevision ?? undefined;
|
|
52
54
|
return Object.freeze({
|
|
55
|
+
datasetRowInput: input.datasetRowInput ?? 'legacy',
|
|
53
56
|
semantics: resolvePlayRuntimeSemantics(
|
|
54
57
|
input.authoringContractEdition ?? PLAY_AUTHORING_CONTRACT_EDITION,
|
|
55
58
|
),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { SafeFetchImplementation } from '../security/safe-fetch';
|
|
2
2
|
import type { RuntimeResourceGovernor } from './resource-governor';
|
|
3
3
|
import { CTX_FETCH_EGRESS_TOOL_ID } from './builtin-pacing';
|
|
4
|
+
import { CtxFetchAmbiguousWriteError } from '../plays/ambiguous-write-error';
|
|
4
5
|
import {
|
|
5
6
|
positiveTimeoutMs,
|
|
6
7
|
RUNTIME_RELIABILITY_POLICY,
|
|
@@ -216,6 +217,7 @@ export async function sendPlayHttpRequest(input: {
|
|
|
216
217
|
timeouts?: { headersMs?: number; bodyMs?: number; totalMs?: number };
|
|
217
218
|
fetchImpl?: SafeFetchImplementation;
|
|
218
219
|
log: (message: string) => void;
|
|
220
|
+
reportAmbiguousWrite?: boolean;
|
|
219
221
|
}): Promise<{ response: Response; bodyText: string }> {
|
|
220
222
|
const { url, init } = input;
|
|
221
223
|
const method = String(init.method ?? 'GET').toUpperCase();
|
|
@@ -244,6 +246,7 @@ export async function sendPlayHttpRequest(input: {
|
|
|
244
246
|
const { safePublicFetch } = await loadSafeFetch();
|
|
245
247
|
let transportAttempt = 1;
|
|
246
248
|
let rateLimitAttempt = 0;
|
|
249
|
+
let writeDispatched = false;
|
|
247
250
|
while (true) {
|
|
248
251
|
const attemptController = new AbortController();
|
|
249
252
|
let permit: Awaited<
|
|
@@ -309,6 +312,8 @@ export async function sendPlayHttpRequest(input: {
|
|
|
309
312
|
phase: 'headers',
|
|
310
313
|
run: () => {
|
|
311
314
|
dispatched = true;
|
|
315
|
+
if (!['GET', 'HEAD', 'OPTIONS'].includes(method))
|
|
316
|
+
writeDispatched = true;
|
|
312
317
|
return (input.fetchImpl ?? globalThis.fetch)(
|
|
313
318
|
physicalUrl,
|
|
314
319
|
physicalInit,
|
|
@@ -333,6 +338,11 @@ export async function sendPlayHttpRequest(input: {
|
|
|
333
338
|
void response?.body?.cancel(error).catch(() => undefined);
|
|
334
339
|
response = null;
|
|
335
340
|
bodyText = null;
|
|
341
|
+
if (input.reportAmbiguousWrite && writeDispatched) {
|
|
342
|
+
throw new CtxFetchAmbiguousWriteError(method, new URL(url).origin, {
|
|
343
|
+
cause: error,
|
|
344
|
+
});
|
|
345
|
+
}
|
|
336
346
|
if (error instanceof CtxFetchTimeoutError) throw error;
|
|
337
347
|
if (init.signal?.aborted) {
|
|
338
348
|
throw init.signal.reason ?? error;
|
|
@@ -120,6 +120,9 @@ export function isQueryResultDatasetReadRequest(
|
|
|
120
120
|
input: Record<string, unknown>,
|
|
121
121
|
): boolean {
|
|
122
122
|
if (!isQueryResultDatasetTool(toolId)) return false;
|
|
123
|
+
// Absence keeps the historical live dataset behavior.
|
|
124
|
+
if (isCustomerDbDatasetTool(toolId) && input.result_mode === 'rows')
|
|
125
|
+
return false;
|
|
123
126
|
if (
|
|
124
127
|
(isSnowflakeQueryDatasetTool(toolId) ||
|
|
125
128
|
isDatabricksQueryDatasetTool(toolId)) &&
|
|
@@ -163,11 +163,14 @@ export const EGRESS_PROBE_BUDGET_MS = 3_000;
|
|
|
163
163
|
const EGRESS_PROBE_REQUESTS_PER_TARGET = 6;
|
|
164
164
|
|
|
165
165
|
export async function collectStartupEgressProbeLines(input: {
|
|
166
|
+
/** Network benchmarks are opt-in and must not delay ordinary Plays. */
|
|
167
|
+
enabled?: boolean;
|
|
166
168
|
receiptGatewayBaseUrl: string | null;
|
|
167
169
|
executionRelayBaseUrl: string | null;
|
|
168
170
|
/** Bearer credential for the gateway's authenticated bandwidth sink. */
|
|
169
171
|
executorToken?: string | null;
|
|
170
172
|
}): Promise<string[]> {
|
|
173
|
+
if (input.enabled !== true) return [];
|
|
171
174
|
const gateway = input.receiptGatewayBaseUrl?.trim().replace(/\/$/, '') || '';
|
|
172
175
|
const relay = input.executionRelayBaseUrl?.trim().replace(/\/$/, '') || '';
|
|
173
176
|
const targets: Array<{ target: EgressProbeTarget; baseUrl: string }> = [];
|
|
@@ -2378,6 +2378,7 @@ async function run(
|
|
|
2378
2378
|
const artifactRuntimeContract = resolvePlayArtifactRuntimeContract({
|
|
2379
2379
|
authoringContractEdition: artifactCompatibility.authoringContractEdition,
|
|
2380
2380
|
slackHitlTimeoutOutcome: artifactCompatibility.slackHitlTimeoutOutcome,
|
|
2381
|
+
datasetRowInput: artifactCompatibility.datasetRowInput,
|
|
2381
2382
|
toolResponseContract: config.context.toolResponseContract,
|
|
2382
2383
|
toolResponseReceiptRevision: config.context.toolResponseReceiptRevision,
|
|
2383
2384
|
});
|
|
@@ -2819,6 +2820,8 @@ async function run(
|
|
|
2819
2820
|
rows: items,
|
|
2820
2821
|
stableWriteIntent: true,
|
|
2821
2822
|
pendingRerunAdmission: true,
|
|
2823
|
+
includePreviousCells: mapContext.includePreviousCells,
|
|
2824
|
+
previousCellsBudgetBytes: mapContext.previousCellsBudgetBytes,
|
|
2822
2825
|
inputOffset: mapContext.inputOffset,
|
|
2823
2826
|
mode: mapContext.mode,
|
|
2824
2827
|
runId,
|
|
@@ -3382,8 +3385,9 @@ async function run(
|
|
|
3382
3385
|
options,
|
|
3383
3386
|
);
|
|
3384
3387
|
for (const line of await collectStartupEgressProbeLines({
|
|
3388
|
+
enabled: process.env.DEEPLINE_RUNTIME_RECEIPT_TRACE === '1',
|
|
3385
3389
|
// A local/direct executor can use baseUrl without a receipt gateway.
|
|
3386
|
-
// Probe only the explicit data-plane hop.
|
|
3390
|
+
// Probe only the explicit data-plane hop in explicit diagnostic mode.
|
|
3387
3391
|
receiptGatewayBaseUrl: config.context.receiptGatewayBaseUrl ?? null,
|
|
3388
3392
|
executionRelayBaseUrl: config.context.executionGatewayBaseUrl ?? null,
|
|
3389
3393
|
executorToken: config.context.executorToken ?? null,
|
|
@@ -4236,23 +4240,26 @@ export async function waitForRunnerExecutionAcknowledgement(
|
|
|
4236
4240
|
timeoutMs = RUNNER_EXECUTION_ACK_TIMEOUT_MS,
|
|
4237
4241
|
): Promise<void> {
|
|
4238
4242
|
if (!heartbeat) return;
|
|
4239
|
-
|
|
4240
|
-
let
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4243
|
+
heartbeat.requestHeartbeat();
|
|
4244
|
+
let timeout: ReturnType<typeof setTimeout> | undefined;
|
|
4245
|
+
try {
|
|
4246
|
+
await Promise.race([
|
|
4247
|
+
heartbeat.executionAcknowledged,
|
|
4248
|
+
new Promise<never>((_resolve, reject) => {
|
|
4249
|
+
timeout = setTimeout(
|
|
4250
|
+
() =>
|
|
4251
|
+
reject(
|
|
4252
|
+
new Error(
|
|
4253
|
+
`RUNTIME_SANDBOX_START_FAILED: scheduler did not acknowledge the detached runner park within ${Math.max(1, timeoutMs)}ms. Customer play code was not started.`,
|
|
4254
|
+
),
|
|
4255
|
+
),
|
|
4256
|
+
Math.max(1, timeoutMs),
|
|
4257
|
+
);
|
|
4258
|
+
}),
|
|
4249
4259
|
]);
|
|
4250
|
-
|
|
4251
|
-
|
|
4260
|
+
} finally {
|
|
4261
|
+
if (timeout) clearTimeout(timeout);
|
|
4252
4262
|
}
|
|
4253
|
-
throw new Error(
|
|
4254
|
-
`RUNTIME_SANDBOX_START_FAILED: scheduler did not acknowledge the detached runner park within ${Math.max(1, timeoutMs)}ms. Customer play code was not started.`,
|
|
4255
|
-
);
|
|
4256
4263
|
}
|
|
4257
4264
|
|
|
4258
4265
|
/**
|
|
@@ -4384,6 +4391,8 @@ async function pushRunnerTerminalIfConfigured(
|
|
|
4384
4391
|
executorToken: context.executorToken,
|
|
4385
4392
|
runId: context.runId,
|
|
4386
4393
|
result,
|
|
4394
|
+
runtimeCompletedPath:
|
|
4395
|
+
process.env.DEEPLINE_PLAY_RUNNER_RUNTIME_COMPLETED_PATH,
|
|
4387
4396
|
...options,
|
|
4388
4397
|
});
|
|
4389
4398
|
}
|
|
@@ -4433,6 +4442,7 @@ function startRunnerPushHeartbeatFromConfig(
|
|
|
4433
4442
|
executorToken,
|
|
4434
4443
|
runId: push.runId,
|
|
4435
4444
|
leaseSeconds: push.leaseSeconds,
|
|
4445
|
+
waitForSchedulerPark: true,
|
|
4436
4446
|
onSelfTerminate: (stop) => {
|
|
4437
4447
|
onSelfTerminate?.(stop);
|
|
4438
4448
|
void terminateRunnerForHeartbeatStop(stop);
|