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.
Files changed (217) hide show
  1. package/dist/bundling-sources/sdk/src/agent-runtime.ts +18 -1
  2. package/dist/bundling-sources/sdk/src/client.ts +212 -334
  3. package/dist/bundling-sources/sdk/src/compat.ts +45 -2
  4. package/dist/bundling-sources/sdk/src/db/query.ts +9 -10
  5. package/dist/bundling-sources/sdk/src/http.ts +38 -20
  6. package/dist/bundling-sources/sdk/src/index.ts +4 -5
  7. package/dist/bundling-sources/sdk/src/play.ts +10 -10
  8. package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +6 -4
  9. package/dist/bundling-sources/sdk/src/plays/check-local-play-graph.ts +114 -0
  10. package/dist/bundling-sources/sdk/src/plays/client.ts +431 -0
  11. package/dist/bundling-sources/sdk/src/plays/local-play-execution.ts +2 -2
  12. package/dist/bundling-sources/sdk/src/plays/run-request.ts +106 -16
  13. package/dist/bundling-sources/sdk/src/release.ts +13 -7
  14. package/dist/bundling-sources/sdk/src/runs/read-errors.ts +8 -0
  15. package/dist/bundling-sources/sdk/src/runs/watch-polling.ts +124 -13
  16. package/dist/bundling-sources/sdk/src/tool-calls.ts +108 -19
  17. package/dist/bundling-sources/sdk/src/types.ts +18 -0
  18. package/dist/bundling-sources/shared_libs/integration-contracts/execute-retry-contract.ts +37 -0
  19. package/dist/bundling-sources/shared_libs/integration-contracts/package.json +3 -0
  20. package/dist/bundling-sources/shared_libs/play-data-plane/r2.ts +3 -1
  21. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +277 -76
  22. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +6 -0
  23. package/dist/bundling-sources/shared_libs/play-runtime/dataset-row-input.ts +124 -0
  24. package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +6 -62
  25. package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +1 -0
  26. package/dist/bundling-sources/shared_libs/play-runtime/durable-tool-identity.ts +67 -0
  27. package/dist/bundling-sources/shared_libs/play-runtime/execute-server-timing.ts +64 -6
  28. package/dist/bundling-sources/shared_libs/play-runtime/freshness-receipt-execution.ts +1 -5
  29. package/dist/bundling-sources/shared_libs/play-runtime/ledger-safe-payload.ts +1 -1
  30. package/dist/bundling-sources/shared_libs/play-runtime/play-artifact-runtime-contract.ts +3 -0
  31. package/dist/bundling-sources/shared_libs/play-runtime/play-http-request.ts +10 -0
  32. package/dist/bundling-sources/shared_libs/play-runtime/query-result-dataset.ts +3 -0
  33. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/egress-probe.ts +3 -0
  34. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +26 -16
  35. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-heartbeat.ts +36 -11
  36. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-terminal-push.ts +35 -0
  37. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-launch-transport.ts +21 -0
  38. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +21 -6
  39. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-session-execution.ts +11 -2
  40. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +85 -20
  41. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +71 -13
  42. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-execution-queries.ts +100 -0
  43. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-pool.ts +9 -5
  44. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +337 -146
  45. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-shared.ts +26 -12
  46. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-state.ts +3 -1
  47. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +425 -102
  48. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-dispatch-authority.ts +4 -0
  49. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +4 -0
  50. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +9 -0
  51. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +181 -124
  52. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-worker-wake.ts +152 -0
  53. package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +5 -3
  54. package/dist/bundling-sources/shared_libs/play-runtime/tool-cache-policy.ts +31 -0
  55. package/dist/bundling-sources/shared_libs/play-runtime/transient-service-error.ts +10 -0
  56. package/dist/bundling-sources/shared_libs/plays/ambiguous-write-error.ts +25 -0
  57. package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +4 -0
  58. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +63 -68
  59. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +129 -63
  60. package/dist/bundling-sources/shared_libs/plays/contracts.ts +14 -0
  61. package/dist/bundling-sources/shared_libs/plays/enrich-play-compiler.ts +58 -16
  62. package/dist/bundling-sources/shared_libs/plays/fetch-http-error.ts +50 -0
  63. package/dist/bundling-sources/shared_libs/plays/source-authoring-edition.ts +351 -0
  64. package/dist/bundling-sources/shared_libs/plays/tool-list-getter-mode.ts +9 -0
  65. package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +1 -1
  66. package/dist/cli/{auth-UVD3CUBB.mjs → auth-LLXLIILR.mjs} +6 -6
  67. package/dist/cli/auth-UG4WOYGL.js +40 -0
  68. package/dist/cli/{billing-BZVTXXLM.mjs → billing-5FVXZYAC.mjs} +8 -8
  69. package/dist/cli/{billing-BZVYAF6T.js → billing-NFPK7GYP.js} +84 -84
  70. package/dist/cli/{chunk-ZAAKSJAS.js → chunk-27GJKC5Q.js} +17 -10
  71. package/dist/cli/{chunk-UHNDVD3P.js → chunk-2H4EY7KH.js} +100 -41
  72. package/dist/cli/{chunk-WTT6CLED.mjs → chunk-2YR7BIIC.mjs} +5 -2
  73. package/dist/cli/{chunk-3ZB6IIA7.js → chunk-36AHOWVS.js} +26 -26
  74. package/dist/cli/{chunk-OSDXE27V.mjs → chunk-4PG4ARL2.mjs} +17 -10
  75. package/dist/cli/{chunk-LOYISF7S.mjs → chunk-4XQLVUC7.mjs} +738 -512
  76. package/dist/cli/{chunk-J5PTX66Y.js → chunk-5MLCBXXU.js} +8 -1
  77. package/dist/cli/chunk-5TUGWDEB.js +313 -0
  78. package/dist/cli/{chunk-D6FFBSM5.js → chunk-5UUQAGJS.js} +5 -2
  79. package/dist/cli/{chunk-4CFULMRB.mjs → chunk-5V5Y37BC.mjs} +2 -2
  80. package/dist/cli/{chunk-PMVFAYL7.mjs → chunk-63ILLN5H.mjs} +2 -2
  81. package/dist/cli/{chunk-AUMD2VXP.js → chunk-63S7X326.js} +1032 -806
  82. package/dist/cli/{chunk-4QFT5LGV.mjs → chunk-6PGATQ6L.mjs} +6 -3
  83. package/dist/cli/{chunk-6BJK4EJ3.mjs → chunk-AARWVK4C.mjs} +2132 -65
  84. package/dist/cli/{chunk-FERRDNMO.js → chunk-AD47BXN2.js} +5 -5
  85. package/dist/cli/{chunk-4RNDKFNQ.js → chunk-D37FEBES.js} +2 -2
  86. package/dist/cli/{chunk-S6R3OX7B.js → chunk-E4CABWXL.js} +25 -2
  87. package/dist/cli/{chunk-NXGCO4JB.mjs → chunk-E4IXDAZI.mjs} +5 -0
  88. package/dist/cli/chunk-EQ4Z7RJW.mjs +35 -0
  89. package/dist/cli/chunk-FR2ILQ4G.mjs +8 -0
  90. package/dist/cli/{chunk-QUAQX3FQ.js → chunk-FVLNYDI4.js} +128 -376
  91. package/dist/cli/{chunk-BRJUESQV.js → chunk-FZJAM576.js} +50 -50
  92. package/dist/cli/{chunk-BZAMOCPA.mjs → chunk-IMZ56EOH.mjs} +3 -3
  93. package/dist/cli/{chunk-IOHRWLQE.mjs → chunk-IPG42SD2.mjs} +452 -138
  94. package/dist/cli/chunk-J33TSWO5.js +8 -0
  95. package/dist/cli/{chunk-XXLXOUUU.mjs → chunk-JNXJZ577.mjs} +1 -1
  96. package/dist/cli/{chunk-JI2B4RZP.mjs → chunk-KCC3FKIW.mjs} +71 -12
  97. package/dist/cli/{chunk-6IKARAYD.mjs → chunk-L2VKAASU.mjs} +23 -0
  98. package/dist/cli/{chunk-PYZZMAJQ.mjs → chunk-LFSHGNT2.mjs} +8 -1
  99. package/dist/cli/{chunk-2XXXFPTD.js → chunk-LTFL4JRN.js} +426 -721
  100. package/dist/cli/{chunk-YHPYUZZX.mjs → chunk-MAMVGOSC.mjs} +1 -1
  101. package/dist/cli/{chunk-URACNNLO.mjs → chunk-MN2OWLFA.mjs} +2 -2
  102. package/dist/cli/{chunk-Q3PUHXOY.js → chunk-NF4V5DTY.js} +12 -12
  103. package/dist/cli/{chunk-Q2E4E4FJ.js → chunk-NPBJI7RE.js} +8 -8
  104. package/dist/cli/chunk-NTVLGHFM.js +501 -0
  105. package/dist/cli/{chunk-HQXL5526.mjs → chunk-NUX2QHNC.mjs} +1 -1
  106. package/dist/cli/{chunk-E3PJF6YP.js → chunk-OBB4QXHA.js} +19 -4
  107. package/dist/cli/{chunk-SEFMGO3Z.js → chunk-OQQOXSYA.js} +2184 -117
  108. package/dist/cli/chunk-OZ6E3IRZ.js +6084 -0
  109. package/dist/cli/{chunk-7P5AA3SN.js → chunk-PPDBRJRW.js} +6 -1
  110. package/dist/cli/{chunk-IWBXJDZA.mjs → chunk-PZSLPBDA.mjs} +2 -2
  111. package/dist/cli/{chunk-ILHRA7AD.js → chunk-QADCFSGH.js} +7 -7
  112. package/dist/cli/{chunk-ECVLPS67.js → chunk-QJI5FIOW.js} +170 -49
  113. package/dist/cli/{chunk-I3DHIXVJ.mjs → chunk-QL22Y56M.mjs} +149 -28
  114. package/dist/cli/{chunk-SD7MXAJA.mjs → chunk-RFB25DSQ.mjs} +36 -284
  115. package/dist/cli/chunk-T44IIOT6.mjs +501 -0
  116. package/dist/cli/chunk-VK2LZ5IP.js +35 -0
  117. package/dist/cli/chunk-VKKVSFRD.js +62 -0
  118. package/dist/cli/{chunk-RWCY6YI2.js → chunk-VYKV5XHL.js} +644 -330
  119. package/dist/cli/{chunk-GSK6NHVM.js → chunk-WU4U6VSB.js} +5 -5
  120. package/dist/cli/chunk-XHLKJOTN.mjs +313 -0
  121. package/dist/cli/{chunk-MJELBQBU.mjs → chunk-XIHWSXSV.mjs} +330 -625
  122. package/dist/cli/chunk-XNZJKRJA.mjs +6084 -0
  123. package/dist/cli/chunk-ZCALLYF6.mjs +62 -0
  124. package/dist/cli/{chunk-ZBABPK6Y.js → chunk-ZFZ427HN.js} +11 -8
  125. package/dist/cli/{chunk-SJVVBWRL.mjs → chunk-ZKYEW55U.mjs} +16 -1
  126. package/dist/cli/command-docs.js +2 -2
  127. package/dist/cli/command-docs.mjs +1 -1
  128. package/dist/cli/{csv-XLGLHJ6P.js → csv-7U3FJYKZ.js} +14 -14
  129. package/dist/cli/{csv-WPSXG6ZZ.mjs → csv-ZWLDMM4A.mjs} +5 -5
  130. package/dist/cli/{db-5PTNJG4X.js → db-DNCGV5PC.js} +42 -47
  131. package/dist/cli/{db-ABS57ABJ.mjs → db-IMYXVMGI.mjs} +15 -20
  132. package/dist/cli/{describe-PVWQJ2PB.mjs → describe-Q23DWJUK.mjs} +20 -15
  133. package/dist/cli/{describe-EZS6PQXA.js → describe-S34JUX5W.js} +27 -22
  134. package/dist/cli/describe-core.d.mts +2 -2
  135. package/dist/cli/describe-core.d.ts +2 -2
  136. package/dist/cli/describe-core.js +6 -6
  137. package/dist/cli/describe-core.mjs +5 -5
  138. package/dist/cli/{executions-OKJGATQZ.mjs → executions-A73EUGSI.mjs} +8 -8
  139. package/dist/cli/{executions-FNTAFQ7Y.js → executions-XOMPX2YJ.js} +10 -10
  140. package/dist/cli/{feedback-W27HDMRR.mjs → feedback-N4GJ2POI.mjs} +11 -7
  141. package/dist/cli/{feedback-6YBOMSUA.js → feedback-QTCHNJJH.js} +13 -9
  142. package/dist/cli/{git-YOOUEL6M.mjs → git-4Q3JIQYZ.mjs} +6 -6
  143. package/dist/cli/git-I6CPBEVG.js +24 -0
  144. package/dist/cli/index.js +240 -352
  145. package/dist/cli/index.mjs +163 -275
  146. package/dist/cli/{legacy-noops-V6OKW7VR.mjs → legacy-noops-3SOVGFF7.mjs} +6 -6
  147. package/dist/cli/{legacy-noops-2VZ7XT6C.js → legacy-noops-4OSHZM34.js} +9 -9
  148. package/dist/cli/{monitors-FBWGVIUS.js → monitors-LVE2KZNG.js} +94 -94
  149. package/dist/cli/{monitors-P2YYWTWT.mjs → monitors-QP2XID2B.mjs} +8 -8
  150. package/dist/cli/{org-DVMG6H3C.mjs → org-IVRETVQA.mjs} +8 -8
  151. package/dist/cli/{org-3XUSVX5T.js → org-XFLK5IAP.js} +68 -68
  152. package/dist/cli/{play-GNC5CQAS.mjs → play-DE7VH6NU.mjs} +533 -98
  153. package/dist/cli/{play-YG5L4BWQ.js → play-XXTPPP23.js} +1067 -632
  154. package/dist/cli/{providers-7PSWG2OV.js → providers-DLD3I4JF.js} +11 -11
  155. package/dist/cli/{providers-JR33SLWL.mjs → providers-GX2NIZQQ.mjs} +8 -8
  156. package/dist/cli/{quickstart-VUOBQYIQ.mjs → quickstart-72B4L4PK.mjs} +5 -5
  157. package/dist/cli/{quickstart-FDVZ5BL3.js → quickstart-XNS3HSWC.js} +7 -7
  158. package/dist/cli/search-6NCH4HB5.js +30 -0
  159. package/dist/cli/{search-JZYLO33K.mjs → search-SUTRANJI.mjs} +9 -9
  160. package/dist/cli/{secrets-VS266FVA.js → secrets-6OBLOVEV.js} +17 -17
  161. package/dist/cli/{secrets-3MCYBT4I.mjs → secrets-FPFXXNUH.mjs} +8 -8
  162. package/dist/cli/sessions-235532DR.js +16 -0
  163. package/dist/cli/{sessions-ELLLT23E.mjs → sessions-R25I4QKN.mjs} +6 -6
  164. package/dist/cli/{settings-PZCKAFII.mjs → settings-AOP6F5PZ.mjs} +12 -12
  165. package/dist/cli/{settings-7364NMMA.js → settings-VL5FOFPN.js} +79 -79
  166. package/dist/cli/{setup-PMWYLCT6.js → setup-BSC67YT3.js} +45 -44
  167. package/dist/cli/{setup-A7GQ4KIA.mjs → setup-ZMPHBHVJ.mjs} +11 -10
  168. package/dist/cli/skills-3IWLYYRL.js +29 -0
  169. package/dist/cli/{skills-WS6BIFPQ.mjs → skills-KF65TVFO.mjs} +7 -7
  170. package/dist/cli/tools-LR66SPYU.js +44 -0
  171. package/dist/cli/{tools-BR4DOZA2.mjs → tools-SX4XIPM7.mjs} +19 -14
  172. package/dist/cli/{update-D2B7UNFT.mjs → update-QRMFRAQQ.mjs} +11 -9
  173. package/dist/cli/update-SP7UEO53.js +31 -0
  174. package/dist/cli/{workflow-PQXC2R47.mjs → workflow-FOEEEB7G.mjs} +44 -20
  175. package/dist/cli/{workflow-6ODTCYXU.js → workflow-KOCK2FLW.js} +54 -30
  176. package/dist/{client-Z9Pye1Wm.d.mts → client-74k4IPh6.d.mts} +137 -54
  177. package/dist/{client-BcvhDfJJ.d.ts → client-C1IK1f8c.d.ts} +137 -54
  178. package/dist/{compiler-manifest-Ycx-hoAr.d.mts → compiler-manifest-lzWpbV3w.d.mts} +83 -66
  179. package/dist/{compiler-manifest-Ycx-hoAr.d.ts → compiler-manifest-lzWpbV3w.d.ts} +83 -66
  180. package/dist/{index-CZXgiN3E.d.mts → index-C8Cy-YTm.d.ts} +5 -1
  181. package/dist/{index-NPG5pqxQ.d.ts → index-CtNK-0nI.d.mts} +5 -1
  182. package/dist/index.d.mts +47 -9
  183. package/dist/index.d.ts +47 -9
  184. package/dist/index.js +17 -14
  185. package/dist/index.mjs +13 -10
  186. package/dist/install-integrity.json +120 -104
  187. package/dist/plays/bundle-play-file.d.mts +3 -3
  188. package/dist/plays/bundle-play-file.d.ts +3 -3
  189. package/dist/plays/bundle-play-file.mjs +5 -4
  190. package/dist/plays/csv-data-input.js +3 -3
  191. package/dist/plays/csv-data-input.mjs +2 -2
  192. package/dist/plays/play-description.d.mts +2 -2
  193. package/dist/plays/play-description.d.ts +2 -2
  194. package/dist/plays/run-request.d.mts +2 -2
  195. package/dist/plays/run-request.d.ts +2 -2
  196. package/dist/plays/run-request.js +11 -3
  197. package/dist/plays/run-request.mjs +10 -2
  198. package/dist/release.d.mts +15 -6
  199. package/dist/release.d.ts +15 -6
  200. package/dist/release.js +2 -2
  201. package/dist/release.mjs +1 -1
  202. package/package.json +2 -2
  203. package/dist/cli/auth-3GB2K636.js +0 -40
  204. package/dist/cli/chunk-67RWR34T.mjs +0 -155
  205. package/dist/cli/chunk-CLJGSOVM.mjs +0 -1716
  206. package/dist/cli/chunk-HQY2SG3K.js +0 -83
  207. package/dist/cli/chunk-OSFWFV72.js +0 -155
  208. package/dist/cli/chunk-Q3LFI3VH.js +0 -392
  209. package/dist/cli/chunk-WPAB4DCU.mjs +0 -83
  210. package/dist/cli/chunk-YMOFWHGO.mjs +0 -392
  211. package/dist/cli/chunk-Z4VNJOF7.js +0 -1716
  212. package/dist/cli/git-YKUXXJOR.js +0 -24
  213. package/dist/cli/search-PPPYC5OZ.js +0 -30
  214. package/dist/cli/sessions-TEHEWW7O.js +0 -16
  215. package/dist/cli/skills-SYS7VRRK.js +0 -29
  216. package/dist/cli/tools-KK4BKVQR.js +0 -39
  217. package/dist/cli/update-2IV5JTX2.js +0 -29
@@ -1,3 +1,11 @@
1
+ import {
2
+ assertDatasetAdmissionHistory,
3
+ type DatasetPreviousCells,
4
+ } from './dataset-row-input';
5
+ import {
6
+ previousCellFromValue,
7
+ type CellStalenessMeta,
8
+ } from '../plays/cell-staleness';
1
9
  import {
2
10
  RuntimeSheetAttemptSupersededError,
3
11
  RuntimeSheetWriteIntentUnavailableError,
@@ -497,6 +505,7 @@ export type ResolvedRuntimePlay = {
497
505
  };
498
506
 
499
507
  export type PrepareRuntimeSheetResult = {
508
+ previousCells?: DatasetPreviousCells[];
500
509
  inserted: number;
501
510
  skipped: number;
502
511
  pendingRows: Record<string, unknown>[];
@@ -4612,6 +4621,7 @@ async function buildRuntimeSheetDatasetStartResult(
4612
4621
  inserted: number;
4613
4622
  rowDispositions: RuntimeSheetPreparedRowDisposition[];
4614
4623
  force?: boolean;
4624
+ includePreviousCells?: boolean;
4615
4625
  timings?: RuntimeSheetTiming[];
4616
4626
  },
4617
4627
  ): Promise<PrepareRuntimeSheetResult> {
@@ -4620,6 +4630,33 @@ async function buildRuntimeSheetDatasetStartResult(
4620
4630
  ? [column.field]
4621
4631
  : [],
4622
4632
  );
4633
+ const historicalCells = (
4634
+ rows: RuntimeApiRowRecord[],
4635
+ ): DatasetPreviousCells[] =>
4636
+ rows.flatMap(({ key, data }) => {
4637
+ const meta = parseRuntimeCellMeta(data[DEEPLINE_CELL_META_FIELD]);
4638
+ const cells = Object.fromEntries(
4639
+ datasetFields.flatMap((field) => {
4640
+ const cellMeta = parseRuntimeCellMeta(meta[field]);
4641
+ if (
4642
+ (cellMeta.status !== 'completed' && cellMeta.status !== 'cached') ||
4643
+ !Object.prototype.hasOwnProperty.call(data, field)
4644
+ )
4645
+ return [];
4646
+ return [
4647
+ [
4648
+ field,
4649
+ previousCellFromValue({
4650
+ hasValue: true,
4651
+ value: data[field],
4652
+ meta: cellMeta as CellStalenessMeta,
4653
+ })!,
4654
+ ],
4655
+ ];
4656
+ }),
4657
+ );
4658
+ return Object.keys(cells).length ? [{ key, cells }] : [];
4659
+ });
4623
4660
  const buildFreshRow = (entry: RuntimeDatasetRowEntry) => {
4624
4661
  const row: Record<string, unknown> = {
4625
4662
  ...sanitizePostgresJsonValue(entry.row),
@@ -4640,6 +4677,7 @@ async function buildRuntimeSheetDatasetStartResult(
4640
4677
  return {
4641
4678
  inserted: input.inserted,
4642
4679
  skipped: input.sourceRowsLength - input.rowEntries.length,
4680
+ ...(input.includePreviousCells ? { previousCells: [] } : {}),
4643
4681
  pendingRows: buildFreshPendingRows(),
4644
4682
  completedRows: [],
4645
4683
  blockedRows: [],
@@ -4721,6 +4759,9 @@ async function buildRuntimeSheetDatasetStartResult(
4721
4759
  return {
4722
4760
  inserted: input.inserted,
4723
4761
  skipped: input.sourceRowsLength - input.rowEntries.length,
4762
+ ...(input.includePreviousCells
4763
+ ? { previousCells: historicalCells(completedData) }
4764
+ : {}),
4724
4765
  pendingRows,
4725
4766
  completedRows,
4726
4767
  blockedRows,
@@ -4771,6 +4812,9 @@ async function buildRuntimeSheetDatasetStartResult(
4771
4812
  return {
4772
4813
  inserted: input.inserted,
4773
4814
  skipped: input.sourceRowsLength - input.rowEntries.length,
4815
+ ...(input.includePreviousCells
4816
+ ? { previousCells: historicalCells(persistedRows) }
4817
+ : {}),
4774
4818
  pendingRows,
4775
4819
  completedRows,
4776
4820
  blockedRows,
@@ -6970,6 +7014,9 @@ export async function startRuntimeSheetDataset(
6970
7014
  writeVersion?: number | null;
6971
7015
  /** Retain this run/table's first admission across pages, retries and wakes. Absence keeps legacy allocation. */
6972
7016
  stableWriteIntent?: boolean;
7017
+ /** Return completed durable cells separately from merged source rows. */
7018
+ includePreviousCells?: boolean;
7019
+ previousCellsBudgetBytes?: number;
6973
7020
  inputOffset?: number;
6974
7021
  force?: boolean;
6975
7022
  mode?: RuntimeSheetDatasetMode;
@@ -6977,16 +7024,25 @@ export async function startRuntimeSheetDataset(
6977
7024
  pendingRerunAdmission?: boolean;
6978
7025
  },
6979
7026
  ): Promise<PrepareRuntimeSheetResult> {
7027
+ const checkedResult = (
7028
+ result: PrepareRuntimeSheetResult,
7029
+ ): PrepareRuntimeSheetResult => {
7030
+ if (input.includePreviousCells)
7031
+ assertDatasetAdmissionHistory(result, input.previousCellsBudgetBytes);
7032
+ return result;
7033
+ };
6980
7034
  if (context.dbSessionStrategy === 'gateway_only') {
6981
- return await postRuntimeApi<PrepareRuntimeSheetResult>(context, {
6982
- // A named operation prevents an old gateway from silently ignoring the
6983
- // intent opt-in and re-admitting this run under a new version.
6984
- action:
6985
- input.stableWriteIntent === true
6986
- ? 'runtime_sheet_start_with_intent'
6987
- : 'runtime_sheet_start',
6988
- input: { ...input, pendingRerunAdmission: true },
6989
- });
7035
+ return checkedResult(
7036
+ await postRuntimeApi<PrepareRuntimeSheetResult>(context, {
7037
+ // A named operation prevents an old gateway from silently ignoring the
7038
+ // intent opt-in and re-admitting this run under a new version.
7039
+ action:
7040
+ input.stableWriteIntent === true
7041
+ ? 'runtime_sheet_start_with_intent'
7042
+ : 'runtime_sheet_start',
7043
+ input: { ...input, pendingRerunAdmission: true },
7044
+ }),
7045
+ );
6990
7046
  }
6991
7047
  const totalStartedAt = Date.now();
6992
7048
  const timings: RuntimeSheetTiming[] = [];
@@ -7088,9 +7144,10 @@ export async function startRuntimeSheetDataset(
7088
7144
  rows: input.rows.length,
7089
7145
  });
7090
7146
  if (rowEntries.length === 0) {
7091
- return {
7147
+ return checkedResult({
7092
7148
  inserted: 0,
7093
7149
  skipped: input.rows.length,
7150
+ ...(input.includePreviousCells ? { previousCells: [] } : {}),
7094
7151
  pendingRows: [],
7095
7152
  completedRows: [],
7096
7153
  blockedRows: [],
@@ -7103,7 +7160,7 @@ export async function startRuntimeSheetDataset(
7103
7160
  rows: input.rows.length,
7104
7161
  },
7105
7162
  ],
7106
- };
7163
+ });
7107
7164
  }
7108
7165
 
7109
7166
  const physicalColumns = physicalSheetColumnNames(input.sheetContract);
@@ -7311,6 +7368,7 @@ export async function startRuntimeSheetDataset(
7311
7368
  writeVersion,
7312
7369
  timings,
7313
7370
  force: input.force === true,
7371
+ includePreviousCells: input.includePreviousCells,
7314
7372
  ...prepared,
7315
7373
  });
7316
7374
  const membershipCapture = await runtimeSheetMembershipCaptureAvailable(
@@ -7395,7 +7453,7 @@ export async function startRuntimeSheetDataset(
7395
7453
  pending: result.pendingRows.length,
7396
7454
  completed: result.completedRows.length,
7397
7455
  });
7398
- return {
7456
+ return checkedResult({
7399
7457
  ...result,
7400
7458
  attemptId,
7401
7459
  attemptOwnerRunId,
@@ -7403,7 +7461,7 @@ export async function startRuntimeSheetDataset(
7403
7461
  attemptSeq,
7404
7462
  writeVersion: result.writeVersion,
7405
7463
  timings,
7406
- };
7464
+ });
7407
7465
  }
7408
7466
 
7409
7467
  export async function heartbeatRuntimeSheetAttempt(
@@ -0,0 +1,100 @@
1
+ /** Every candidate after an org's first B eligible runs has at least B runs
2
+ * from that same org ahead of it in the global total order. It therefore cannot
3
+ * enter the global first B. Enumerate every org, including NULL, without rotating
4
+ * a subset; retain the engine's fixed chosen IDs and under-lock rechecks. */
5
+ export function optimizeAbsurdFairClaimSql(noCapClaim: string): string {
6
+ const start = noCapClaim.indexOf(
7
+ " v_sql := format(\n 'with inflight as (",
8
+ );
9
+ const end = noCapClaim.indexOf('\n return query execute v_sql', start);
10
+ if (start < 0 || end < 0)
11
+ throw new Error('Absurd fair claim SQL markers are malformed.');
12
+ const original = noCapClaim.slice(start, end);
13
+ const from = original.indexOf(
14
+ ' from absurd.%1$I r\n join absurd.%2$I t',
15
+ );
16
+ const until = original.indexOf('\n ),\n ranked as (', from);
17
+ if (from < 0 || until < 0)
18
+ throw new Error('Absurd fair claim candidate markers are malformed.');
19
+ const eligibility = original
20
+ .slice(from, until)
21
+ .replace(
22
+ ' left join inflight i on i.org_key is not distinct from r.org_key\n',
23
+ '',
24
+ );
25
+ const bounded = `with recursive org_keys(org_key) as (
26
+ select min(org_key) from absurd.%1$I
27
+ where state in (''pending'', ''sleeping'') and org_key is not null
28
+ union all
29
+ select (select min(r.org_key) from absurd.%1$I r
30
+ where r.state in (''pending'', ''sleeping'') and r.org_key > o.org_key)
31
+ from org_keys o where o.org_key is not null
32
+ ), orgs as (
33
+ select org_key from org_keys where org_key is not null
34
+ ), bounded_ready as (
35
+ select head.* from orgs o cross join lateral (
36
+ select r.*
37
+ ${eligibility}
38
+ and r.org_key = o.org_key
39
+ order by r.priority desc, r.available_at, r.created_at, r.run_id
40
+ limit $2
41
+ ) head
42
+ union all
43
+ select null_head.* from (
44
+ select r.*
45
+ ${eligibility}
46
+ and r.org_key is null
47
+ order by r.priority desc, r.available_at, r.created_at, r.run_id
48
+ limit $2
49
+ ) null_head
50
+ ), inflight as (`;
51
+ const optimized = original
52
+ .replace('with inflight as (', bounded)
53
+ .replace(
54
+ original.slice(from, until),
55
+ ' from bounded_ready r\n left join inflight i on i.org_key is not distinct from r.org_key',
56
+ );
57
+ const choice = ` -- A false result proves there is no due run. Conservative run-only
58
+ -- probes retain task and continuation eligibility in the existing plans.
59
+ -- This must follow BOTH maintenance sweeps: fail_run can create ready work.
60
+ execute format('select exists (select 1 from absurd.%1$I where state = ''pending'' and available_at <= $1) or exists (select 1 from absurd.%1$I where state = ''sleeping'' and available_at <= $1)', 'r_' || p_queue_name)
61
+ into v_has_ready_run using v_now;
62
+ if not v_has_ready_run then
63
+ return;
64
+ end if;
65
+
66
+ -- An index changes only the query plan. Unmigrated queues keep the
67
+ -- identical fair ranking; no scheduler admission depends on migration state.
68
+ execute format('select exists (select 1 from absurd.%I where state in (''pending'', ''sleeping'', ''running'') and cancel_at is not null and cancel_at <= $1)', 't_' || p_queue_name)
69
+ into v_due_cancellations using v_now;
70
+ if exists (
71
+ select 1 from pg_index ix
72
+ join pg_class idx on idx.oid = ix.indexrelid
73
+ join pg_class tbl on tbl.oid = ix.indrelid
74
+ join pg_stats stats on stats.schemaname = 'absurd'
75
+ and stats.tablename = tbl.relname and stats.attname = 'org_key'
76
+ and stats.tablename = 'r_' || p_queue_name
77
+ and (stats.inherited or tbl.relkind <> 'p')
78
+ where ix.indexrelid = to_regclass(format('absurd.%I', 'r_' || p_queue_name ||
79
+ case when v_worker_id like '%:continuations' then '_fc' else '_fq' end))
80
+ and ix.indisvalid and ix.indisready
81
+ -- Require an eightfold candidate reduction to avoid sparse-tenant
82
+ -- random lookup amplification relative to the original window plan.
83
+ -- Catalog estimates select only an equivalent plan, never admission.
84
+ and (case when idx.relkind = 'I' then (
85
+ select coalesce(sum(greatest(leaf.reltuples, 0)), 0)
86
+ from pg_partition_tree(ix.indexrelid) tree
87
+ join pg_class leaf on leaf.oid = tree.relid where tree.isleaf
88
+ ) else idx.reltuples end) > 8::double precision * v_qty * greatest(1,
89
+ case when stats.n_distinct < 0 then -stats.n_distinct * tbl.reltuples
90
+ else stats.n_distinct end)
91
+ ) and not v_due_cancellations then
92
+ ${optimized}
93
+ else
94
+ ${original}
95
+ end if;`;
96
+ return (noCapClaim.slice(0, start) + choice + noCapClaim.slice(end)).replace(
97
+ ' v_sql text;',
98
+ ' v_sql text;\n v_due_cancellations boolean;\n v_has_ready_run boolean;',
99
+ );
100
+ }
@@ -12,6 +12,7 @@
12
12
  */
13
13
  import { createRequire } from 'node:module';
14
14
  import { AsyncLocalStorage } from 'node:async_hooks';
15
+ import { optimizeAbsurdFairClaimSql } from './absurd-execution-queries';
15
16
  import { readFileSync } from 'node:fs';
16
17
  import path from 'node:path';
17
18
  import {
@@ -142,10 +143,7 @@ export function readAbsurdSchemaSql(): string {
142
143
  * claim function deliberately ignores the retired setting, so it cannot limit
143
144
  * scheduler claims even while its compatibility-only column exists.
144
145
  */
145
- export function readAbsurdSchemaNoSchedulerOrgCapCompatibilitySql(): string {
146
- if (cachedNoSchedulerOrgCapCompatibilitySql !== null) {
147
- return cachedNoSchedulerOrgCapCompatibilitySql;
148
- }
146
+ export function readAbsurdSchemaUncappedClaimSql(): string {
149
147
  const sql = readAbsurdSchemaSql();
150
148
  const claim = schemaSection(
151
149
  sql,
@@ -188,10 +186,16 @@ export function readAbsurdSchemaNoSchedulerOrgCapCompatibilitySql(): string {
188
186
  }
189
187
  // The installed v4 claim function has the identical signature and result
190
188
  // type. Replacing only its body is safe for old and new processes alike.
191
- cachedNoSchedulerOrgCapCompatibilitySql = noCapClaim.replace(
189
+ return noCapClaim.replace(
192
190
  'create function absurd.claim_task',
193
191
  'create or replace function absurd.claim_task',
194
192
  );
193
+ }
194
+
195
+ export function readAbsurdSchemaNoSchedulerOrgCapCompatibilitySql(): string {
196
+ cachedNoSchedulerOrgCapCompatibilitySql ??= optimizeAbsurdFairClaimSql(
197
+ readAbsurdSchemaUncappedClaimSql(),
198
+ );
195
199
  return cachedNoSchedulerOrgCapCompatibilitySql;
196
200
  }
197
201