deepline 0.3.461 → 0.3.462
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundling-sources/sdk/src/client-core.ts +7593 -0
- package/dist/bundling-sources/sdk/src/client.ts +8 -7366
- package/dist/bundling-sources/sdk/src/http-core.ts +1239 -0
- package/dist/bundling-sources/sdk/src/http.ts +6 -1231
- package/dist/bundling-sources/sdk/src/index.ts +4 -1
- package/dist/bundling-sources/sdk/src/play.ts +5 -5
- package/dist/bundling-sources/sdk/src/plays/client-core.ts +437 -0
- package/dist/bundling-sources/sdk/src/plays/client.ts +4 -421
- package/dist/bundling-sources/sdk/src/plays/input-example.ts +3 -4
- package/dist/bundling-sources/sdk/src/plays/play-description.ts +1 -1
- package/dist/bundling-sources/sdk/src/plays/run-request.ts +1 -1
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/server.ts +43 -0
- package/dist/bundling-sources/sdk/src/types.ts +15 -5
- package/dist/bundling-sources/shared_libs/integration-contracts/billing-entitlements.ts +15 -0
- package/dist/bundling-sources/shared_libs/monitors/callback-security.ts +0 -307
- package/dist/bundling-sources/shared_libs/monitors/http-error-response.ts +3 -0
- package/dist/bundling-sources/shared_libs/monitors/lifecycle-notifications.ts +3 -2
- package/dist/bundling-sources/shared_libs/monitors/package.json +2 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-callback-verification.ts +34 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +59 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-upstream-identity.ts +94 -1
- package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-dead-letter.ts +11 -1
- package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-failure-codes.ts +24 -0
- package/dist/bundling-sources/shared_libs/observability/dlq.ts +32 -0
- package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +57 -3
- package/dist/bundling-sources/shared_libs/observability/scheduled-work.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-data-plane/r2.ts +66 -1
- package/dist/bundling-sources/shared_libs/play-data-plane/sheet-column-storage.ts +36 -7
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +250 -11
- package/dist/bundling-sources/shared_libs/play-runtime/array-input-store.ts +319 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +991 -359
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +17 -0
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-janitor.ts +13 -0
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-reaper.ts +110 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-machines.ts +155 -6
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-registry.ts +110 -6
- package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +127 -13
- package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +14 -1
- package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +57 -1
- package/dist/bundling-sources/shared_libs/play-runtime/free-company-lookup-batching.ts +218 -0
- package/dist/bundling-sources/shared_libs/play-runtime/gateway-postgres-admission.ts +42 -5
- package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-budget-state-backend.ts +6 -1
- package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +92 -31
- package/dist/bundling-sources/shared_libs/play-runtime/governor/block-reserving-budget-state-backend.ts +69 -14
- package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +93 -23
- package/dist/bundling-sources/shared_libs/play-runtime/governor/in-memory-rate-state-backend.ts +15 -4
- package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +22 -18
- package/dist/bundling-sources/shared_libs/play-runtime/governor/rate-state-backend.ts +5 -0
- package/dist/bundling-sources/shared_libs/play-runtime/launch-identity.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/map-memory-limits.ts +190 -14
- package/dist/bundling-sources/shared_libs/play-runtime/memory-ledger.ts +131 -0
- package/dist/bundling-sources/shared_libs/play-runtime/modal-runtime-config.ts +77 -2
- package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +271 -2
- package/dist/bundling-sources/shared_libs/play-runtime/play-run-recovery-policy.ts +51 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/contracts.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/job.ts +27 -1
- package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-batching-registry.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/provider-text-for-log.ts +63 -0
- package/dist/bundling-sources/shared_libs/play-runtime/resource-governor.ts +19 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger-event-transport.ts +112 -16
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +104 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +265 -151
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-gateway-transport.ts +17 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-progress-push.ts +35 -14
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-sheet-persistence-retry.ts +12 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-control-transport.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-labels.ts +36 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-launch-transport.ts +136 -70
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +237 -36
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-runtime-watchdog.ts +148 -4
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-session-execution.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +285 -32
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/modal.ts +251 -56
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +29 -4
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/sandbox-create-outcome.ts +27 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/types.ts +22 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +1397 -382
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-array-input-receipts.ts +920 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-constants.ts +16 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-environment.ts +38 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-flow.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-incident-drills.ts +26 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-operation-contract.ts +30 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-store-adapter.ts +14 -3
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-writer.ts +31 -4
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-row-transition.ts +47 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-compute-usage.ts +20 -7
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/contract.ts +12 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/index.ts +9 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/runner-backend-adapter.ts +10 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +1496 -320
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-required-env.ts +31 -1
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +1389 -129
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +36 -0
- 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 +162 -23
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +499 -115
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +377 -9
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-ledger-reconciliation.ts +117 -8
- package/dist/bundling-sources/shared_libs/play-runtime/secret-resolution-retry-policy.ts +25 -0
- package/dist/bundling-sources/shared_libs/play-runtime/terminal-runtime-performance.ts +391 -0
- package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +40 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-call/index.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-call/mapped-calls.ts +171 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-call/receipt-cohort.ts +16 -1
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +26 -3
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +16 -2
- package/dist/bundling-sources/shared_libs/play-runtime/transport-error-diagnostics.ts +28 -0
- package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-storage-contract.ts +55 -5
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +41 -1
- package/dist/bundling-sources/shared_libs/plays/contracts.ts +4 -0
- package/dist/bundling-sources/shared_libs/plays/dataset.ts +9 -3
- package/dist/bundling-sources/shared_libs/plays/deploy/manifest-contract.ts +2 -0
- package/dist/bundling-sources/shared_libs/plays/deploy/manifest.ts +3 -2
- package/dist/bundling-sources/shared_libs/plays/deploy/project-serializer.ts +2 -2
- package/dist/bundling-sources/shared_libs/plays/run-output-summary.ts +66 -0
- package/dist/bundling-sources/shared_libs/plays/script-entry.ts +1 -1
- package/dist/bundling-sources/shared_libs/product-notifications/catalog.ts +43 -1
- package/dist/bundling-sources/shared_libs/product-notifications/content.ts +9 -0
- package/dist/bundling-sources/shared_libs/product-notifications/email.ts +91 -13
- package/dist/bundling-sources/shared_libs/product-notifications/events.ts +3 -0
- package/dist/bundling-sources/shared_libs/product-notifications/slack-delivery.ts +41 -24
- package/dist/bundling-sources/shared_libs/security/attested-client-ip.ts +91 -0
- package/dist/bundling-sources/shared_libs/security/internal-actor.ts +0 -11
- package/dist/cli/{auth-6HJXNWUG.mjs → auth-JDLEY7VU.mjs} +5 -4
- package/dist/cli/auth-UXKY6TCC.js +41 -0
- package/dist/cli/{billing-6P5HO6QG.js → billing-HXAXB3XZ.js} +152 -78
- package/dist/cli/{billing-MJ42N7YF.mjs → billing-SDHLBLMV.mjs} +84 -10
- package/dist/cli/{chunk-5MDIZX7M.js → chunk-3ACMRZRV.js} +8 -6
- package/dist/cli/{chunk-FGLKOWSC.mjs → chunk-3KZCFOZ6.mjs} +1 -1
- package/dist/cli/chunk-4KQ6SIBC.mjs +1038 -0
- package/dist/cli/{chunk-Z2GUFYT6.js → chunk-5LEAXRHV.js} +11 -11
- package/dist/cli/{chunk-MEAIOXJL.mjs → chunk-6NNVJDVR.mjs} +7 -5
- package/dist/cli/{chunk-NMJ4D2WO.js → chunk-6PMCRYDA.js} +216 -91
- package/dist/cli/{chunk-RY4IVOU3.mjs → chunk-6RNQGWFD.mjs} +16 -806
- package/dist/cli/{chunk-EBU7LQ64.js → chunk-6V7KVRR5.js} +3 -3
- package/dist/cli/{chunk-OZBWRICM.js → chunk-7LFIMWMW.js} +2 -2
- package/dist/cli/chunk-7MJ6VI2T.mjs +19 -0
- package/dist/cli/chunk-7SWNPNML.js +1039 -0
- package/dist/cli/{chunk-IHHLTHE7.mjs → chunk-7U3XNPOA.mjs} +267 -38
- package/dist/cli/{chunk-5FDKJQZE.js → chunk-7VZHXVOQ.js} +1 -1
- package/dist/cli/{chunk-R64BGGRQ.mjs → chunk-AT636LLU.mjs} +2 -2
- package/dist/cli/{chunk-MDJPEGVN.js → chunk-BGTPIMSM.js} +392 -261
- package/dist/cli/{chunk-KVJ5VHW5.mjs → chunk-CKSOY47X.mjs} +2 -2
- package/dist/cli/{chunk-7DH2FD7Y.mjs → chunk-D464JW3N.mjs} +5 -85
- package/dist/cli/chunk-D6DXOUTO.mjs +827 -0
- package/dist/cli/{describe-2WQY7ZCY.js → chunk-EM4TXCCI.js} +27 -44
- package/dist/cli/chunk-F6QV42MC.mjs +91 -0
- package/dist/cli/chunk-FKVYR3QA.mjs +1039 -0
- package/dist/cli/{chunk-FGMX4HUZ.js → chunk-GEGW5HPZ.js} +29 -27
- package/dist/cli/{chunk-TNMBPMMC.js → chunk-HUB3CCM2.js} +13 -4
- package/dist/cli/{chunk-ACCR7POB.js → chunk-I6VHOU5O.js} +27 -27
- package/dist/cli/{chunk-Z2XUZC34.js → chunk-IAYSWZDJ.js} +188 -76
- package/dist/cli/chunk-JF3TLIMQ.js +19 -0
- package/dist/cli/{chunk-HDFRJ4IT.mjs → chunk-JVHOS3K3.mjs} +177 -65
- package/dist/cli/{chunk-V7REJRDZ.mjs → chunk-LFXLQEZN.mjs} +1 -1
- package/dist/cli/{chunk-CRYOUPEB.js → chunk-LROWFPGN.js} +16 -16
- package/dist/cli/{chunk-SLEUWLJE.mjs → chunk-MSY22NQW.mjs} +5 -5
- package/dist/cli/{chunk-BGY2PLP7.mjs → chunk-MUUQZIOF.mjs} +23 -49
- package/dist/cli/{chunk-FCAZQ7WV.js → chunk-NBLSCHKK.js} +52 -50
- package/dist/cli/{chunk-QAJAJPKK.mjs → chunk-NHRWZPWZ.mjs} +4 -2
- package/dist/cli/{chunk-KXMNM4AQ.js → chunk-NMU3VR5U.js} +4 -5
- package/dist/cli/{chunk-QIW7TVV6.mjs → chunk-O2RX5A66.mjs} +14 -12
- package/dist/cli/{chunk-SAZFZQRI.js → chunk-OMQ23IXL.js} +2 -2
- package/dist/cli/{chunk-5IYOUBFZ.js → chunk-OPJAJBD4.js} +28 -54
- package/dist/cli/{chunk-FJZILBL7.mjs → chunk-PHSEINNH.mjs} +5 -5
- package/dist/cli/{chunk-3DNKFH2G.mjs → chunk-PKHVSIJG.mjs} +19 -1
- package/dist/cli/{chunk-WIYWSYDS.mjs → chunk-Q2EIZKVX.mjs} +3 -3
- package/dist/cli/{chunk-5FY72YOV.js → chunk-QJZ6WNWD.js} +8 -8
- package/dist/cli/{chunk-EIMG75BT.mjs → chunk-S3A4IXBQ.mjs} +4 -5
- package/dist/cli/{chunk-3BMLICF7.mjs → chunk-S42YIQNE.mjs} +13 -8
- package/dist/cli/{chunk-RFONC4WJ.mjs → chunk-S6UAJR6V.mjs} +3 -3
- package/dist/cli/{chunk-G7L27KZB.mjs → chunk-TKAQR3IB.mjs} +31 -21
- package/dist/cli/{chunk-QWRHGGUH.js → chunk-UAJFWWZE.js} +20 -2
- package/dist/cli/{chunk-VZBCEA5S.mjs → chunk-UDRPEZ5F.mjs} +223 -92
- package/dist/cli/{chunk-KCCOQ5G5.js → chunk-ULK7JGGI.js} +511 -282
- package/dist/cli/chunk-V335HGX5.js +1038 -0
- package/dist/cli/{chunk-MGXEUZHL.mjs → chunk-V3MEA7NB.mjs} +7 -5
- package/dist/cli/{chunk-O6QOMHCH.js → chunk-VFGVXXZP.js} +37 -35
- package/dist/cli/chunk-VLEVVDWG.js +91 -0
- package/dist/cli/{chunk-R2GLGLDR.mjs → chunk-VPHN2HAL.mjs} +216 -91
- package/dist/cli/{chunk-CFUTOWE4.js → chunk-WG3KGAII.js} +8 -88
- package/dist/cli/{describe-FRAVCY5F.mjs → chunk-WIY6U6GD.mjs} +19 -36
- package/dist/cli/{chunk-PNATXKLP.js → chunk-XANRM3QA.js} +6 -6
- package/dist/cli/{chunk-KGQNIA37.js → chunk-XQCTG5OO.js} +44 -34
- package/dist/cli/{chunk-T3MVIPHG.mjs → chunk-XZAFIOUQ.mjs} +1 -1
- package/dist/cli/chunk-Y4DPU4OM.js +827 -0
- package/dist/cli/chunk-YT5EODJO.js +920 -0
- package/dist/cli/{chunk-SCIR5JXW.js → chunk-ZGQSFYD2.js} +56 -51
- package/dist/cli/{chunk-QEYHTIV4.mjs → chunk-ZUK6LIJB.mjs} +10 -1
- package/dist/cli/command-docs.d.mts +5 -0
- package/dist/cli/command-docs.d.ts +5 -0
- package/dist/cli/command-docs.js +2 -2
- package/dist/cli/command-docs.mjs +1 -1
- package/dist/cli/{csv-NX7NO3O6.js → csv-C56GSCEU.js} +13 -12
- package/dist/cli/{csv-DQ6GW5B5.mjs → csv-L54JS7TF.mjs} +4 -3
- package/dist/cli/{db-R72DFMP6.js → db-MOGRMZTA.js} +30 -27
- package/dist/cli/{db-2YP33M4K.mjs → db-YVBUW2DX.mjs} +10 -7
- package/dist/cli/describe-KYEULWPG.js +48 -0
- package/dist/cli/describe-NLZKKT7C.mjs +48 -0
- package/dist/cli/describe-core.d.mts +153 -5
- package/dist/cli/describe-core.d.ts +153 -5
- package/dist/cli/describe-core.js +9 -5
- package/dist/cli/describe-core.mjs +10 -6
- package/dist/cli/{executions-ZLHD4QIT.js → executions-A7L4ULPP.js} +9 -7
- package/dist/cli/{executions-WFBU7L2Q.mjs → executions-ZBGSTT37.mjs} +7 -5
- package/dist/cli/{feedback-CN3HJFVF.mjs → feedback-G6GU37FD.mjs} +6 -5
- package/dist/cli/{feedback-NDV6TPHG.js → feedback-OHLY7RYD.js} +10 -9
- package/dist/cli/getting-started.d.mts +6 -6
- package/dist/cli/getting-started.d.ts +6 -6
- package/dist/cli/getting-started.js +2 -2
- package/dist/cli/getting-started.mjs +1 -1
- package/dist/cli/git-P76N4NDQ.js +25 -0
- package/dist/cli/{git-QAD6E3HW.mjs → git-PKZW3QD5.mjs} +5 -4
- package/dist/cli/index.js +152 -142
- package/dist/cli/index.mjs +56 -46
- package/dist/cli/{legacy-noops-KVC5QJ74.js → legacy-noops-5LM3D724.js} +8 -7
- package/dist/cli/{legacy-noops-TPTKNBI2.mjs → legacy-noops-LJJYG6YA.mjs} +5 -4
- package/dist/cli/{monitors-SV57JFLO.mjs → monitors-72QV4ALO.mjs} +19 -6
- package/dist/cli/{monitors-KCROV6PJ.js → monitors-UX3H5DC2.js} +103 -90
- package/dist/cli/{org-KX6QIR7A.mjs → org-6RRRKOCP.mjs} +9 -6
- package/dist/cli/{org-NJYX5743.js → org-IF7ISUVB.js} +70 -67
- package/dist/cli/pages-3SU3HKL7.js +252 -0
- package/dist/cli/pages-DXDYYKEK.mjs +252 -0
- package/dist/cli/{play-IQQ57L7Z.mjs → play-AHASKRLA.mjs} +512 -1508
- package/dist/cli/{play-32L7EQN4.js → play-EUIUVLUH.js} +1090 -2086
- package/dist/cli/{providers-4WEC2EQN.mjs → providers-GWGE3WY3.mjs} +7 -5
- package/dist/cli/{providers-ZQV6QLVQ.js → providers-V5WU4VXJ.js} +10 -8
- package/dist/cli/{quickstart-RQ76RIUE.mjs → quickstart-OXKQ5ZST.mjs} +5 -4
- package/dist/cli/{quickstart-HKUSFADF.js → quickstart-QP65I5PF.js} +13 -12
- package/dist/cli/run-6MM72IGL.mjs +443 -0
- package/dist/cli/run-F3FTYS56.js +443 -0
- package/dist/cli/search-OYKOOI7A.js +32 -0
- package/dist/cli/{search-ZRAVFBZC.mjs → search-ZMEBVJZB.mjs} +8 -6
- package/dist/cli/{secrets-J3G5Y43U.js → secrets-ACND5N6A.js} +16 -14
- package/dist/cli/{secrets-CMJOVNVH.mjs → secrets-XRCJFF3L.mjs} +7 -5
- package/dist/cli/{sessions-MDQYY5CB.mjs → sessions-RTK3CEW6.mjs} +5 -4
- package/dist/cli/{sessions-WY7VN4AE.js → sessions-ZGRJPCFF.js} +6 -5
- package/dist/cli/{settings-HTNTFKCE.js → settings-PD5KWQQZ.js} +80 -77
- package/dist/cli/{settings-4RWZPCT5.mjs → settings-XDRBPRDE.mjs} +14 -11
- package/dist/cli/{setup-P3GYYZWG.mjs → setup-3HPYAOCC.mjs} +12 -10
- package/dist/cli/{setup-QGCAP62X.js → setup-E2Q6PXHC.js} +53 -51
- package/dist/cli/{skills-7NAE4ICL.mjs → skills-OOQFMPOV.mjs} +7 -6
- package/dist/cli/skills-XYWV52KB.js +31 -0
- package/dist/cli/tools-ASCDZJCK.js +55 -0
- package/dist/cli/tools-C5ZT3UIC.mjs +55 -0
- package/dist/cli/update-5RQSEIFM.js +33 -0
- package/dist/cli/{update-GODLRKNB.mjs → update-ZWJTADIW.mjs} +9 -8
- package/dist/cli/{workflow-4BXOUVEO.mjs → workflow-23NMPAJ7.mjs} +10 -8
- package/dist/cli/{workflow-AO3A6LXN.js → workflow-TCXU5YJV.js} +20 -18
- package/dist/client-DS2IWYZF.d.ts +10 -0
- package/dist/client-DTwnz_AW.d.mts +10 -0
- package/dist/{client-CYqG23K1.d.ts → client-core-B_6HAIBy.d.ts} +385 -12
- package/dist/{client-BbU5_j7n.d.mts → client-core-DzBSlY1U.d.mts} +385 -12
- package/dist/{compiler-manifest-CWz_sNOQ.d.ts → compiler-manifest-Dcyd3-Zd.d.mts} +43 -1
- package/dist/{compiler-manifest-CWz_sNOQ.d.mts → compiler-manifest-Dcyd3-Zd.d.ts} +43 -1
- package/dist/errors-d-sTrZhe.d.mts +142 -0
- package/dist/errors-yQwfgrcX.d.ts +142 -0
- package/dist/{index-BF2JB_Ug.d.mts → index-C6oXchjN.d.mts} +1 -1
- package/dist/{index-4NPXDzlD.d.ts → index-P56zy_z5.d.ts} +1 -1
- package/dist/index.d.mts +11 -147
- package/dist/index.d.ts +11 -147
- package/dist/index.js +15 -11
- package/dist/index.mjs +14 -10
- package/dist/install-integrity.json +141 -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 +2 -1
- package/dist/plays/play-description.d.mts +2 -2
- package/dist/plays/play-description.d.ts +2 -2
- package/dist/plays/play-description.js +2 -2
- package/dist/plays/play-description.mjs +1 -1
- package/dist/plays/run-request.d.mts +2 -2
- package/dist/plays/run-request.d.ts +2 -2
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +2 -2
- package/dist/release.mjs +1 -1
- package/dist/server.d.mts +17 -0
- package/dist/server.d.ts +17 -0
- package/dist/server.js +76 -0
- package/dist/server.mjs +76 -0
- package/package.json +6 -1
- package/dist/cli/auth-IACERYQH.js +0 -40
- package/dist/cli/chunk-PQUUWFXY.js +0 -95
- package/dist/cli/chunk-YBWAG72P.mjs +0 -95
- package/dist/cli/chunk-YQDUODZW.js +0 -1710
- package/dist/cli/git-JVI36ZFV.js +0 -24
- package/dist/cli/search-75X5LTDE.js +0 -30
- package/dist/cli/skills-BKJ53JOQ.js +0 -30
- package/dist/cli/tools-COWMIEJ6.mjs +0 -45
- package/dist/cli/tools-TASOCE7I.js +0 -45
- package/dist/cli/update-SJIKVME6.js +0 -32
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
} from '../types';
|
|
8
8
|
import { buildPlayRunnerBundle } from '../bundle';
|
|
9
9
|
import { findPlayRunnerResult, parsePlayRunnerEvents } from '../runner-events';
|
|
10
|
+
import { logSandboxCreateOutcome } from '../sandbox-create-outcome';
|
|
10
11
|
import type {
|
|
11
12
|
PlayRunnerExecutionConfig,
|
|
12
13
|
PlayRunnerResult,
|
|
@@ -21,6 +22,7 @@ import {
|
|
|
21
22
|
MODAL_SANDBOX_MEMORY_MIB,
|
|
22
23
|
loadModalClientConfig,
|
|
23
24
|
loadModalRequiredConfig,
|
|
25
|
+
withModalCallSignal,
|
|
24
26
|
} from '../../modal-runtime-config';
|
|
25
27
|
import type { PlaySandboxRuntimeLimits } from '../../../plays/sandbox-runtime-limits';
|
|
26
28
|
import { validateDaytonaExecutionContext } from './daytona-lifecycle';
|
|
@@ -33,6 +35,7 @@ import {
|
|
|
33
35
|
isPlayRunRecoveryError,
|
|
34
36
|
recoveryForOpenModalCircuit,
|
|
35
37
|
recoveryForModalSandboxCreateFailure,
|
|
38
|
+
recoveryForRunnerStartupNotLive,
|
|
36
39
|
} from '../../play-run-recovery-policy';
|
|
37
40
|
import { shouldInjectModalSandboxCreateResourceExhausted } from '../../test-runtime-seams';
|
|
38
41
|
import { RUNTIME_RELIABILITY_POLICY } from '../../runtime-reliability-policy';
|
|
@@ -44,8 +47,19 @@ const MODAL_SANDBOX_CREATE_TIMEOUT_MS =
|
|
|
44
47
|
const MODAL_PAYLOAD_UPLOAD_TIMEOUT_MS = 90_000;
|
|
45
48
|
const MODAL_TERMINATION_TIMEOUT_MS = 10_000;
|
|
46
49
|
const MODAL_DETACHED_INSPECTION_TIMEOUT_MS = 10_000;
|
|
50
|
+
/** Completion-marker reads still out, after their deadline or not. */
|
|
51
|
+
export const MODAL_RUNTIME_COMPLETION_READS_MAX = 8;
|
|
52
|
+
let modalRuntimeCompletionReadsOutstanding = 0;
|
|
53
|
+
/**
|
|
54
|
+
* A state-only read serves the fixed controller's liveness sweep, so it ends
|
|
55
|
+
* well inside that sweep's 10-second pass. The deadline cancels the call, so
|
|
56
|
+
* a provider that never answers leaves no abandoned read holding a slot.
|
|
57
|
+
*/
|
|
58
|
+
export const MODAL_SANDBOX_STATE_READ_TIMEOUT_MS = 5_000;
|
|
47
59
|
const MODAL_CAPACITY_RELEASE_RETRY_DELAYS_MS = [0, 100, 500, 2_000] as const;
|
|
48
60
|
const MODAL_LATE_CREATE_PERSIST_RETRY_DELAYS_MS = [0, 100, 500, 2_000] as const;
|
|
61
|
+
// The SDK does not export gRPC status codes.
|
|
62
|
+
const MODAL_GRPC_STATUS_NOT_FOUND = 5;
|
|
49
63
|
type ModalSandbox = Awaited<ReturnType<ModalClient['sandboxes']['create']>>;
|
|
50
64
|
|
|
51
65
|
class ModalPayloadUploadTimeoutError extends Error {
|
|
@@ -57,6 +71,18 @@ class ModalPayloadUploadTimeoutError extends Error {
|
|
|
57
71
|
}
|
|
58
72
|
}
|
|
59
73
|
|
|
74
|
+
/**
|
|
75
|
+
* A file did not reach the sandbox because Modal reports the sandbox
|
|
76
|
+
* unavailable, which another sandbox can outrun. Staging sends no command, so
|
|
77
|
+
* nothing could run. By name, as `isModalSandboxNotFoundError` reads the SDK's
|
|
78
|
+
* errors. Other write errors stay loud: the SDK folds a refused credential into
|
|
79
|
+
* the same `SandboxFilesystemError` as a provider fault, and a stalled upload
|
|
80
|
+
* may be input too large for any sandbox.
|
|
81
|
+
*/
|
|
82
|
+
function isUndeliveredModalRunnerFailure(error: unknown): boolean {
|
|
83
|
+
return error instanceof Error && error.name === 'NotFoundError';
|
|
84
|
+
}
|
|
85
|
+
|
|
60
86
|
async function writeModalFileWithDeadline(input: {
|
|
61
87
|
sandbox: ModalSandbox;
|
|
62
88
|
content: Buffer;
|
|
@@ -205,13 +231,15 @@ function emitModalStage(
|
|
|
205
231
|
);
|
|
206
232
|
}
|
|
207
233
|
|
|
208
|
-
async function confirmDetachedModalRunnerReady(input: {
|
|
234
|
+
export async function confirmDetachedModalRunnerReady(input: {
|
|
209
235
|
readiness: NonNullable<PlayRunnerCallbacks['readDetachedRunnerReadiness']>;
|
|
210
236
|
baselineHeartbeatAt: string | null;
|
|
211
237
|
cancellation?: Promise<never>;
|
|
238
|
+
timeoutMs?: number;
|
|
212
239
|
}): Promise<void> {
|
|
213
240
|
const cancellation = input.cancellation ?? new Promise<never>(() => {});
|
|
214
|
-
const
|
|
241
|
+
const timeoutMs = input.timeoutMs ?? MODAL_RUNNER_READY_TIMEOUT_MS;
|
|
242
|
+
const deadline = Date.now() + timeoutMs;
|
|
215
243
|
let delayMs = 50;
|
|
216
244
|
while (Date.now() < deadline) {
|
|
217
245
|
const response = await Promise.race([
|
|
@@ -225,8 +253,10 @@ async function confirmDetachedModalRunnerReady(input: {
|
|
|
225
253
|
]);
|
|
226
254
|
delayMs = Math.min(1_000, delayMs * 2);
|
|
227
255
|
}
|
|
228
|
-
throw
|
|
229
|
-
|
|
256
|
+
throw recoveryForRunnerStartupNotLive(
|
|
257
|
+
new Error(
|
|
258
|
+
`RUNTIME_SANDBOX_START_FAILED: Modal accepted the runner command, but the scheduler did not observe play-runner liveness within ${timeoutMs}ms. Customer play execution was not parked.`,
|
|
259
|
+
),
|
|
230
260
|
);
|
|
231
261
|
}
|
|
232
262
|
|
|
@@ -355,6 +385,7 @@ export const modalPlayRunnerBackend: PlayRunnerBackend = {
|
|
|
355
385
|
attempt: String(config.context.runAttempt ?? 0),
|
|
356
386
|
};
|
|
357
387
|
let sandbox: ModalSandbox;
|
|
388
|
+
let createSent = false;
|
|
358
389
|
try {
|
|
359
390
|
// This is deliberately adjacent to the real provider boundary. The
|
|
360
391
|
// reservation proves the scheduler observes the same no-resource
|
|
@@ -394,6 +425,7 @@ export const modalPlayRunnerBackend: PlayRunnerBackend = {
|
|
|
394
425
|
? { sandboxCapacityLeaseId: capacityReservation.leaseId }
|
|
395
426
|
: {}),
|
|
396
427
|
});
|
|
428
|
+
createSent = true;
|
|
397
429
|
sandbox = await awaitModalSandboxCreate({
|
|
398
430
|
create: modalConfig.client.sandboxes.create(app, image, {
|
|
399
431
|
cpu: MODAL_SANDBOX_CPU_CORES,
|
|
@@ -409,6 +441,12 @@ export const modalPlayRunnerBackend: PlayRunnerBackend = {
|
|
|
409
441
|
: {}),
|
|
410
442
|
}),
|
|
411
443
|
onLateSuccess: async (lateSandbox) => {
|
|
444
|
+
logSandboxCreateOutcome({
|
|
445
|
+
provider: 'modal',
|
|
446
|
+
outcome: 'succeeded',
|
|
447
|
+
runId: config.context.runId,
|
|
448
|
+
reason: 'late',
|
|
449
|
+
});
|
|
412
450
|
// Do not directly delete a late sandbox. First store it as a
|
|
413
451
|
// durable cleanup obligation, then let the normal cleanup worker
|
|
414
452
|
// perform provider-confirmed deletion, capacity release, and
|
|
@@ -467,7 +505,25 @@ export const modalPlayRunnerBackend: PlayRunnerBackend = {
|
|
|
467
505
|
await callbacks?.onAmbiguousModalCreateResolved?.();
|
|
468
506
|
},
|
|
469
507
|
});
|
|
508
|
+
logSandboxCreateOutcome({
|
|
509
|
+
provider: 'modal',
|
|
510
|
+
outcome: 'succeeded',
|
|
511
|
+
runId: config.context.runId,
|
|
512
|
+
});
|
|
470
513
|
} catch (error) {
|
|
514
|
+
if (createSent) {
|
|
515
|
+
logSandboxCreateOutcome({
|
|
516
|
+
provider: 'modal',
|
|
517
|
+
outcome:
|
|
518
|
+
error instanceof ModalSandboxCreateOutcomeUnknownError
|
|
519
|
+
? 'unknown'
|
|
520
|
+
: 'failed',
|
|
521
|
+
runId: config.context.runId,
|
|
522
|
+
reason:
|
|
523
|
+
recoveryForModalSandboxCreateFailure(error)?.decision.reason ??
|
|
524
|
+
null,
|
|
525
|
+
});
|
|
526
|
+
}
|
|
471
527
|
if (
|
|
472
528
|
capacityReservation &&
|
|
473
529
|
!(error instanceof ModalSandboxCreateOutcomeUnknownError)
|
|
@@ -604,7 +660,17 @@ export const modalPlayRunnerBackend: PlayRunnerBackend = {
|
|
|
604
660
|
emitModalStage(config.context, stage, extra),
|
|
605
661
|
}),
|
|
606
662
|
cancellationPromise,
|
|
607
|
-
])
|
|
663
|
+
]).catch((error: unknown) => {
|
|
664
|
+
// The runner never reached this sandbox. `finally` terminates it,
|
|
665
|
+
// and the defer starts a new attempt on a new sandbox.
|
|
666
|
+
if (
|
|
667
|
+
!callbacks?.cancellationSignal?.aborted &&
|
|
668
|
+
isUndeliveredModalRunnerFailure(error)
|
|
669
|
+
) {
|
|
670
|
+
throw recoveryForRunnerStartupNotLive(error);
|
|
671
|
+
}
|
|
672
|
+
throw error;
|
|
673
|
+
});
|
|
608
674
|
runtimeTiming.modalUploadMs = Date.now() - uploadStartedAt;
|
|
609
675
|
const baselineHeartbeatAt = await Promise.race([
|
|
610
676
|
captureDetachedDaytonaRunnerReadinessBaseline({
|
|
@@ -628,10 +694,10 @@ export const modalPlayRunnerBackend: PlayRunnerBackend = {
|
|
|
628
694
|
provider: 'modal',
|
|
629
695
|
sandboxId: sandbox.sandboxId,
|
|
630
696
|
});
|
|
631
|
-
//
|
|
632
|
-
//
|
|
633
|
-
//
|
|
634
|
-
//
|
|
697
|
+
// The runner holds customer code until this worker parks the attempt,
|
|
698
|
+
// and that park comes after this check. A runner that never reports
|
|
699
|
+
// live therefore never released anything, and the scheduler's defer
|
|
700
|
+
// starts a new attempt whose fence rejects it.
|
|
635
701
|
await confirmDetachedModalRunnerReady({
|
|
636
702
|
readiness: readRunnerReadiness,
|
|
637
703
|
baselineHeartbeatAt,
|
|
@@ -746,6 +812,46 @@ export const modalPlayRunnerBackend: PlayRunnerBackend = {
|
|
|
746
812
|
},
|
|
747
813
|
};
|
|
748
814
|
|
|
815
|
+
/**
|
|
816
|
+
* `poll()` and `terminate()` pass Modal's gRPC failure through unchanged, so
|
|
817
|
+
* Modal not knowing an exact sandbox id arrives as a gRPC NOT_FOUND. The SDK's
|
|
818
|
+
* `NotFoundError` is what its other lookups raise for the same fact.
|
|
819
|
+
*
|
|
820
|
+
* Use this only on those calls. `sandbox.filesystem` also raises
|
|
821
|
+
* `NotFoundError` for transient failures such as UNAVAILABLE, so a failed file
|
|
822
|
+
* read proves nothing about the sandbox.
|
|
823
|
+
*/
|
|
824
|
+
function isModalSandboxNotFoundError(error: unknown): boolean {
|
|
825
|
+
if (!(error instanceof Error)) return false;
|
|
826
|
+
if (error.name === 'NotFoundError') return true;
|
|
827
|
+
return (
|
|
828
|
+
error.name === 'ClientError' &&
|
|
829
|
+
(error as { code?: unknown }).code === MODAL_GRPC_STATUS_NOT_FOUND
|
|
830
|
+
);
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* What Modal says about one sandbox. A failed read throws: it is not a state,
|
|
835
|
+
* and a stale runner must stay unproven rather than be called lost.
|
|
836
|
+
*/
|
|
837
|
+
async function readModalSandboxState(
|
|
838
|
+
sandbox: ModalSandbox,
|
|
839
|
+
): Promise<
|
|
840
|
+
| { kind: 'running' }
|
|
841
|
+
| { kind: 'stopped'; returnCode: number }
|
|
842
|
+
| { kind: 'missing' }
|
|
843
|
+
> {
|
|
844
|
+
try {
|
|
845
|
+
const returnCode = await sandbox.poll();
|
|
846
|
+
return returnCode === null
|
|
847
|
+
? { kind: 'running' }
|
|
848
|
+
: { kind: 'stopped', returnCode };
|
|
849
|
+
} catch (error) {
|
|
850
|
+
if (isModalSandboxNotFoundError(error)) return { kind: 'missing' };
|
|
851
|
+
throw error;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
|
|
749
855
|
export async function deleteModalSandboxById(input: {
|
|
750
856
|
sandboxId: string;
|
|
751
857
|
expectedAppId?: string | null;
|
|
@@ -768,17 +874,19 @@ export async function deleteModalSandboxById(input: {
|
|
|
768
874
|
}
|
|
769
875
|
try {
|
|
770
876
|
const { client } = await loadModalClientConfig();
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
// id is absent satisfies the obligation without an unsafe cross-app get.
|
|
780
|
-
return { kind: 'already_absent', appId: expectedAppId };
|
|
877
|
+
// Never walk the app here: each walk spends Modal's LIST limit, and on
|
|
878
|
+
// Oct 29 that throttled deletes while finished sandboxes kept billing.
|
|
879
|
+
// `fromId` makes no call. Modal has no public read of a sandbox's app, so
|
|
880
|
+
// the exact id persisted at create is the authority and `terminate` is
|
|
881
|
+
// the first thing to learn whether it still exists.
|
|
882
|
+
const sandbox = await client.sandboxes.fromId(input.sandboxId);
|
|
883
|
+
await sandbox.terminate({ wait: true });
|
|
884
|
+
return { kind: 'deleted', appId: expectedAppId };
|
|
781
885
|
} catch (error) {
|
|
886
|
+
// Cleanup means ensure absent, and this answer is about this exact id.
|
|
887
|
+
if (isModalSandboxNotFoundError(error)) {
|
|
888
|
+
return { kind: 'already_absent', appId: expectedAppId };
|
|
889
|
+
}
|
|
782
890
|
console.warn('[play-runner.modal.reclaim_sandbox_delete_failed]', {
|
|
783
891
|
sandboxId: input.sandboxId,
|
|
784
892
|
expectedAppId,
|
|
@@ -797,6 +905,8 @@ export async function deleteModalSandboxById(input: {
|
|
|
797
905
|
* Read the provider inventory using the exact app + tag selector persisted
|
|
798
906
|
* before a Modal create call. This is deliberately a tiny provider adapter:
|
|
799
907
|
* the scheduler owns claim/fencing, resource recording, cleanup, and policy.
|
|
908
|
+
* A list is required here: a create with an unknown outcome has no sandbox id
|
|
909
|
+
* to read, and these tags name one attempt, so this does not walk the app.
|
|
800
910
|
*/
|
|
801
911
|
export async function findModalSandboxIdsByTags(input: {
|
|
802
912
|
modalAppId: string;
|
|
@@ -827,14 +937,16 @@ export async function findModalSandboxIdsByTags(input: {
|
|
|
827
937
|
|
|
828
938
|
/**
|
|
829
939
|
* Best-effort terminal recovery for an already-detached Modal runner. This
|
|
830
|
-
* reads
|
|
831
|
-
* code or launches a replacement sandbox.
|
|
940
|
+
* reads the sandbox's state and the payload wrapper's captured files; it never
|
|
941
|
+
* executes Play code or launches a replacement sandbox.
|
|
832
942
|
*/
|
|
833
943
|
export async function inspectDetachedModalRunner(input: {
|
|
834
944
|
sandboxId: string;
|
|
835
945
|
outputPath: string;
|
|
836
946
|
exitCodePath: string;
|
|
837
947
|
expectedAppId?: string | null;
|
|
948
|
+
/** Answer from the sandbox's state alone. See the reconciliation seam. */
|
|
949
|
+
skipCapturedOutput?: boolean;
|
|
838
950
|
}): Promise<{
|
|
839
951
|
exitCode: number | null;
|
|
840
952
|
result: PlayRunnerResult | null;
|
|
@@ -852,15 +964,59 @@ export async function inspectDetachedModalRunner(input: {
|
|
|
852
964
|
};
|
|
853
965
|
}
|
|
854
966
|
|
|
855
|
-
|
|
967
|
+
const timeoutMs = input.skipCapturedOutput
|
|
968
|
+
? MODAL_SANDBOX_STATE_READ_TIMEOUT_MS
|
|
969
|
+
: MODAL_DETACHED_INSPECTION_TIMEOUT_MS;
|
|
970
|
+
// The deadline cancels Modal's calls as well as the wait, so a read that
|
|
971
|
+
// times out is over and a stuck provider cannot pile reads up behind it.
|
|
972
|
+
const deadline = new AbortController();
|
|
973
|
+
const timer = setTimeout(() => {
|
|
974
|
+
deadline.abort(
|
|
975
|
+
new Error(
|
|
976
|
+
`Modal detached-runner inspection exceeded ${timeoutMs}ms.`,
|
|
977
|
+
),
|
|
978
|
+
);
|
|
979
|
+
}, timeoutMs);
|
|
856
980
|
try {
|
|
857
981
|
return await Promise.race([
|
|
858
|
-
(async () => {
|
|
982
|
+
withModalCallSignal(deadline.signal, async () => {
|
|
859
983
|
const { client } = await loadModalClientConfig();
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
984
|
+
const sandbox = await client.sandboxes.fromId(input.sandboxId);
|
|
985
|
+
try {
|
|
986
|
+
// Proof of loss is a read of this one sandbox. The app list holds
|
|
987
|
+
// only running sandboxes and is rate limited, so absence from it
|
|
988
|
+
// proves nothing.
|
|
989
|
+
const state = await readModalSandboxState(sandbox);
|
|
990
|
+
if (state.kind === 'missing') {
|
|
991
|
+
return {
|
|
992
|
+
exitCode: null,
|
|
993
|
+
result: null,
|
|
994
|
+
diagnosis: {
|
|
995
|
+
stage: 'sandbox_missing',
|
|
996
|
+
detail: 'Modal has no sandbox with this id.',
|
|
997
|
+
},
|
|
998
|
+
};
|
|
999
|
+
}
|
|
1000
|
+
if (state.kind === 'stopped') {
|
|
1001
|
+
// Files cannot be read from a stopped sandbox. The return code is
|
|
1002
|
+
// the sandbox's own, not the runner's, and 137 covers both a spend
|
|
1003
|
+
// limit kill and a terminate, so it stays out of `exitCode`.
|
|
1004
|
+
return {
|
|
1005
|
+
exitCode: null,
|
|
1006
|
+
result: null,
|
|
1007
|
+
diagnosis: {
|
|
1008
|
+
stage: 'sandbox_stopped',
|
|
1009
|
+
detail: `Modal sandbox ended with return code ${state.returnCode}.`,
|
|
1010
|
+
},
|
|
1011
|
+
};
|
|
1012
|
+
}
|
|
1013
|
+
if (input.skipCapturedOutput) {
|
|
1014
|
+
return {
|
|
1015
|
+
exitCode: null,
|
|
1016
|
+
result: null,
|
|
1017
|
+
diagnosis: { stage: 'sandbox_not_ended', detail: null },
|
|
1018
|
+
};
|
|
1019
|
+
}
|
|
864
1020
|
const [output, exitCode] = await Promise.allSettled([
|
|
865
1021
|
sandbox.filesystem.readText(input.outputPath),
|
|
866
1022
|
sandbox.filesystem.readText(input.exitCodePath),
|
|
@@ -892,24 +1048,18 @@ export async function inspectDetachedModalRunner(input: {
|
|
|
892
1048
|
? { stage: 'salvaged', detail: null }
|
|
893
1049
|
: { stage: 'result_missing', detail: null },
|
|
894
1050
|
};
|
|
1051
|
+
} finally {
|
|
1052
|
+
sandbox.detach();
|
|
895
1053
|
}
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
diagnosis: {
|
|
900
|
-
stage: 'sandbox_missing',
|
|
901
|
-
detail: 'Sandbox was not found in the launch-pinned Modal app.',
|
|
902
|
-
},
|
|
903
|
-
};
|
|
904
|
-
})(),
|
|
1054
|
+
}),
|
|
1055
|
+
// An auth token refresh is shared and keeps running, so do not wait on
|
|
1056
|
+
// whatever the abort could not cancel.
|
|
905
1057
|
new Promise<never>((_resolve, reject) => {
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
);
|
|
912
|
-
}, MODAL_DETACHED_INSPECTION_TIMEOUT_MS);
|
|
1058
|
+
deadline.signal.addEventListener(
|
|
1059
|
+
'abort',
|
|
1060
|
+
() => reject(deadline.signal.reason),
|
|
1061
|
+
{ once: true },
|
|
1062
|
+
);
|
|
913
1063
|
}),
|
|
914
1064
|
]);
|
|
915
1065
|
} catch (error) {
|
|
@@ -927,7 +1077,7 @@ export async function inspectDetachedModalRunner(input: {
|
|
|
927
1077
|
},
|
|
928
1078
|
};
|
|
929
1079
|
} finally {
|
|
930
|
-
|
|
1080
|
+
clearTimeout(timer);
|
|
931
1081
|
}
|
|
932
1082
|
}
|
|
933
1083
|
|
|
@@ -938,20 +1088,63 @@ export async function readDetachedModalRuntimeCompletion(input: {
|
|
|
938
1088
|
}): Promise<number | null> {
|
|
939
1089
|
const expectedAppId = input.expectedAppId?.trim() || null;
|
|
940
1090
|
if (!expectedAppId) return null;
|
|
1091
|
+
// A read past its deadline keeps running, so a Modal that never answers
|
|
1092
|
+
// would otherwise gather one per settlement. The marker is only telemetry.
|
|
1093
|
+
if (
|
|
1094
|
+
modalRuntimeCompletionReadsOutstanding >= MODAL_RUNTIME_COMPLETION_READS_MAX
|
|
1095
|
+
) {
|
|
1096
|
+
console.warn('[play-runner.modal.runtime_completion_marker_unavailable]', {
|
|
1097
|
+
sandboxId: input.sandboxId,
|
|
1098
|
+
expectedAppId,
|
|
1099
|
+
error: `${modalRuntimeCompletionReadsOutstanding} earlier reads have not answered.`,
|
|
1100
|
+
});
|
|
1101
|
+
return null;
|
|
1102
|
+
}
|
|
1103
|
+
modalRuntimeCompletionReadsOutstanding += 1;
|
|
1104
|
+
const read = readModalRuntimeCompletionMarker(input, expectedAppId).finally(
|
|
1105
|
+
() => {
|
|
1106
|
+
modalRuntimeCompletionReadsOutstanding -= 1;
|
|
1107
|
+
},
|
|
1108
|
+
);
|
|
1109
|
+
// Terminal settlement awaits this read. Modal's calls have no RPC deadline
|
|
1110
|
+
// and retry throttling without limit, so settle without the marker rather
|
|
1111
|
+
// than leave a finished run `running`. The read cannot be cancelled.
|
|
1112
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
1113
|
+
return await Promise.race([
|
|
1114
|
+
read,
|
|
1115
|
+
new Promise<null>((resolve) => {
|
|
1116
|
+
timer = setTimeout(() => {
|
|
1117
|
+
console.warn(
|
|
1118
|
+
'[play-runner.modal.runtime_completion_marker_unavailable]',
|
|
1119
|
+
{
|
|
1120
|
+
sandboxId: input.sandboxId,
|
|
1121
|
+
expectedAppId,
|
|
1122
|
+
error: `No answer within ${MODAL_DETACHED_INSPECTION_TIMEOUT_MS}ms.`,
|
|
1123
|
+
},
|
|
1124
|
+
);
|
|
1125
|
+
resolve(null);
|
|
1126
|
+
}, MODAL_DETACHED_INSPECTION_TIMEOUT_MS);
|
|
1127
|
+
}),
|
|
1128
|
+
]).finally(() => clearTimeout(timer));
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
async function readModalRuntimeCompletionMarker(
|
|
1132
|
+
input: { sandboxId: string; runtimeCompletedPath: string },
|
|
1133
|
+
expectedAppId: string,
|
|
1134
|
+
): Promise<number | null> {
|
|
1135
|
+
let sandbox: ModalSandbox | undefined;
|
|
941
1136
|
try {
|
|
942
1137
|
const { client } = await loadModalClientConfig();
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
}
|
|
954
|
-
return null;
|
|
1138
|
+
sandbox = await client.sandboxes.fromId(input.sandboxId);
|
|
1139
|
+
// The marker went with a stopped sandbox. Check first: a file read of a
|
|
1140
|
+
// sandbox with no task yet can wait minutes inside the SDK.
|
|
1141
|
+
if ((await readModalSandboxState(sandbox)).kind !== 'running') return null;
|
|
1142
|
+
const marker = JSON.parse(
|
|
1143
|
+
await sandbox.filesystem.readText(input.runtimeCompletedPath),
|
|
1144
|
+
) as { at?: unknown };
|
|
1145
|
+
return typeof marker.at === 'number' && Number.isFinite(marker.at)
|
|
1146
|
+
? marker.at
|
|
1147
|
+
: null;
|
|
955
1148
|
} catch (error) {
|
|
956
1149
|
console.warn('[play-runner.modal.runtime_completion_marker_unavailable]', {
|
|
957
1150
|
sandboxId: input.sandboxId,
|
|
@@ -959,5 +1152,7 @@ export async function readDetachedModalRuntimeCompletion(input: {
|
|
|
959
1152
|
error: error instanceof Error ? error.message : String(error),
|
|
960
1153
|
});
|
|
961
1154
|
return null;
|
|
1155
|
+
} finally {
|
|
1156
|
+
sandbox?.detach();
|
|
962
1157
|
}
|
|
963
1158
|
}
|
|
@@ -32,6 +32,7 @@ export type RuntimeSandboxReconciliationAdapter = {
|
|
|
32
32
|
inspectDetachedRunner(
|
|
33
33
|
ref: RuntimeSandboxRef,
|
|
34
34
|
suspension: DetachedRunnerSuspension,
|
|
35
|
+
options?: RuntimeSandboxDetachedInspectionOptions,
|
|
35
36
|
): Promise<RuntimeSandboxDetachedRunnerInspection | null>;
|
|
36
37
|
readWorkCompletedAt(
|
|
37
38
|
ref: RuntimeSandboxRef,
|
|
@@ -44,6 +45,7 @@ export type RuntimeSandboxReconciliation = {
|
|
|
44
45
|
inspectDetachedRunner(
|
|
45
46
|
ref: RuntimeSandboxRef,
|
|
46
47
|
suspension: DetachedRunnerSuspension,
|
|
48
|
+
options?: RuntimeSandboxDetachedInspectionOptions,
|
|
47
49
|
): Promise<RuntimeSandboxDetachedRunnerInspection | null>;
|
|
48
50
|
readWorkCompletedAt(
|
|
49
51
|
ref: RuntimeSandboxRef,
|
|
@@ -57,11 +59,28 @@ export type RuntimeSandboxDetachedRunnerInspection = {
|
|
|
57
59
|
diagnosis: { stage: string; detail: string | null };
|
|
58
60
|
};
|
|
59
61
|
|
|
62
|
+
export type RuntimeSandboxDetachedInspectionOptions = {
|
|
63
|
+
/**
|
|
64
|
+
* Prove only whether the sandbox itself has ended. A runner's captured output
|
|
65
|
+
* grows with customer logs, so a small fixed controller must never load it,
|
|
66
|
+
* and an ended sandbox has no files left to read. A sandbox that has not
|
|
67
|
+
* ended stays unproven here, and its parked attempt can still salvage it.
|
|
68
|
+
*/
|
|
69
|
+
skipCapturedOutput?: boolean;
|
|
70
|
+
};
|
|
71
|
+
|
|
60
72
|
export type RuntimeSandboxDeleteOutcome =
|
|
61
73
|
| {
|
|
62
74
|
kind: 'deleted' | 'already_absent';
|
|
63
75
|
routingDomain: string | null;
|
|
64
76
|
}
|
|
77
|
+
| {
|
|
78
|
+
kind: 'delete_pending';
|
|
79
|
+
routingDomain: string | null;
|
|
80
|
+
code: string;
|
|
81
|
+
detail: string;
|
|
82
|
+
deleteAccepted: boolean;
|
|
83
|
+
}
|
|
65
84
|
| {
|
|
66
85
|
kind: 'timed_out' | 'rate_limited' | 'failed';
|
|
67
86
|
routingDomain: string | null;
|
|
@@ -116,8 +135,8 @@ export function createRuntimeSandboxReconciliation(input: {
|
|
|
116
135
|
};
|
|
117
136
|
return {
|
|
118
137
|
delete: (ref) => resolve(ref).delete(ref),
|
|
119
|
-
inspectDetachedRunner: (ref, suspension) =>
|
|
120
|
-
resolve(ref).inspectDetachedRunner(ref, suspension),
|
|
138
|
+
inspectDetachedRunner: (ref, suspension, ...options) =>
|
|
139
|
+
resolve(ref).inspectDetachedRunner(ref, suspension, ...options),
|
|
121
140
|
readWorkCompletedAt: (ref, path) =>
|
|
122
141
|
resolve(ref).readWorkCompletedAt(ref, path),
|
|
123
142
|
};
|
|
@@ -205,7 +224,7 @@ export const defaultRuntimeSandboxReconciliation =
|
|
|
205
224
|
routingDomain: outcome.organizationId,
|
|
206
225
|
};
|
|
207
226
|
},
|
|
208
|
-
inspectDetachedRunner: (ref, suspension) =>
|
|
227
|
+
inspectDetachedRunner: (ref, suspension, options) =>
|
|
209
228
|
inspectDetachedDaytonaRunner({
|
|
210
229
|
sandboxId: ref.resourceId,
|
|
211
230
|
sessionId: suspension.sessionId,
|
|
@@ -213,6 +232,9 @@ export const defaultRuntimeSandboxReconciliation =
|
|
|
213
232
|
outputPath: suspension.outputPath,
|
|
214
233
|
exitCodePath: suspension.exitCodePath,
|
|
215
234
|
expectedOrganizationId: ref.routingDomain,
|
|
235
|
+
...(options?.skipCapturedOutput
|
|
236
|
+
? { skipCapturedOutput: true }
|
|
237
|
+
: {}),
|
|
216
238
|
}),
|
|
217
239
|
readWorkCompletedAt: (ref, path) =>
|
|
218
240
|
readDetachedDaytonaRuntimeCompletion({
|
|
@@ -233,12 +255,15 @@ export const defaultRuntimeSandboxReconciliation =
|
|
|
233
255
|
routingDomain: outcome.appId,
|
|
234
256
|
};
|
|
235
257
|
},
|
|
236
|
-
inspectDetachedRunner: (ref, suspension) =>
|
|
258
|
+
inspectDetachedRunner: (ref, suspension, options) =>
|
|
237
259
|
inspectDetachedModalRunner({
|
|
238
260
|
sandboxId: ref.resourceId,
|
|
239
261
|
outputPath: suspension.outputPath,
|
|
240
262
|
exitCodePath: suspension.exitCodePath,
|
|
241
263
|
expectedAppId: ref.routingDomain,
|
|
264
|
+
...(options?.skipCapturedOutput
|
|
265
|
+
? { skipCapturedOutput: true }
|
|
266
|
+
: {}),
|
|
242
267
|
}),
|
|
243
268
|
readWorkCompletedAt: (ref, path) =>
|
|
244
269
|
readDetachedModalRuntimeCompletion({
|
package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/sandbox-create-outcome.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type SandboxCreateOutcome = 'succeeded' | 'failed' | 'unknown';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* One line for each create request that reached a provider, read by the
|
|
5
|
+
* provider outage alert. Log it only where a request was really sent: a run held
|
|
6
|
+
* behind the open Modal circuit makes no request, and account reads prove
|
|
7
|
+
* nothing, since Modal reported no limit on Oct 31 while refusing a real create.
|
|
8
|
+
* `unknown` means the request outlived its client deadline and may still land.
|
|
9
|
+
*/
|
|
10
|
+
export function logSandboxCreateOutcome(input: {
|
|
11
|
+
provider: 'daytona' | 'modal';
|
|
12
|
+
outcome: SandboxCreateOutcome;
|
|
13
|
+
runId: string | null | undefined;
|
|
14
|
+
reason?: string | null;
|
|
15
|
+
}): void {
|
|
16
|
+
console.info('[runtime.sandbox.create_outcome]', {
|
|
17
|
+
event: 'runtime.sandbox.create_outcome',
|
|
18
|
+
provider: input.provider,
|
|
19
|
+
outcome: input.outcome,
|
|
20
|
+
runId: input.runId ?? null,
|
|
21
|
+
reason: input.reason ?? null,
|
|
22
|
+
runtimeEnvironment:
|
|
23
|
+
process.env.DEEPLINE_RUNTIME_ENVIRONMENT === 'preview'
|
|
24
|
+
? 'preview'
|
|
25
|
+
: 'production',
|
|
26
|
+
});
|
|
27
|
+
}
|
|
@@ -46,6 +46,17 @@ export type PlayRunnerRuntimeResource = {
|
|
|
46
46
|
sandboxCapacityLeaseId?: string;
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
+
/** Exact durable owner identity required before reconciling an ambiguous
|
|
50
|
+
* Daytona create by deleting the sandbox it produced. */
|
|
51
|
+
export type PlayRunnerDaytonaCleanupIntent = {
|
|
52
|
+
leaseId: string;
|
|
53
|
+
providerOperationToken: string;
|
|
54
|
+
orgId: string;
|
|
55
|
+
runId: string;
|
|
56
|
+
sandboxId: string;
|
|
57
|
+
routingDomain: string;
|
|
58
|
+
};
|
|
59
|
+
|
|
49
60
|
/**
|
|
50
61
|
* Durable identity for a Modal create that can outlive the caller's timeout.
|
|
51
62
|
* These fields are only provider routing and correlation data; payloads,
|
|
@@ -183,9 +194,19 @@ export interface PlayRunnerCallbacks {
|
|
|
183
194
|
reserveSandboxCapacity?: (
|
|
184
195
|
provider: 'daytona' | 'modal' | 'agentcore_runtime',
|
|
185
196
|
providerAttempt?: number,
|
|
186
|
-
) => Promise<{
|
|
197
|
+
) => Promise<{
|
|
198
|
+
leaseId: string;
|
|
199
|
+
providerOperationToken: string | null;
|
|
200
|
+
resumeExistingProviderOperation?: boolean;
|
|
201
|
+
resumePendingDelete?: boolean;
|
|
202
|
+
existingProviderOperationAgeMs?: number;
|
|
203
|
+
}>;
|
|
187
204
|
/** Release an unbound reservation when provider create never produced a resource. */
|
|
188
205
|
releaseSandboxCapacity?: (leaseId: string) => Promise<void>;
|
|
206
|
+
/** Persist a cleanup obligation before removing an ambiguously-created sandbox. */
|
|
207
|
+
recordDaytonaCleanupIntent?: (
|
|
208
|
+
intent: PlayRunnerDaytonaCleanupIntent,
|
|
209
|
+
) => Promise<void>;
|
|
189
210
|
/**
|
|
190
211
|
* Scheduler-owned dependency circuit admission. A false result means no
|
|
191
212
|
* provider call is safe to make yet; the backend must return/throw a typed
|