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,7 @@
1
+ import {
2
+ DatasetRowInputView,
3
+ assertDatasetAdmissionHistory,
4
+ } from './dataset-row-input';
1
5
  import {
2
6
  readRowFailureCounts,
3
7
  settledRowFailureKind,
@@ -275,6 +279,7 @@ import { resolveExplicitDurableCallPolicy } from './durable-call-policy';
275
279
  import { executeWithFreshnessReceipt } from './freshness-receipt-execution';
276
280
  import {
277
281
  CtxFetchHttpError,
282
+ LEGACY_PLAY_AUTHORING_CONTRACT_EDITION,
278
283
  PLAY_AUTHORING_CONTRACT_EDITION,
279
284
  PlayAuthoringFieldValidationError,
280
285
  normalizePlayAuthoringCustomerDbStatement,
@@ -287,6 +292,7 @@ import {
287
292
  type PlaySqlQuery,
288
293
  type PlayAuthoringRunScope,
289
294
  type PlayAuthoringRuntimeContext,
295
+ type PlayAuthoringRunStepsOptions,
290
296
  } from '../plays/authoring-contract';
291
297
  import {
292
298
  resolvePlayArtifactRuntimeContract,
@@ -681,6 +687,9 @@ const TOOL_RETRY_AFTER_FALLBACK_MS = 1_000;
681
687
  export const TOOL_EXECUTE_RESPONSE_BODY_TIMEOUT_MS = 30_000;
682
688
  const TOOL_RETRY_HEARTBEAT_INTERVAL_MS = 30_000;
683
689
  const TOOL_PROVIDER_RESIDENT_WAIT_BUDGET_MS = 5_000;
690
+ // The call already waited its whole admission budget in this sandbox, so it
691
+ // rejoins the shared lane promptly instead of adding a fixed delay of its own.
692
+ const PROVIDER_ADMISSION_REQUEUE_DELAY_MS = 1_000;
684
693
  const AUTHORED_SLEEP_RESIDENT_LIMIT_MS = 10_000;
685
694
  const DEEPLINEAGENT_TOOL_RUNTIME_TIMEOUT_MS = 15 * 60 * 1000;
686
695
  // Every runtime-API tool fetch needs a client-side deadline. Without one, a
@@ -1316,18 +1325,7 @@ export async function waitForNodeRuntimeMapRowsVisible(input: {
1316
1325
  * __deeplineRowKey and re-derivable output columns — never present on the raw
1317
1326
  * input row — are restored.
1318
1327
  */
1319
- export function persistedFieldsAbsentFromInputRow(
1320
- inputRow: Record<string, unknown>,
1321
- persisted: Record<string, unknown>,
1322
- ): Record<string, unknown> {
1323
- const extra: Record<string, unknown> = {};
1324
- for (const key of Object.keys(persisted)) {
1325
- if (!Object.prototype.hasOwnProperty.call(inputRow, key)) {
1326
- extra[key] = persisted[key];
1327
- }
1328
- }
1329
- return extra;
1330
- }
1328
+ export { persistedFieldsAbsentFromInputRow } from './dataset-row-input';
1331
1329
 
1332
1330
  export async function reconcileNodeRuntimeMapResultsWithPersistedSheet(input: {
1333
1331
  mapName: string;
@@ -2829,6 +2827,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
2829
2827
  >();
2830
2828
  #options: ContextOptions;
2831
2829
  private readonly rootRuntimeContract: PlayArtifactRuntimeContract;
2830
+ private readonly datasetRowInputs = new DatasetRowInputView();
2832
2831
  private readonly executionScope: RunExecutionScope;
2833
2832
  private readonly logBuffer = new RunLogBuffer();
2834
2833
  private logContextBudgetWarningLogged = false;
@@ -3420,6 +3419,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
3420
3419
  resolvePlayArtifactRuntimeContract({
3421
3420
  authoringContractEdition: options.authoringContractEdition,
3422
3421
  slackHitlTimeoutOutcome: options.slackHitlTimeoutOutcome,
3422
+ datasetRowInput: options.datasetRowInput,
3423
3423
  toolResponseContract: options.toolResponseContract,
3424
3424
  toolResponseReceiptRevision: options.toolResponseReceiptRevision,
3425
3425
  });
@@ -7524,6 +7524,12 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
7524
7524
  row: Record<string, unknown>,
7525
7525
  fieldName: string,
7526
7526
  ): PreviousCell | undefined {
7527
+ if (this.currentRuntimeContract.datasetRowInput === 'current_run') {
7528
+ const previous = this.datasetRowInputs.previous(row, fieldName);
7529
+ return previous
7530
+ ? { ...previous, value: this.rehydrateCellValue(previous.value) }
7531
+ : undefined;
7532
+ }
7527
7533
  const hasValue =
7528
7534
  Object.prototype.hasOwnProperty.call(row, fieldName) &&
7529
7535
  this.isCompletedFieldValue(row[fieldName]);
@@ -8367,7 +8373,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
8367
8373
  async runSteps<TInput extends Record<string, unknown>, TOutput = unknown>(
8368
8374
  program: RuntimeStepProgram,
8369
8375
  input: TInput,
8370
- options?: { description?: string },
8376
+ options?: PlayAuthoringRunStepsOptions,
8371
8377
  ): Promise<TOutput> {
8372
8378
  this.assertNoPendingDurableSuspension();
8373
8379
  if (!isRuntimeStepProgram(program)) {
@@ -8380,8 +8386,20 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
8380
8386
  );
8381
8387
  this.runtimeLog(options.description);
8382
8388
  }
8389
+ if (
8390
+ this.usesExplicitFreshness &&
8391
+ options?.staleAfterSeconds !== undefined
8392
+ ) {
8393
+ validatePlayAuthoringField(
8394
+ 'ctx.runSteps.options.staleAfterSeconds',
8395
+ options.staleAfterSeconds,
8396
+ );
8397
+ }
8383
8398
  return (await this.executeStepProgram(program, input, 0, [], {
8384
8399
  checkpointSteps: true,
8400
+ ...(options?.staleAfterSeconds !== undefined
8401
+ ? { defaultStaleAfterSeconds: options.staleAfterSeconds }
8402
+ : {}),
8385
8403
  })) as TOutput;
8386
8404
  }
8387
8405
 
@@ -8868,6 +8886,15 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
8868
8886
  executorToken: this.#options.executorToken,
8869
8887
  staticPipeline: this.currentStaticPipeline,
8870
8888
  forceRefresh: this.#options.cachePolicy?.forceToolRefresh === true,
8889
+ ...(this.currentRuntimeContract.datasetRowInput === 'current_run'
8890
+ ? {
8891
+ includePreviousCells: true,
8892
+ previousCellsBudgetBytes: Math.floor(
8893
+ mapMemoryLimits.materializedBudgetBytes /
8894
+ NODE_RUNTIME_MAP_MATERIALIZED_MEMORY_MULTIPLIER,
8895
+ ),
8896
+ }
8897
+ : {}),
8871
8898
  inputOffset: page.offset,
8872
8899
  mode: options?.mode,
8873
8900
  columnTypes: unchangedColumnTypes,
@@ -8876,6 +8903,16 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
8876
8903
  resolvedTableNamespace = normalizeTableNamespace(
8877
8904
  mapStartResult.tableNamespace,
8878
8905
  );
8906
+ const previousCellsByKey =
8907
+ this.currentRuntimeContract.datasetRowInput === 'current_run'
8908
+ ? assertDatasetAdmissionHistory(
8909
+ mapStartResult,
8910
+ Math.floor(
8911
+ mapMemoryLimits.materializedBudgetBytes /
8912
+ NODE_RUNTIME_MAP_MATERIALIZED_MEMORY_MULTIPLIER,
8913
+ ),
8914
+ )
8915
+ : undefined;
8879
8916
 
8880
8917
  const pendingRowsByKey = new Map<string, Record<string, unknown>>();
8881
8918
  for (
@@ -8900,12 +8937,12 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
8900
8937
  const persisted =
8901
8938
  pendingRowsByKey.get(rowKey) ?? completedRowsByKey.get(rowKey);
8902
8939
  return {
8903
- row: persisted
8904
- ? cloneCsvAliasedRow(
8905
- row,
8906
- persistedFieldsAbsentFromInputRow(row, persisted),
8907
- )
8908
- : row,
8940
+ row: this.datasetRowInputs.seed(
8941
+ row,
8942
+ persisted,
8943
+ this.currentRuntimeContract.datasetRowInput,
8944
+ previousCellsByKey?.get(rowKey),
8945
+ ),
8909
8946
  index: originalIndex,
8910
8947
  };
8911
8948
  });
@@ -8946,8 +8983,23 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
8946
8983
  rows: [],
8947
8984
  rowKeys: [],
8948
8985
  rowIndexes: [],
8949
- memoryEstimate: pageMemoryEstimate,
8986
+ memoryEstimate:
8987
+ this.currentRuntimeContract.datasetRowInput === 'current_run'
8988
+ ? estimateRuntimeMapRowsMemory(
8989
+ [...rowsToExecuteByKey.values()].map(({ row }) =>
8990
+ this.datasetRowInputs.memoryValue(row),
8991
+ ),
8992
+ )
8993
+ : pageMemoryEstimate,
8950
8994
  };
8995
+ if (prepared.memoryEstimate.estimatedResidentBytes > pageBudgetBytes) {
8996
+ throw new RuntimeMapMemoryLimitError({
8997
+ mapName: normalizedMapNamespace,
8998
+ phase: 'materialize',
8999
+ estimate: prepared.memoryEstimate,
9000
+ budgetBytes: pageBudgetBytes,
9001
+ });
9002
+ }
8951
9003
  for (const [rowKey, entry] of rowsToExecuteByKey) {
8952
9004
  prepared.rows.push(entry.row);
8953
9005
  prepared.rowKeys.push(rowKey);
@@ -9789,6 +9841,15 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
9789
9841
  executorToken: this.#options.executorToken,
9790
9842
  staticPipeline: this.currentStaticPipeline,
9791
9843
  forceRefresh: this.#options.cachePolicy?.forceToolRefresh === true,
9844
+ ...(this.currentRuntimeContract.datasetRowInput === 'current_run'
9845
+ ? {
9846
+ includePreviousCells: true,
9847
+ previousCellsBudgetBytes: Math.floor(
9848
+ mapMemoryLimits.materializedBudgetBytes /
9849
+ NODE_RUNTIME_MAP_MATERIALIZED_MEMORY_MULTIPLIER,
9850
+ ),
9851
+ }
9852
+ : {}),
9792
9853
  mode: options?.mode,
9793
9854
  columnTypes: unchangedColumnTypes,
9794
9855
  },
@@ -9796,6 +9857,16 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
9796
9857
  resolvedTableNamespace = normalizeTableNamespace(
9797
9858
  mapStartResult.tableNamespace,
9798
9859
  );
9860
+ const previousCellsByKey =
9861
+ this.currentRuntimeContract.datasetRowInput === 'current_run'
9862
+ ? assertDatasetAdmissionHistory(
9863
+ mapStartResult,
9864
+ Math.floor(
9865
+ mapMemoryLimits.materializedBudgetBytes /
9866
+ NODE_RUNTIME_MAP_MATERIALIZED_MEMORY_MULTIPLIER,
9867
+ ),
9868
+ )
9869
+ : undefined;
9799
9870
  const persistedRowIdentity = (row: Record<string, unknown>, index = 0) =>
9800
9871
  resolveMapRowOutcomeKey(row) ?? rowIdentity(row, index);
9801
9872
  const pendingRowsByKey = new Map<string, Record<string, unknown>>();
@@ -9825,25 +9896,13 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
9825
9896
  const rowKey = seedRowIdentity(row, index);
9826
9897
  const persisted =
9827
9898
  pendingRowsByKey.get(rowKey) ?? mapStartSeedRowsByKey.get(rowKey);
9828
- // Restore persisted OUTPUT columns, cell meta, and the carried
9829
- // __deeplineRowKey so key functions and column resolvers keep seeing
9830
- // projected values/aliases across the sheet round-trip. But the
9831
- // CURRENT run's INPUT columns are authoritative and must win: a
9832
- // persisted row is matched only by the map key, so for a play whose
9833
- // key does not capture every input column it can be a DIFFERENT run's
9834
- // row that merely shares that key. Letting its stale input columns
9835
- // overwrite this run's inputs corrupts input-derived tool arguments
9836
- // (e.g. scenario 87 vs 78 collide on key `id`='target' but pass
9837
- // distinct `key` columns to the probe tool, flipping a terminal
9838
- // failure into a spurious success). Merge only persisted fields
9839
- // absent from the fresh input row.
9840
9899
  return {
9841
- row: persisted
9842
- ? cloneCsvAliasedRow(
9843
- row,
9844
- persistedFieldsAbsentFromInputRow(row, persisted),
9845
- )
9846
- : row,
9900
+ row: this.datasetRowInputs.seed(
9901
+ row,
9902
+ persisted,
9903
+ this.currentRuntimeContract.datasetRowInput,
9904
+ previousCellsByKey?.get(rowKey),
9905
+ ),
9847
9906
  index,
9848
9907
  // `index` already names the authored input, not a position in
9849
9908
  // the pending subset. Looking it up again aliases resumed rows.
@@ -9858,6 +9917,22 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
9858
9917
  : seededItems;
9859
9918
  rawItems = admittedItems.map((item) => item.row);
9860
9919
  itemsToProcess = admittedItems.map((item) => item.row);
9920
+ if (this.currentRuntimeContract.datasetRowInput === 'current_run') {
9921
+ const estimate = estimateRuntimeMapRowsMemory(
9922
+ rawItems.map((row) => this.datasetRowInputs.memoryValue(row)),
9923
+ );
9924
+ if (
9925
+ estimate.estimatedResidentBytes >
9926
+ mapMemoryLimits.materializedBudgetBytes
9927
+ ) {
9928
+ throw new RuntimeMapMemoryLimitError({
9929
+ mapName: normalizedMapNamespace,
9930
+ phase: 'materialize',
9931
+ estimate,
9932
+ budgetBytes: mapMemoryLimits.materializedBudgetBytes,
9933
+ });
9934
+ }
9935
+ }
9861
9936
  itemOriginalIndexes = admittedItems.map((item) => item.originalIndex);
9862
9937
  totalInputCount = resumedPendingRowsOnly
9863
9938
  ? Math.max(replayMapFrame?.totalRows ?? 0, admittedItems.length)
@@ -10768,7 +10843,9 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
10768
10843
  name: 'run-row',
10769
10844
  acquire: async ({ baseRow }) =>
10770
10845
  await this.resourceGovernor.acquireRow({
10771
- estimatedBytes: runtimeMapJsonByteLength(baseRow),
10846
+ estimatedBytes: runtimeMapJsonByteLength(
10847
+ this.datasetRowInputs.memoryValue(baseRow),
10848
+ ),
10772
10849
  }),
10773
10850
  },
10774
10851
  ],
@@ -11309,6 +11386,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
11309
11386
  Math.max(0, TOOL_PROVIDER_RESIDENT_WAIT_BUDGET_MS - elapsedMs)
11310
11387
  );
11311
11388
  };
11389
+ const activeRowHistories = new Map<number, Record<string, unknown>>();
11312
11390
  const workers = Array.from({ length: workerCount }, async () => {
11313
11391
  while (firstRowError == null) {
11314
11392
  // A short provider hold must not leave this row behind the entire
@@ -11354,6 +11432,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
11354
11432
  continue;
11355
11433
  }
11356
11434
  const idx = providerRetry?.rowIndex ?? nextRowIndex++;
11435
+ let historyRow: Record<string, unknown> | undefined;
11357
11436
  if (!providerRetry) rowFeed?.markDispatched();
11358
11437
  try {
11359
11438
  const waitingRow = providerRetry
@@ -11367,6 +11446,11 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
11367
11446
  `Provider retry row ${idx} lost its resumable input.`,
11368
11447
  );
11369
11448
  }
11449
+ historyRow = baseRow;
11450
+ if (this.currentRuntimeContract.datasetRowInput === 'current_run') {
11451
+ activeRowHistories.set(idx, baseRow);
11452
+ this.datasetRowInputs.retain(baseRow, this.memoryLedger);
11453
+ }
11370
11454
  if (providerRetry) waitingBaseRows.delete(idx);
11371
11455
  else releaseDispatchedInputRow?.(idx);
11372
11456
  const callIndexes =
@@ -11395,6 +11479,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
11395
11479
  }
11396
11480
  rowFeed?.wakeWorkersAt(nextProviderRetry(true)!.readyAtMs);
11397
11481
  } else if (settledResults[idx] !== WAITING_ROW) {
11482
+ this.datasetRowInputs.release(baseRow);
11398
11483
  providerIdleWaitStartedAt = null;
11399
11484
  }
11400
11485
  if (mapProgress.activeResolvers === 0) retryWakeFeed.wakeWorkers();
@@ -11407,6 +11492,10 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
11407
11492
  heapAdmission.close(firstRowError);
11408
11493
  retryWakeFeed.fail(firstRowError);
11409
11494
  throw error;
11495
+ } finally {
11496
+ activeRowHistories.delete(idx);
11497
+ if (historyRow && !waitingBaseRows.has(idx))
11498
+ this.datasetRowInputs.release(historyRow);
11410
11499
  }
11411
11500
  }
11412
11501
  });
@@ -11504,6 +11593,15 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
11504
11593
  // The retained rows leave this map with the caller; from here they are
11505
11594
  // no longer bytes this runtime is holding on the caller's behalf.
11506
11595
  materializedRows.bytes?.release();
11596
+ for (const item of items) {
11597
+ if (item && typeof item === 'object')
11598
+ this.datasetRowInputs.release(item);
11599
+ }
11600
+ for (const { baseRow } of waitingBaseRows.values())
11601
+ this.datasetRowInputs.release(baseRow);
11602
+ for (const baseRow of activeRowHistories.values())
11603
+ this.datasetRowInputs.release(baseRow);
11604
+ activeRowHistories.clear();
11507
11605
  const heapSnapshot = heapAdmission.close();
11508
11606
  this.resourceGovernor.recordMapAdmission(
11509
11607
  normalizedTableNamespace,
@@ -11805,7 +11903,10 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
11805
11903
  row: Record<string, unknown>,
11806
11904
  index: number,
11807
11905
  path: string[],
11808
- options?: { checkpointSteps?: boolean },
11906
+ options?: {
11907
+ checkpointSteps?: boolean;
11908
+ defaultStaleAfterSeconds?: number | null;
11909
+ },
11809
11910
  ): Promise<unknown> {
11810
11911
  let currentRow = cloneCsvAliasedRow(row);
11811
11912
  const produced: Record<string, unknown> = {};
@@ -11846,6 +11947,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
11846
11947
  stepPath,
11847
11948
  undefined,
11848
11949
  stageExecution,
11950
+ options,
11849
11951
  ),
11850
11952
  {
11851
11953
  semanticKey: stableDigest(
@@ -11857,7 +11959,11 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
11857
11959
  ),
11858
11960
  ...(step.staleAfterSeconds !== undefined
11859
11961
  ? { staleAfterSeconds: step.staleAfterSeconds }
11860
- : {}),
11962
+ : options?.defaultStaleAfterSeconds !== undefined
11963
+ ? {
11964
+ staleAfterSeconds: options.defaultStaleAfterSeconds,
11965
+ }
11966
+ : {}),
11861
11967
  },
11862
11968
  )
11863
11969
  : await this.executeStepProgramStep(
@@ -11999,6 +12105,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
11999
12105
  path: string[],
12000
12106
  previousCell?: PreviousCell,
12001
12107
  stageExecution?: { skipped: boolean },
12108
+ options?: { defaultStaleAfterSeconds?: number | null },
12002
12109
  ): Promise<unknown> {
12003
12110
  const resolver = step.resolver;
12004
12111
  const store = rowContext.getStore();
@@ -12017,7 +12124,13 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
12017
12124
  if (isRuntimeStepProgram(resolver)) {
12018
12125
  return await runWithStepScope(
12019
12126
  async () =>
12020
- await this.executeStepProgram(resolver, currentRow, index, path),
12127
+ await this.executeStepProgram(resolver, currentRow, index, path, {
12128
+ ...(options?.defaultStaleAfterSeconds !== undefined
12129
+ ? {
12130
+ defaultStaleAfterSeconds: options.defaultStaleAfterSeconds,
12131
+ }
12132
+ : {}),
12133
+ }),
12021
12134
  );
12022
12135
  }
12023
12136
 
@@ -12253,6 +12366,10 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
12253
12366
  } finally {
12254
12367
  this.pulseProgressHeartbeat(true);
12255
12368
  this.pureMapExecutionActive = false;
12369
+ for (const item of items) {
12370
+ if (item && typeof item === 'object')
12371
+ this.datasetRowInputs.release(item);
12372
+ }
12256
12373
  }
12257
12374
 
12258
12375
  return results;
@@ -12935,9 +13052,12 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
12935
13052
 
12936
13053
  private toOutputRow<T>(item: T): Record<string, unknown> {
12937
13054
  if (item != null && typeof item === 'object' && !Array.isArray(item)) {
12938
- return copyPlayDatasetSourceRowIdentity(
13055
+ return this.datasetRowInputs.copy(
12939
13056
  item,
12940
- stripCsvProjectionMetadata(item as Record<string, unknown>),
13057
+ copyPlayDatasetSourceRowIdentity(
13058
+ item,
13059
+ stripCsvProjectionMetadata(item as Record<string, unknown>),
13060
+ ),
12941
13061
  );
12942
13062
  }
12943
13063
 
@@ -13218,8 +13338,6 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
13218
13338
  input,
13219
13339
  authScope,
13220
13340
  actionVersion,
13221
- responseContract: this.currentToolResponseContract,
13222
- responseRevision: this.currentToolResponseReceiptRevision,
13223
13341
  });
13224
13342
  if (sqlTool && input.operation_key !== undefined) {
13225
13343
  throw new Error(
@@ -13278,7 +13396,8 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
13278
13396
  key,
13279
13397
  toolId,
13280
13398
  requestInput,
13281
- { ...options, force: true, staleAfterSeconds: 0 },
13399
+ { ...options },
13400
+ true,
13282
13401
  );
13283
13402
  if ((await this.resolveToolAuthScopeDigest(toolId)) !== authScope) {
13284
13403
  throw new Error(
@@ -13287,17 +13406,47 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
13287
13406
  }
13288
13407
  return value;
13289
13408
  },
13290
- onOutcome: (value, freshness) =>
13291
- isToolExecuteResult(value)
13292
- ? cloneToolExecuteResultWithExecution(value, {
13293
- ...value._metadata.execution,
13294
- cached: freshness.source !== 'executed',
13295
- source: freshness.source === 'executed' ? 'live' : 'cache',
13296
- resultReceiptKey: freshness.operationReceiptKey,
13297
- freshness,
13298
- completedAt: freshness.completedAt,
13299
- })
13300
- : value,
13409
+ onOutcome: (value, freshness) => {
13410
+ if (!isToolExecuteResult(value)) return value;
13411
+ if (freshness.source !== 'executed') {
13412
+ const row = rowContext.getStore();
13413
+ if (row?.fieldName && row.tableNamespace && row.rowKey) {
13414
+ this.emitScopedFieldMetaUpdate({
13415
+ rowId: row.rowId,
13416
+ key: row.rowKey,
13417
+ tableNamespace: row.tableNamespace,
13418
+ fieldName: row.fieldName,
13419
+ status: 'cached',
13420
+ rowStatus: 'running',
13421
+ stage: toolId,
13422
+ provider: null,
13423
+ error: null,
13424
+ reused: true,
13425
+ dataPatch: {},
13426
+ });
13427
+ }
13428
+ }
13429
+ const resultReceiptKey =
13430
+ value._metadata.execution.resultReceiptKey ??
13431
+ value._metadata.execution.receiptKey ??
13432
+ freshness.operationReceiptKey;
13433
+ return this.materializeToolExecutionResult(
13434
+ cloneToolExecuteResultWithExecution(value, {
13435
+ ...value._metadata.execution,
13436
+ cached: freshness.source !== 'executed',
13437
+ source: freshness.source === 'executed' ? 'live' : 'cache',
13438
+ ...(freshness.source !== 'executed'
13439
+ ? {
13440
+ receiptRole: 'follower' as const,
13441
+ attachedToReceiptKey: resultReceiptKey,
13442
+ }
13443
+ : {}),
13444
+ ...(resultReceiptKey ? { resultReceiptKey } : {}),
13445
+ freshness,
13446
+ completedAt: freshness.completedAt,
13447
+ }),
13448
+ );
13449
+ },
13301
13450
  });
13302
13451
  }
13303
13452
 
@@ -13306,6 +13455,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
13306
13455
  toolId: string,
13307
13456
  input: Record<string, unknown>,
13308
13457
  options?: ToolCallOptions,
13458
+ deferResponseMaterialization = false,
13309
13459
  ): Promise<unknown> {
13310
13460
  if (!rowContext.getStore()) this.assertRowAdmissionOpen();
13311
13461
  this.assertNoPendingDurableSuspension();
@@ -13337,6 +13487,10 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
13337
13487
  );
13338
13488
  }
13339
13489
  const normalizedKey = this.normalizeContextKey(key, 'tool');
13490
+ const presentResult = (result: unknown): unknown =>
13491
+ isToolExecuteResult(result) && !deferResponseMaterialization
13492
+ ? this.materializeToolExecutionResult(result)
13493
+ : result;
13340
13494
  const toolCachePolicy = this.effectiveToolCallCachePolicy(options);
13341
13495
  const toolRequestIdentity = deriveToolRequestIdentity({
13342
13496
  toolId,
@@ -13449,9 +13603,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
13449
13603
  explicitForce,
13450
13604
  logicalCallId,
13451
13605
  );
13452
- return isToolExecuteResult(result)
13453
- ? this.materializeToolExecutionResult(result)
13454
- : result;
13606
+ return presentResult(result);
13455
13607
  }
13456
13608
  if (toolId === 'run_javascript') {
13457
13609
  throw new Error(DISALLOWED_RUN_JAVASCRIPT_TOOL_MESSAGE);
@@ -13472,7 +13624,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
13472
13624
  outcome: 'cached',
13473
13625
  durationMs: 0,
13474
13626
  });
13475
- return this.materializeToolExecutionResult(sourceRunRecovered);
13627
+ return presentResult(sourceRunRecovered);
13476
13628
  }
13477
13629
  }
13478
13630
  // callToolExecutionAPI charges the tool-call budget before first provider
@@ -13527,7 +13679,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
13527
13679
  outcome: 'cached',
13528
13680
  durationMs: 0,
13529
13681
  });
13530
- return this.materializeToolExecutionResult(recovered);
13682
+ return presentResult(recovered);
13531
13683
  } finally {
13532
13684
  if (!settled) {
13533
13685
  this.emitToolCallLifecycle('settled', toolId, normalizedKey, {
@@ -13578,9 +13730,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
13578
13730
  this.runtimeLog(
13579
13731
  `Calling tool: ${toolId} recovered from an explicit action compatibility receipt`,
13580
13732
  );
13581
- return isToolExecuteResult(recoveredCompatible)
13582
- ? this.materializeToolExecutionResult(recoveredCompatible)
13583
- : recoveredCompatible;
13733
+ return presentResult(recoveredCompatible);
13584
13734
  }
13585
13735
  }
13586
13736
  }
@@ -13629,9 +13779,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
13629
13779
  cacheKey: directCacheKey,
13630
13780
  }),
13631
13781
  );
13632
- return isToolExecuteResult(recoveredHistorical)
13633
- ? this.materializeToolExecutionResult(recoveredHistorical)
13634
- : recoveredHistorical;
13782
+ return presentResult(recoveredHistorical);
13635
13783
  }
13636
13784
  if (
13637
13785
  (!historicalReceipt || !historicalCanServeCurrentContract) &&
@@ -13666,9 +13814,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
13666
13814
  recoveredLegacy,
13667
13815
  )
13668
13816
  ) {
13669
- return isToolExecuteResult(recoveredLegacy)
13670
- ? this.materializeToolExecutionResult(recoveredLegacy)
13671
- : recoveredLegacy;
13817
+ return presentResult(recoveredLegacy);
13672
13818
  }
13673
13819
  bypassDirectResultCache = true;
13674
13820
  }
@@ -13930,7 +14076,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
13930
14076
  );
13931
14077
  this.#options.onBatchComplete?.(this.checkpoint);
13932
14078
  }
13933
- return this.materializeToolExecutionResult(wrapped);
14079
+ return presentResult(wrapped);
13934
14080
  } catch (error) {
13935
14081
  if (isControlledPlaySuspension(error)) {
13936
14082
  // A durable pause is not a terminal tool failure. Leave the start
@@ -13959,7 +14105,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
13959
14105
  : this.getCachedToolResultCandidate(toolId, checkpointCacheKeys);
13960
14106
  if (cached) {
13961
14107
  this.runtimeLog(` Row ${rowId} ${toolId}: recovered from checkpoint`);
13962
- return this.materializeToolExecutionResult(
14108
+ return presentResult(
13963
14109
  await this.wrapToolExecutionResult({
13964
14110
  toolId,
13965
14111
  status: cached.result.result == null ? 'no_result' : 'completed',
@@ -14375,6 +14521,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
14375
14521
  toolId,
14376
14522
  status: 'completed',
14377
14523
  result: existing.output,
14524
+ toolResponse: { rawV2: existing.output, view: 'rawV2' },
14378
14525
  execution: toolExecutionMetadataForOutcome({
14379
14526
  kind: 'checkpoint',
14380
14527
  cacheKey: `integration_event:${preparedBoundary.boundaryId}`,
@@ -14450,6 +14597,10 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
14450
14597
  toolId,
14451
14598
  status: 'completed',
14452
14599
  result: boundary.resolvedOutput,
14600
+ toolResponse: {
14601
+ rawV2: boundary.resolvedOutput,
14602
+ view: 'rawV2',
14603
+ },
14453
14604
  execution: toolExecutionMetadataForOutcome({
14454
14605
  kind: 'checkpoint',
14455
14606
  cacheKey: `integration_event:${boundary.boundaryId}`,
@@ -14590,13 +14741,16 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
14590
14741
  const childCompatibilitySnapshot =
14591
14742
  resolvedPlay.contractSnapshot?.compatibility ??
14592
14743
  resolvedPlay.artifact?.compatibility ??
14593
- buildPlayContractCompatibility();
14744
+ buildPlayContractCompatibility({
14745
+ authoringContractEdition: LEGACY_PLAY_AUTHORING_CONTRACT_EDITION,
14746
+ });
14594
14747
  const childCompatibility = normalizePlayContractCompatibility(
14595
14748
  childCompatibilitySnapshot,
14596
14749
  );
14597
14750
  const childRuntimeContract = resolvePlayArtifactRuntimeContract({
14598
14751
  authoringContractEdition: childCompatibility.authoringContractEdition,
14599
14752
  slackHitlTimeoutOutcome: childCompatibility.slackHitlTimeoutOutcome,
14753
+ datasetRowInput: childCompatibility.datasetRowInput,
14600
14754
  toolResponseContract: childCompatibility.toolResponseContract,
14601
14755
  toolResponseReceiptRevision:
14602
14756
  childCompatibility.toolResponseReceiptRevision,
@@ -15694,6 +15848,8 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
15694
15848
  timeouts: this.#options.ctxFetchTimeouts,
15695
15849
  fetchImpl: this.#options.fetchImpl,
15696
15850
  log: (message) => this.runtimeLog(message),
15851
+ reportAmbiguousWrite:
15852
+ this.usesExplicitFreshness && !reusableReadMethod,
15697
15853
  });
15698
15854
  const rawJson = parseJsonOrNull(bodyText);
15699
15855
  const output: PlayFetchResponse =
@@ -15766,6 +15922,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
15766
15922
  options?: RuntimeStepOptions,
15767
15923
  ): Promise<T> {
15768
15924
  if (!rowContext.getStore()) this.assertRowAdmissionOpen();
15925
+ this.assertNoPendingDurableSuspension();
15769
15926
  validatePlayAuthoringField('ctx.step.id', key);
15770
15927
  validateOptionalPlayAuthoringField(
15771
15928
  'ctx.step.semanticKey',
@@ -18477,6 +18634,11 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
18477
18634
  const providerNoProgressScope = stableDigest(
18478
18635
  `${provider}\u0000${executionAuthScopeDigest ?? ''}`,
18479
18636
  );
18637
+ // Starvation in Deepline's own admission queue is tracked apart from
18638
+ // provider holds so it never settles as a provider no-progress 429.
18639
+ const providerAdmissionNoProgressScope = stableDigest(
18640
+ `admission\u0000${providerNoProgressScope}`,
18641
+ );
18480
18642
  const providerNoProgressError = (retryAtMs: number) =>
18481
18643
  createToolHttpError(
18482
18644
  toolErrorSchemaVersion,
@@ -20040,7 +20202,43 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
20040
20202
  throw heartbeatFailure;
20041
20203
  }
20042
20204
  if (error instanceof ProviderAdmissionWaitTimeoutError) {
20043
- throw providerAdmissionTimeoutError(error);
20205
+ if (!this.#options.durableBoundaries) {
20206
+ throw providerAdmissionTimeoutError(error);
20207
+ }
20208
+ // A full shared lane is a queue, not a failure: other runs
20209
+ // hold its permits and nothing was sent. Re-queue durably
20210
+ // behind them. Only a lane that grants this call nothing for
20211
+ // the no-progress window settles, as a Deepline admission
20212
+ // timeout rather than a provider 429.
20213
+ const retryAtMs =
20214
+ Date.now() + PROVIDER_ADMISSION_REQUEUE_DELAY_MS;
20215
+ if (
20216
+ observeProviderNoProgress({
20217
+ startedAtMsByScope:
20218
+ (this.checkpoint.providerNoProgressStartedAtMsByScope ??=
20219
+ {}),
20220
+ scope: providerAdmissionNoProgressScope,
20221
+ retryAtMs,
20222
+ nowMs: Date.now(),
20223
+ }).exhausted
20224
+ ) {
20225
+ throw providerAdmissionTimeoutError(error);
20226
+ }
20227
+ if (
20228
+ options?.providerBackpressureMapRows ||
20229
+ rowContext.getStore()
20230
+ ) {
20231
+ throw new PlayRowProviderBackpressureError(
20232
+ error.provider,
20233
+ retryAtMs,
20234
+ markProviderResidentWaitBudgetExhausted(),
20235
+ );
20236
+ }
20237
+ await this.waitForProviderBackpressure(
20238
+ error.provider,
20239
+ retryAtMs,
20240
+ );
20241
+ continue;
20044
20242
  }
20045
20243
  if (error instanceof ProviderExhaustedError) {
20046
20244
  const retryAtMs = Date.parse(error.retryAt);
@@ -20666,6 +20864,9 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
20666
20864
  delete this.checkpoint.providerNoProgressStartedAtMsByScope[
20667
20865
  providerNoProgressScope
20668
20866
  ];
20867
+ delete this.checkpoint.providerNoProgressStartedAtMsByScope[
20868
+ providerAdmissionNoProgressScope
20869
+ ];
20669
20870
  }
20670
20871
  return receiptOutputRef
20671
20872
  ? { ...resolved, receiptOutputRef }