withruntime 0.8.4 → 0.10.0

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 (132) hide show
  1. package/BLAXEL.md +4 -4
  2. package/COMPATIBILITY.md +145 -0
  3. package/DAYTONA.md +13 -7
  4. package/E2B.md +34 -20
  5. package/README.md +22 -11
  6. package/README.src.md +22 -11
  7. package/VERCEL.md +13 -3
  8. package/compatibility-lock.json +357 -0
  9. package/dist/ai-harness/index.js +2 -2
  10. package/dist/api-defaults.d.ts +17 -0
  11. package/dist/api-defaults.js +22 -0
  12. package/dist/blaxel/errors.js +1 -1
  13. package/dist/blaxel/lookup.d.ts +3 -2
  14. package/dist/blaxel/lookup.js +3 -2
  15. package/dist/blaxel/pagination.d.ts +2 -2
  16. package/dist/blaxel/pagination.js +45 -17
  17. package/dist/blaxel/preview.d.ts +3 -2
  18. package/dist/blaxel/preview.js +16 -14
  19. package/dist/blaxel/process.d.ts +1 -1
  20. package/dist/blaxel/process.js +66 -11
  21. package/dist/blaxel/sandbox.d.ts +2 -0
  22. package/dist/blaxel/sandbox.js +2 -0
  23. package/dist/blaxel/snapshot.js +3 -5
  24. package/dist/cli-words.d.ts +27 -0
  25. package/dist/cli-words.js +135 -0
  26. package/dist/cli.d.ts +2 -0
  27. package/dist/cli.js +351 -85
  28. package/dist/client.d.ts +33 -4
  29. package/dist/client.js +47 -12
  30. package/dist/cloudflare/identity.d.ts +7 -0
  31. package/dist/cloudflare/identity.js +13 -0
  32. package/dist/cloudflare/index.d.ts +303 -0
  33. package/dist/cloudflare/index.js +592 -0
  34. package/dist/cloudflare/worker.d.ts +419 -0
  35. package/dist/cloudflare/worker.js +447 -0
  36. package/dist/codesandbox/guest-service.d.ts +31 -0
  37. package/dist/codesandbox/guest-service.js +490 -0
  38. package/dist/codesandbox/index.d.ts +386 -0
  39. package/dist/codesandbox/index.js +1347 -0
  40. package/dist/compat/core.d.ts +40 -0
  41. package/dist/compat/core.js +238 -0
  42. package/dist/compat/files.d.ts +26 -0
  43. package/dist/compat/files.js +133 -0
  44. package/dist/compat/shell.d.ts +4 -0
  45. package/dist/compat/shell.js +165 -0
  46. package/dist/credentials.d.ts +6 -1
  47. package/dist/credentials.js +107 -38
  48. package/dist/daytona/context.js +2 -1
  49. package/dist/daytona/daytona.js +11 -4
  50. package/dist/daytona/filesystem.d.ts +17 -4
  51. package/dist/daytona/filesystem.js +121 -38
  52. package/dist/daytona/index.d.ts +1 -1
  53. package/dist/daytona/process.d.ts +1 -1
  54. package/dist/daytona/process.js +27 -4
  55. package/dist/daytona/sandbox.d.ts +1 -1
  56. package/dist/daytona/sandbox.js +16 -7
  57. package/dist/e2b/client.js +1 -1
  58. package/dist/e2b/code-interpreter.d.ts +4 -5
  59. package/dist/e2b/code-interpreter.js +54 -56
  60. package/dist/e2b/commands.d.ts +35 -12
  61. package/dist/e2b/commands.js +169 -73
  62. package/dist/e2b/errors.js +1 -1
  63. package/dist/e2b/filesystem.d.ts +8 -6
  64. package/dist/e2b/filesystem.js +127 -28
  65. package/dist/e2b/index.d.ts +1 -0
  66. package/dist/e2b/index.js +1 -0
  67. package/dist/e2b/pty.d.ts +24 -0
  68. package/dist/e2b/pty.js +80 -0
  69. package/dist/e2b/sandbox.d.ts +6 -4
  70. package/dist/e2b/sandbox.js +59 -25
  71. package/dist/errors.d.ts +8 -0
  72. package/dist/errors.js +15 -2
  73. package/dist/file-source.d.ts +16 -0
  74. package/dist/file-source.js +162 -0
  75. package/dist/freestyle/index.d.ts +309 -0
  76. package/dist/freestyle/index.js +343 -0
  77. package/dist/index.d.ts +3 -1
  78. package/dist/login.js +16 -10
  79. package/dist/mcp.js +2 -2
  80. package/dist/modal/index.d.ts +205 -0
  81. package/dist/modal/index.js +486 -0
  82. package/dist/network-cli.js +112 -44
  83. package/dist/openai-agents/index.js +18 -71
  84. package/dist/page.d.ts +1 -1
  85. package/dist/page.js +2 -2
  86. package/dist/products/audit.d.ts +3 -0
  87. package/dist/products/index.d.ts +14 -0
  88. package/dist/products/index.js +12 -0
  89. package/dist/products/interpreter.d.ts +11 -4
  90. package/dist/products/interpreter.js +33 -9
  91. package/dist/products/jobs.js +3 -2
  92. package/dist/products/limits.d.ts +10 -0
  93. package/dist/products/observability.d.ts +44 -0
  94. package/dist/products/observability.js +6 -0
  95. package/dist/products/previews.d.ts +18 -4
  96. package/dist/products/previews.js +14 -5
  97. package/dist/products/tailscale.d.ts +57 -0
  98. package/dist/products/tailscale.js +17 -0
  99. package/dist/products/volumes.d.ts +42 -0
  100. package/dist/products/volumes.js +36 -0
  101. package/dist/products/watch.d.ts +25 -4
  102. package/dist/products/watch.js +132 -18
  103. package/dist/proxy.js +3 -1
  104. package/dist/runloop/index.d.ts +326 -0
  105. package/dist/runloop/index.js +535 -0
  106. package/dist/runloop/pagination.d.ts +46 -0
  107. package/dist/runloop/pagination.js +82 -0
  108. package/dist/runloop/snapshots.d.ts +52 -0
  109. package/dist/runloop/snapshots.js +244 -0
  110. package/dist/sandbox.d.ts +76 -16
  111. package/dist/sandbox.js +696 -135
  112. package/dist/snapshots.d.ts +20 -5
  113. package/dist/snapshots.js +11 -1
  114. package/dist/sprites/index.d.ts +251 -0
  115. package/dist/sprites/index.js +588 -0
  116. package/dist/tar.d.ts +10 -1
  117. package/dist/tar.js +311 -35
  118. package/dist/tools/index.js +2 -1
  119. package/dist/transport.d.ts +23 -8
  120. package/dist/transport.js +247 -127
  121. package/dist/types.d.ts +52 -3
  122. package/dist/vercel/command.d.ts +1 -1
  123. package/dist/vercel/command.js +15 -3
  124. package/dist/vercel/errors.d.ts +2 -2
  125. package/dist/vercel/errors.js +19 -2
  126. package/dist/vercel/filesystem.d.ts +21 -18
  127. package/dist/vercel/filesystem.js +95 -48
  128. package/dist/vercel/sandbox.d.ts +8 -8
  129. package/dist/vercel/sandbox.js +159 -64
  130. package/dist/vercel/snapshot.d.ts +3 -2
  131. package/dist/vercel/snapshot.js +9 -5
  132. package/package.json +46 -3
package/VERCEL.md CHANGED
@@ -16,9 +16,9 @@ from withruntime.vercel import sandbox # was: from vercel import sandbox
16
16
  from withruntime.vercel.sandbox import sync as sandbox # was: from vercel.sandbox import sync as sandbox
17
17
  ```
18
18
 
19
- The mapping was written against `@vercel/sandbox` 3.5.0 and `vercel-sandbox`
19
+ The mapping was written against `@vercel/sandbox` 3.5.1 and `vercel-sandbox`
20
20
  0.7.0 on PyPI (the `vercel.sandbox` module of `vercel` 0.11.4), checked
21
- 23 September 2026.
21
+ 30 September 2026.
22
22
 
23
23
  ## Keys
24
24
 
@@ -73,7 +73,7 @@ are ignored.
73
73
  | `domain(port)`, `update({ ports })` | The public preview of that port; ports added or removed. |
74
74
  | `stop()`, `delete()`, `extendTimeout(ms)` | `pause` (persistent) or `stop`; `stop`; `extend`. |
75
75
  | `update({ timeout, networkPolicy, snapshotExpiration })` | `extend` (later only), network rules, retention. |
76
- | `snapshot()`, `Snapshot.get`, `Snapshot.list`, `snapshot.delete()` | A Runtime snapshot (files, memory and processes), then the sandbox stops, as in Vercel; `snapshots.get`, `list`, `delete`. |
76
+ | `snapshot()`, `Snapshot.get`, `Snapshot.list`, `snapshot.delete()` | A verified disk-only capture, then the source stops; restored snapshots start fresh processes; `snapshots.get`, `list`, `delete`. |
77
77
  | Error classes | `APIError` with a `response` whose status is Runtime's and `json` of `{ error: { code, message } }`; also `code`, `hint` and `requestId`. |
78
78
  | Python: `create_sandbox`, `run_process`, `create_process`, `box.fs` | The same mapping; operations await or work as context managers, which stop and by default destroy the sandbox; readers iterate by line. |
79
79
 
@@ -98,6 +98,16 @@ Each of these throws `NotSupportedError` before anything happens. Its
98
98
  | `Drive`, `SandboxUser`, `defineSandboxProxy` | Runtime volumes; `sudo`; `sandbox.withruntime.previews`. |
99
99
  | Listing by time, prefix or cursor (JavaScript) | List them all and filter the result yourself. (Python applies a name prefix and newest-first order itself.) |
100
100
 
101
+ Explicit snapshots require the released native disk-capture capability; a server
102
+ that does not confirm disk-only capture is refused. If capture succeeds but the
103
+ source cannot finish stopping, the error retains `snapshotId` and
104
+ `sourceSandboxId` so the saved filesystem remains recoverable. JavaScript exposes
105
+ them in `error.json.error.details` for API errors and directly on other errors;
106
+ Python exposes them in `error.data` for API errors and directly on other errors.
107
+ `snapshot_source_stop_timeout` means the source is still stopping after its wait;
108
+ a failed stop request keeps its original error code. These contracts remain
109
+ partial; controlled package comparisons do not prove hosted restoration.
110
+
101
111
  Some differences are not refusals:
102
112
 
103
113
  - A persistent sandbox keeps its memory and processes as well as its files
@@ -0,0 +1,357 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "checkedAt": "2026-09-29",
4
+ "providers": [
5
+ {
6
+ "id": "e2b",
7
+ "status": "partial",
8
+ "upstreams": [
9
+ {
10
+ "registry": "npm",
11
+ "name": "e2b",
12
+ "version": "2.51.0",
13
+ "artifacts": {
14
+ "2.51.0": "sha512-P+50lx1nOYpgCFyE1xuz6JVN/TqJivMUiH7v+RW0CUSfb4+NCu8IkC5KruT2sNPgp6aexddQQ77+OZKGpZZJ+Q=="
15
+ },
16
+ "latestReview": {
17
+ "version": "2.52.0",
18
+ "artifacts": {
19
+ "2.52.0": "sha512-TmUZlAvQq8BbguodpA+BBdawR/x5uILMQtHcLkdaLUqevsDjDdh46IYYU8ZRYKsQ4OhWr4xhsFIPSg1kgf+O0w=="
20
+ },
21
+ "reviewedAt": "2026-10-01",
22
+ "disposition": "held-for-sdk-qualification",
23
+ "evidence": {
24
+ "sourceUrls": [
25
+ "https://registry.npmjs.org/e2b/2.52.0",
26
+ "https://registry.npmjs.org/e2b/-/e2b-2.52.0.tgz"
27
+ ],
28
+ "artifactSha256": {
29
+ "2.52.0": "facbc53fa42757d94aa2be3433d779c7ab6b0afc780d4821a12a6d6815848c8e"
30
+ },
31
+ "changes": [
32
+ "dist/index.d.ts/index.mjs: HTTP1.1/2 selection, E2B_HTTP_VERSION, retry502/503 and connection failures, fork integer count 1..20, Dockerignore matching/precedence and invalid-pattern behavior changed. package.json changes protobuf/chalk/openapi-fetch floors. Installed transport/retry/fork/filesystem consumers not qualified; supported 2.51.0 unchanged.",
33
+ "Source digest dist/index.d.ts: 304acc9c8bbec8aeb69296719eb34986f987256e758aa7e220b551b9a7dcbd30 -> fa2e6eb09b6c6d3489056ee948248812e8879a23b6865561e5152f243bf6ca40.",
34
+ "Source digest dist/index.mjs: b75feeedb6543fee003533270b0f07fc1a9eb40315dfc0c44510e2dd8854b896 -> 343a41249ea8d48fe0a70fc986066d3ef97b6da2b71267211d21f77036efafea.",
35
+ "Source digest package.json: a2c759c4681b91b824aea7919f4661e498ec0e0b68d6cc333f4967f7b2b63f7b -> c5b699f80831b621178c83ea477d096bc1167e0083b6ba7a51d17f564207255f."
36
+ ]
37
+ }
38
+ }
39
+ },
40
+ {
41
+ "registry": "npm",
42
+ "name": "@e2b/code-interpreter",
43
+ "version": "2.8.0",
44
+ "artifacts": {
45
+ "2.8.0": "sha512-tWFi8IJYV3V6jOVfQ8V5PkzockrYP+ndWB/jKiJvRATTmNAy8+S/7S+iSh2Lb2Hrul869G2adRiN2xW8peJTig=="
46
+ }
47
+ },
48
+ {
49
+ "registry": "pypi",
50
+ "name": "e2b",
51
+ "version": "2.51.0",
52
+ "artifacts": {
53
+ "e2b-2.51.0-py3-none-any.whl": "sha256-951d0fd069f017e760b338a435bdb83589b4bfb9574fc5203a7f777e9cb994c2",
54
+ "e2b-2.51.0.tar.gz": "sha256-902ee861b30c8ec3e46e7f84db8c993f30695872c7b4490efaad1627ec6e08ba"
55
+ },
56
+ "latestReview": {
57
+ "version": "2.52.0",
58
+ "artifacts": {
59
+ "e2b-2.52.0-py3-none-any.whl": "sha256-6f4b5084b09986db43e99c7405bae6b14dc56984a69bbb1dc0687f1c71515cfb",
60
+ "e2b-2.52.0.tar.gz": "sha256-58c0042609513799341d4c1837e2581a4a5e73d3d62c9f1c57495c5e23eedee2"
61
+ },
62
+ "reviewedAt": "2026-10-01",
63
+ "disposition": "held-for-sdk-qualification",
64
+ "evidence": {
65
+ "sourceUrls": [
66
+ "https://pypi.org/pypi/e2b/2.52.0/json",
67
+ "https://files.pythonhosted.org/packages/53/71/1a01b7e4486b5962eaade7dba7026876a1b4569e49b464e82912d8801e38/e2b-2.52.0-py3-none-any.whl",
68
+ "https://files.pythonhosted.org/packages/3c/c4/560e7de54cece3573086f09d304e595729964aa18593b437125d9f8bd926/e2b-2.52.0.tar.gz"
69
+ ],
70
+ "artifactSha256": {
71
+ "e2b-2.52.0-py3-none-any.whl": "6f4b5084b09986db43e99c7405bae6b14dc56984a69bbb1dc0687f1c71515cfb",
72
+ "e2b-2.52.0.tar.gz": "58c0042609513799341d4c1837e2581a4a5e73d3d62c9f1c57495c5e23eedee2"
73
+ },
74
+ "changes": [
75
+ "e2b/connection_config.py/retry.py: HTTP1.1/2 selection and E2B_HTTP_VERSION; retries 502/503 and eligible network failures, excluding unsafe resource-creating replay. e2b/api clients replace pool shards with bounded least-in-flight shared pools, defaults 100 streams / 200 connections.",
76
+ "Fork count validation1..20 and template/dockerignore/fileIgnorePatterns matching/precedence changed. Installed sync/async transport/cleanup/retry/fork/filesystem consumers not qualified; supported 2.51.0 unchanged.",
77
+ "Source digest e2b/api/__init__.py: 00b09a79f25d01594c4b1ec5f14d3d0cc3ccc319958a2e1ca34ba91cdbf114b3 -> 640233a615a3c68752a2f2cecb1af919aebfc5e895bd4f09003aee61da38c7c0.",
78
+ "Source digest e2b/connection_config.py: 284aa3e7cc319432ca9147ddb7d9ab8cd315cf35283da7699eebe877375758a4 -> c165948133a2f174b5a490afa9502301d038d8097f91203b2c2174f451accf83.",
79
+ "Source digest e2b/retry.py: aa54aa8873fd44027a9c3ff790594d4583d2f415c0d3bd858566d2f0e15fa71f -> 40b1d7ea0732a721d77b31483e54f9f190e444cb798c54fc141856f52685e208.",
80
+ "Source digest e2b/template/dockerignore.py: None -> cba4ff9d7efa5ae987c4c0114770c114b5aefe2c18847e55d2bd811b9a1a088c."
81
+ ]
82
+ }
83
+ }
84
+ },
85
+ {
86
+ "registry": "pypi",
87
+ "name": "e2b-code-interpreter",
88
+ "version": "2.10.0",
89
+ "artifacts": {
90
+ "e2b_code_interpreter-2.10.0-py3-none-any.whl": "sha256-6ba776122086261875bc6033ef2dc42ac6b6e22cefdffdfd19d30e93bb09786f",
91
+ "e2b_code_interpreter-2.10.0.tar.gz": "sha256-57fb7f9b9ad99ebbdf407619786fdb84e31537c2fbc8358c394aa0f0cbc1af28"
92
+ },
93
+ "latestReview": {
94
+ "version": "2.10.1",
95
+ "artifacts": {
96
+ "e2b_code_interpreter-2.10.1-py3-none-any.whl": "sha256-f4c9732699ee4b1c289acedac8bff66fccecc6ab374bf0b4ef88d5ad063e333d",
97
+ "e2b_code_interpreter-2.10.1.tar.gz": "sha256-94e504667788c6cbb175e5deaf1f68e8df474b670343fe1d72e2496b49d5a666"
98
+ },
99
+ "reviewedAt": "2026-10-01",
100
+ "disposition": "held-for-sdk-qualification",
101
+ "evidence": {
102
+ "sourceUrls": [
103
+ "https://pypi.org/pypi/e2b-code-interpreter/2.10.1/json",
104
+ "https://files.pythonhosted.org/packages/27/1f/0f9a4c4d9669afd5389e91bd96099a8eb1d1a32f9c67871cc56c4a8556b7/e2b_code_interpreter-2.10.1-py3-none-any.whl",
105
+ "https://files.pythonhosted.org/packages/38/e6/b01e60524e7e4d2e8ce634b3be6d00fe09c606f3d24a448b4a5c087d3bda/e2b_code_interpreter-2.10.1.tar.gz"
106
+ ],
107
+ "artifactSha256": {
108
+ "e2b_code_interpreter-2.10.1-py3-none-any.whl": "f4c9732699ee4b1c289acedac8bff66fccecc6ab374bf0b4ef88d5ad063e333d",
109
+ "e2b_code_interpreter-2.10.1.tar.gz": "94e504667788c6cbb175e5deaf1f68e8df474b670343fe1d72e2496b49d5a666"
110
+ },
111
+ "changes": [
112
+ "code_interpreter_{sync,async}.py: Jupyter get_transport argument changes from http2=False to http_version=\"1.1\". pyproject.toml and PKG-INFO raise e2b floor to 2.52.0,<3.0.0. Installed Jupyter cancellation/base SDK consumers not qualified; supported 2.10.0 unchanged.",
113
+ "Source digest e2b_code_interpreter/code_interpreter_sync.py: 298d832fe93e488300ac3174f2de590cc16d3563bdcc4ec31439d28265b66426 -> a88ff6a0df5163bceea545d077be090dbc78c96e48354e304677b02799eec17e.",
114
+ "Source digest pyproject.toml: 6c395fdf75ddc89acabb94fd0e419fc31317e6f3fa297894cbe7e766f090322c -> ef2b569a82f2e6edf722939ab27ca476a292886655c2af8f9e75eb9cae287941."
115
+ ]
116
+ }
117
+ }
118
+ }
119
+ ]
120
+ },
121
+ {
122
+ "id": "daytona",
123
+ "status": "partial",
124
+ "upstreams": [
125
+ {
126
+ "registry": "npm",
127
+ "name": "@daytona/sdk",
128
+ "version": "0.220.0",
129
+ "artifacts": {
130
+ "0.220.0": "sha512-PJio3vbDwRApzlsK6AGO7r4CHJcF9PI5DWuUW2yUnA2MVJSh/jotS0onKBv6boC5F+oboljTibUMxrwVPIrOlQ=="
131
+ }
132
+ },
133
+ {
134
+ "registry": "pypi",
135
+ "name": "daytona",
136
+ "version": "0.220.0",
137
+ "artifacts": {
138
+ "daytona-0.220.0-py3-none-any.whl": "sha256-5f71299eaf3a446e6569ada69919fc49997c1b2c587845057394aab886f113c8",
139
+ "daytona-0.220.0.tar.gz": "sha256-eda82eac9b3601e757b1dbe3ec2d966b46a9e3038b69ce44a0d90e01dac8417a"
140
+ }
141
+ },
142
+ {
143
+ "registry": "npm",
144
+ "name": "@daytona/api-client",
145
+ "version": "0.220.0",
146
+ "artifacts": {
147
+ "0.220.0": "sha512-XaMEtiQCaIHc3T7y3HUqx1A5eWSnd+FJvhpSHDwP3Snu9Nnhy4t+K2LHBWgJQn9dGtWXsdOsbB9K0BqpmFJtyA=="
148
+ }
149
+ },
150
+ {
151
+ "registry": "npm",
152
+ "name": "@daytona/toolbox-api-client",
153
+ "version": "0.220.0",
154
+ "artifacts": {
155
+ "0.220.0": "sha512-Kn94AOxhGQil0XygOOR26SaCkndE4dOtxYS0hLbqrTxcP3H1uq1HGFGSRkHFQNkaR8eL9QwFUPSMqd0Vr3A64A=="
156
+ }
157
+ },
158
+ {
159
+ "registry": "npm",
160
+ "name": "@daytona/analytics-api-client",
161
+ "version": "0.220.0",
162
+ "artifacts": {
163
+ "0.220.0": "sha512-3BGYILzjo2aFTJhLd6XBXlNEQBSo9Zr2Nj31OdX9o50fMRVUwVydF6ekIGkPGSLwskz6b6xxg5BSS+f9dbrxCQ=="
164
+ }
165
+ }
166
+ ]
167
+ },
168
+ {
169
+ "id": "vercel",
170
+ "status": "partial",
171
+ "upstreams": [
172
+ {
173
+ "registry": "npm",
174
+ "name": "@vercel/sandbox",
175
+ "version": "3.5.1",
176
+ "artifacts": {
177
+ "3.5.1": "sha512-VHItQtcv4FkSXET29b088p87MNPAIhRscF3ifrup2KkC8ix4hy4NpgCO9F3GI4yOsztgGtuV7bDx29Iufun2hQ=="
178
+ }
179
+ },
180
+ {
181
+ "registry": "pypi",
182
+ "name": "vercel",
183
+ "version": "0.11.4",
184
+ "artifacts": {
185
+ "vercel-0.11.4-py3-none-any.whl": "sha256-3ba3a0de2276a2b3daf590263082f6a82850dc77b35cf68f86a1e5bc9e83b6f1",
186
+ "vercel-0.11.4.tar.gz": "sha256-80038906615bf4182787af8354bce71b57d9fd5471a35ebca457d34ab5f50b2e"
187
+ }
188
+ },
189
+ {
190
+ "registry": "pypi",
191
+ "name": "vercel-sandbox",
192
+ "version": "0.7.0",
193
+ "artifacts": {
194
+ "vercel_sandbox-0.7.0-py3-none-any.whl": "sha256-f7eb897a1a5092fe8c38319ce803033b1a9ced8f414564a43a668432f91ffcd9",
195
+ "vercel_sandbox-0.7.0.tar.gz": "sha256-07d703790d0141dc75e0962baf35d666a6961bc1de913749137267a2550c81e2"
196
+ }
197
+ }
198
+ ]
199
+ },
200
+ {
201
+ "id": "blaxel",
202
+ "status": "partial",
203
+ "upstreams": [
204
+ {
205
+ "registry": "npm",
206
+ "name": "@blaxel/core",
207
+ "version": "0.3.25",
208
+ "artifacts": {
209
+ "0.3.25": "sha512-K6aGUyIpgrPnkpwMOI/U/gbZwveOMu1Am04pkawZQjkp7NUa/roG0HC6NJPBp3AVVJY3CQtkGSWpAJ2DV4ZKpw=="
210
+ }
211
+ },
212
+ {
213
+ "registry": "pypi",
214
+ "name": "blaxel",
215
+ "version": "0.4.13",
216
+ "artifacts": {
217
+ "blaxel-0.4.13-py3-none-any.whl": "sha256-b8817718ca63a2b31a5026f98c7191d5ed8f2f4c1aafc2d4aa57491a560a2146",
218
+ "blaxel-0.4.13.tar.gz": "sha256-a036256792e85238724b8bce38fb7c0b4f661fe4c3ac576258a8be1736ac8483"
219
+ }
220
+ }
221
+ ]
222
+ },
223
+ {
224
+ "id": "runloop",
225
+ "status": "partial",
226
+ "upstreams": [
227
+ {
228
+ "registry": "npm",
229
+ "name": "@runloop/api-client",
230
+ "version": "1.32.0",
231
+ "artifacts": {
232
+ "1.32.0": "sha512-aCNKjlGzLVEAFl8WA42LmgiYkdIkaocOlFK/cMGppijsM0AGS+1hkw/RxroQxyHlkIhjyRaqLv7m5ZNMGhks7Q=="
233
+ }
234
+ },
235
+ {
236
+ "registry": "pypi",
237
+ "name": "runloop-api-client",
238
+ "version": "1.32.0",
239
+ "artifacts": {
240
+ "runloop_api_client-1.32.0-py3-none-any.whl": "sha256-23c36910de7423f73aef91d4a963abea80a6b2f5b2df5bb8e439d788d5486cc7",
241
+ "runloop_api_client-1.32.0.tar.gz": "sha256-1f2077fb5a99b5ef30dbc1d96d47c1ca1d3f77895b9e186d985e47365fe85634"
242
+ }
243
+ }
244
+ ]
245
+ },
246
+ {
247
+ "id": "codesandbox",
248
+ "status": "partial",
249
+ "upstreams": [
250
+ {
251
+ "registry": "npm",
252
+ "name": "@codesandbox/sdk",
253
+ "version": "2.4.2",
254
+ "artifacts": {
255
+ "2.4.2": "sha512-pwz/+xNPLiCEvIYLxk2VJwiAFuy28V3J6FuO+xIB5U3AV/EylHlm77Lsi/WNYeXoSljIlaLLU7IemAjw3ojNfg=="
256
+ }
257
+ }
258
+ ]
259
+ },
260
+ {
261
+ "id": "sprites",
262
+ "status": "partial",
263
+ "upstreams": [
264
+ {
265
+ "registry": "npm",
266
+ "name": "@fly/sprites",
267
+ "version": "0.2.3",
268
+ "artifacts": {
269
+ "0.2.3": "sha512-LB3xmHpHLdVECTQej+Vyi/aFFTc/Otf8bZ8GwVe/Hhlx4kIFS0K+9O5B8ru8Llg+cEwvYmzyeV69vNZPpCt0fw=="
270
+ }
271
+ },
272
+ {
273
+ "registry": "pypi",
274
+ "name": "sprites-py",
275
+ "version": "0.7.1",
276
+ "artifacts": {
277
+ "sprites_py-0.7.1-py3-none-any.whl": "sha256-23774f8111c9a4fbb7007f8e305677734eb7616bebb6c668c394788399ff38a8",
278
+ "sprites_py-0.7.1.tar.gz": "sha256-c45596f3994376eb25dd7c4f988b3a6893dd8218502bacd7eedf2b20888d8456"
279
+ }
280
+ }
281
+ ]
282
+ },
283
+ {
284
+ "id": "freestyle",
285
+ "status": "partial",
286
+ "upstreams": [
287
+ {
288
+ "registry": "npm",
289
+ "name": "freestyle",
290
+ "version": "0.2.16",
291
+ "artifacts": {
292
+ "0.2.16": "sha512-8pC7lh/R2PDanbs9Noc1Q7YlPl8Be8hHaQA/rpwFmELrcLTUAuCuxpoZ1Xm+7fuxqhJqJzO83bTTeLcSUoJ9SA=="
293
+ }
294
+ }
295
+ ]
296
+ },
297
+ {
298
+ "id": "prime",
299
+ "status": "partial",
300
+ "upstreams": [
301
+ {
302
+ "registry": "pypi",
303
+ "name": "prime-sandboxes",
304
+ "version": "0.4.1",
305
+ "artifacts": {
306
+ "prime_sandboxes-0.4.1-py3-none-any.whl": "sha256-1a1bb96afacc66d690815be82c0b7af180ea141421b7d180b4a0adbada4f38f0",
307
+ "prime_sandboxes-0.4.1.tar.gz": "sha256-53f7577dc9070e3b8e30db360f9e3cce3bcc35f8765b26f24f64dbc3c7763b06"
308
+ }
309
+ }
310
+ ]
311
+ },
312
+ {
313
+ "id": "modal",
314
+ "status": "partial",
315
+ "upstreams": [
316
+ {
317
+ "registry": "npm",
318
+ "name": "modal",
319
+ "version": "0.11.0",
320
+ "artifacts": {
321
+ "0.11.0": "sha512-Kvy2nejPkice2FI82p5e8TJrFDy0BaSYZjJVmvnTnu51bOH9Ok7IRtp8NavBQqMuXhbpbj6gRULwxsjNkweF6A=="
322
+ }
323
+ },
324
+ {
325
+ "registry": "pypi",
326
+ "name": "modal",
327
+ "version": "1.6.0",
328
+ "artifacts": {
329
+ "modal-1.6.0-py3-none-any.whl": "sha256-2f5981ba656570ad96379d29f0ddff876880708c84966024ce130e9e1794fa68",
330
+ "modal-1.6.0.tar.gz": "sha256-c5dd551b5e0a283f3c764476c0a4ebe5bdef1e4a69432fa27e1b1ad8ca5e0817"
331
+ }
332
+ }
333
+ ]
334
+ },
335
+ {
336
+ "id": "cloudflare",
337
+ "status": "partial",
338
+ "upstreams": [
339
+ {
340
+ "registry": "npm",
341
+ "name": "@cloudflare/sandbox",
342
+ "version": "0.12.10",
343
+ "artifacts": {
344
+ "0.12.10": "sha512-245s6xEdR1v0Jti0YYd8ORWcTG/f/ksjJfpubvnbky0KxFC/ZDOpbpNKdtyiRBYZqmJGtEncYW7Cwge47tDrpg=="
345
+ },
346
+ "unsupported": {
347
+ "version": "1.0.0",
348
+ "artifacts": {
349
+ "1.0.0": "sha512-+TZVuCey6OBDTvPLWisq4Ie7/R5Zy3zFyYOFCNRpdEIyQsKq3xwzpctonE43DfZ+wYZvvu6QYpR138PayDjF+A=="
350
+ },
351
+ "reason": "1.0 removes getSandbox, the Sandbox class, exec, processes, sessions and preview proxying and keeps only Files, S3Mount and DirectoryBackup for the caller's own Durable Object; withruntime/cloudflare implements the 0.x API"
352
+ }
353
+ }
354
+ ]
355
+ }
356
+ ]
357
+ }
@@ -19,6 +19,7 @@
19
19
  * token. The key comes from RUNTIME_API_KEY or this machine's `runtime login`.
20
20
  * Needs `@ai-sdk/harness` 1.x beside this package. */
21
21
  import { HarnessCapabilityUnsupportedError, HarnessSandboxAuthenticationError, } from "@ai-sdk/harness";
22
+ import { AI_HARNESS_COMMAND_TIMEOUT_MS } from "../api-defaults.js";
22
23
  import { Runtime } from "../client.js";
23
24
  import { AuthenticationError, NotFoundError, PermissionDeniedError, RuntimeError, } from "../errors.js";
24
25
  export const PROVIDER_ID = "runtime-sandbox";
@@ -27,7 +28,6 @@ export const PREVIEW_TOKEN_HEADER = "x-runtime-preview-token";
27
28
  const TOKEN_QUERY = "runtime_preview_token";
28
29
  const SESSION_NAME_PREFIX = "ai-harness-";
29
30
  const MAX_COMMAND_MS = 86_400_000;
30
- const DEFAULT_COMMAND_MS = 3_600_000;
31
31
  /** Exit codes for a command that ended without one, as coreutils `timeout` and SIGKILL give. */
32
32
  const TIMED_OUT_EXIT = 124;
33
33
  const KILLED_EXIT = 137;
@@ -161,7 +161,7 @@ export class RuntimeSandboxSession {
161
161
  ? {}
162
162
  : { cwd: this.#path(options.workingDirectory) }),
163
163
  ...(Object.keys(env).length ? { env } : {}),
164
- timeoutMs: Math.min(MAX_COMMAND_MS, options.timeoutMs ?? this.settings.commandTimeoutMs ?? DEFAULT_COMMAND_MS),
164
+ timeoutMs: Math.min(MAX_COMMAND_MS, options.timeoutMs ?? this.settings.commandTimeoutMs ?? AI_HARNESS_COMMAND_TIMEOUT_MS),
165
165
  };
166
166
  }
167
167
  /** Runs `command` under `bash -c` and returns once it exits, with all of
@@ -0,0 +1,17 @@
1
+ /** A server-side wait for a state (`GET /v1/sandboxes/{id}?waitFor=`). */
2
+ export declare const WAIT_FOR_TIMEOUT_SECONDS = 60;
3
+ /** A streamed exec's command limit when none is given: the API's longest. */
4
+ export declare const STREAMED_EXEC_TIMEOUT_MS = 86400000;
5
+ /** The lease keepAlive keeps ahead of now, and so the most it extends by. */
6
+ export declare const KEEP_ALIVE_MARGIN_SECONDS = 600;
7
+ /** A webhook watch runs until stopped. */
8
+ export declare const WEBHOOK_WATCH_TIMEOUT_MS = 0;
9
+ /** A job run's limit, and the time added to it for its sandbox to start. */
10
+ export declare const JOB_TIMEOUT_SECONDS = 1800;
11
+ export declare const JOB_START_SECONDS = 60;
12
+ /** A command the framework-free tools run without a timeout of its own. */
13
+ export declare const TOOL_EXEC_TIMEOUT_SECONDS = 300;
14
+ /** A command the AI SDK harness runs without a timeout of its own. */
15
+ export declare const AI_HARNESS_COMMAND_TIMEOUT_MS = 3600000;
16
+ /** A command the OpenAI Agents sandbox runs without a timeout of its own. */
17
+ export declare const OPENAI_AGENTS_EXEC_TIMEOUT_MS = 3600000;
@@ -0,0 +1,22 @@
1
+ /* Every value this SDK sends the API for a bounded time field when the caller
2
+ * names none, in one place. packages/cloud/tests/sdk-defaults.test.ts holds
3
+ * each inside the range the API's registry gives that field, and the same
4
+ * names in the Python, Go, Java and Ruby SDKs to theirs. The suffix is the
5
+ * unit; a new default goes here, under a name that test maps to its field. */
6
+ /** A server-side wait for a state (`GET /v1/sandboxes/{id}?waitFor=`). */
7
+ export const WAIT_FOR_TIMEOUT_SECONDS = 60;
8
+ /** A streamed exec's command limit when none is given: the API's longest. */
9
+ export const STREAMED_EXEC_TIMEOUT_MS = 86_400_000;
10
+ /** The lease keepAlive keeps ahead of now, and so the most it extends by. */
11
+ export const KEEP_ALIVE_MARGIN_SECONDS = 600;
12
+ /** A webhook watch runs until stopped. */
13
+ export const WEBHOOK_WATCH_TIMEOUT_MS = 0;
14
+ /** A job run's limit, and the time added to it for its sandbox to start. */
15
+ export const JOB_TIMEOUT_SECONDS = 1800;
16
+ export const JOB_START_SECONDS = 60;
17
+ /** A command the framework-free tools run without a timeout of its own. */
18
+ export const TOOL_EXEC_TIMEOUT_SECONDS = 300;
19
+ /** A command the AI SDK harness runs without a timeout of its own. */
20
+ export const AI_HARNESS_COMMAND_TIMEOUT_MS = 3_600_000;
21
+ /** A command the OpenAI Agents sandbox runs without a timeout of its own. */
22
+ export const OPENAI_AGENTS_EXEC_TIMEOUT_MS = 3_600_000;
@@ -95,7 +95,7 @@ const BLAXEL_HINTS = {
95
95
  sandbox_paused: "Call sandbox.unarchive(), then try again.",
96
96
  not_running: "The sandbox is not running: call sandbox.unarchive() if it was archived, or make a new one with SandboxInstance.create if it was deleted.",
97
97
  trial_busy: "The trial's sandboxes are all in use: delete one you no longer need (sandbox.delete()) or archive it (sandbox.archive()), then try again. Moving to paid credit is the account owner's decision.",
98
- public_preview_not_allowed: "On the trial, share the port privately: sandbox.previews.create({ metadata: { name }, spec: { port, public: false } }) and a token from preview.tokens.create(expiresAt). A public preview needs a paid sandbox, which is the account owner's decision.",
98
+ public_preview_not_allowed: "On the trial, share the port privately: sandbox.previews.create({ metadata: { name }, spec: { port, public: false } }) and a token from preview.tokens.create(expiresAt) on a server supporting absolute preview deadlines. A public preview needs a paid sandbox, which is the account owner's decision.",
99
99
  busy: AGAIN,
100
100
  guest_busy: AGAIN,
101
101
  rate_limited: AGAIN,
@@ -32,6 +32,7 @@ export declare function findSandbox(client: Runtime, name: string): Promise<Runt
32
32
  export declare function findByExternalId(client: Runtime, externalId: string): Promise<RuntimeSandbox>;
33
33
  /** Runs a create or fork that names a sandbox. When the name is still held
34
34
  * by a sandbox that is stopping (deleted a moment ago, by this client or
35
- * another), waits for it to stop, up to 30 seconds, and runs it once more, as
36
- * Blaxel's createIfNotExists waits out a sandbox being deleted. */
35
+ * another), waits for it to stop, up to 30 seconds, and runs it once more.
36
+ * This reconciles Runtime's stopping-name conflicts. Blaxel 0.3.25 delegates
37
+ * createIfNotExists reconciliation to its control plane without client polling. */
37
38
  export declare function whenNameFree<T>(client: Runtime, work: () => Promise<T>): Promise<T>;
@@ -54,8 +54,9 @@ export async function findByExternalId(client, externalId) {
54
54
  }
55
55
  /** Runs a create or fork that names a sandbox. When the name is still held
56
56
  * by a sandbox that is stopping (deleted a moment ago, by this client or
57
- * another), waits for it to stop, up to 30 seconds, and runs it once more, as
58
- * Blaxel's createIfNotExists waits out a sandbox being deleted. */
57
+ * another), waits for it to stop, up to 30 seconds, and runs it once more.
58
+ * This reconciles Runtime's stopping-name conflicts. Blaxel 0.3.25 delegates
59
+ * createIfNotExists reconciliation to its control plane without client polling. */
59
60
  export async function whenNameFree(client, work) {
60
61
  try {
61
62
  return await work();
@@ -28,7 +28,7 @@ export type PaginatedList<T, TQuery extends CursorPaginationQuery = CursorPagina
28
28
  /** Blaxel's own helper: the items of a list answer in any of its shapes. */
29
29
  export declare function unwrapListData<T>(response: ListResponse<T>): T[];
30
30
  /** Blaxel's own helper, for a list fetched by `fetchPage`. */
31
- export declare function createPaginatedList<TRaw, TItem, TQuery extends CursorPaginationQuery>({ response, fetchPage, mapItem, query, }: {
31
+ export declare function createPaginatedList<TRaw, TItem, TQuery extends CursorPaginationQuery>({ response, fetchPage, mapItem, query, seenCursors, }: {
32
32
  response: ListResponse<TRaw>;
33
33
  fetchPage: (query?: TQuery) => Promise<ListResponse<TRaw>>;
34
34
  mapItem: (item: TRaw) => TItem | Promise<TItem>;
@@ -36,4 +36,4 @@ export declare function createPaginatedList<TRaw, TItem, TQuery extends CursorPa
36
36
  seenCursors?: Set<string>;
37
37
  }): Promise<PaginatedList<TItem, TQuery>>;
38
38
  /** A Runtime page, each item mapped, as Blaxel's paginated list. */
39
- export declare function paginate<TRaw, TItem>(page: Page<TRaw>, map: (item: TRaw) => TItem): PaginatedList<TItem>;
39
+ export declare function paginate<TRaw, TItem>(page: Page<TRaw>, map: (item: TRaw) => TItem, seenCursors?: Set<string>): PaginatedList<TItem>;
@@ -8,30 +8,58 @@ export function unwrapListData(response) {
8
8
  return response.data ?? [];
9
9
  }
10
10
  /** Blaxel's own helper, for a list fetched by `fetchPage`. */
11
- export async function createPaginatedList({ response, fetchPage, mapItem, query, }) {
12
- const meta = !response || Array.isArray(response) ? {} : (response.meta ?? {});
11
+ export async function createPaginatedList({ response, fetchPage, mapItem, query, seenCursors, }) {
12
+ const meta = !response || Array.isArray(response)
13
+ ? { hasMore: false }
14
+ : (response.meta ?? { hasMore: false });
13
15
  const data = await Promise.all(unwrapListData(response).map(mapItem));
14
- return build(data, meta.nextCursor || undefined, async (cursor) => createPaginatedList({
15
- response: await fetchPage({ ...(query ?? {}), cursor }),
16
- fetchPage,
17
- mapItem,
18
- ...(query ? { query: { ...query, cursor } } : {}),
19
- }));
16
+ const cursors = new Set(seenCursors);
17
+ if (query?.cursor)
18
+ cursors.add(query.cursor);
19
+ return build(data, meta.nextCursor || undefined, async (cursor) => {
20
+ if (cursors.has(cursor))
21
+ throw new Error("Pagination returned a repeated cursor");
22
+ const nextQuery = { ...(query ?? {}), cursor };
23
+ const nextSeenCursors = new Set(cursors);
24
+ nextSeenCursors.add(cursor);
25
+ return createPaginatedList({
26
+ response: await fetchPage(nextQuery),
27
+ fetchPage,
28
+ mapItem,
29
+ query: nextQuery,
30
+ seenCursors: nextSeenCursors,
31
+ });
32
+ }, meta);
20
33
  }
21
34
  /** A Runtime page, each item mapped, as Blaxel's paginated list. */
22
- export function paginate(page, map) {
23
- return build(page.data.map(map), page.nextCursor ?? undefined, async () => {
24
- const next = await guard(() => page.next());
25
- return next ? paginate(next, map) : null;
35
+ export function paginate(page, map, seenCursors = new Set()) {
36
+ return build(page.data.map(map), page.nextCursor ?? undefined, async (cursor) => {
37
+ if (cursor && seenCursors.has(cursor))
38
+ throw new Error("Pagination returned a repeated cursor");
39
+ const nextSeenCursors = new Set(seenCursors);
40
+ if (cursor)
41
+ nextSeenCursors.add(cursor);
42
+ const next = await guard(() => page.next(cursor));
43
+ return next ? paginate(next, map, nextSeenCursors) : null;
26
44
  });
27
45
  }
28
- function build(data, nextCursor, more) {
46
+ function build(data, nextCursor, more, meta = {
47
+ hasMore: nextCursor !== undefined,
48
+ ...(nextCursor ? { nextCursor } : {}),
49
+ }) {
29
50
  const list = {
30
51
  data,
31
- meta: { hasMore: nextCursor !== undefined, ...(nextCursor ? { nextCursor } : {}) },
32
- hasMore: nextCursor !== undefined,
33
- ...(nextCursor ? { nextCursor } : {}),
34
- nextPage: async () => (nextCursor ? more(nextCursor) : null),
52
+ meta,
53
+ get hasMore() {
54
+ return Boolean(list.nextCursor);
55
+ },
56
+ get nextCursor() {
57
+ return meta.nextCursor || undefined;
58
+ },
59
+ nextPage: async () => {
60
+ const cursor = list.nextCursor;
61
+ return cursor ? more(cursor) : null;
62
+ },
35
63
  async autoPagingEach(onItem) {
36
64
  for await (const item of list)
37
65
  if ((await onItem(item)) === false)
@@ -67,7 +67,8 @@ export declare class SandboxPreviewTokens {
67
67
  constructor(preview: SandboxPreview, ctx: PreviewContext);
68
68
  get previewName(): string;
69
69
  get resourceName(): string;
70
- /** A token that lasts until `expiresAt` (at least a minute, at most a week). */
70
+ /** A token bounded by `expiresAt`; native signing floors milliseconds and
71
+ * caps it to the caller's session. Older servers refuse without a TTL fallback. */
71
72
  create(expiresAt: Date): Promise<SandboxPreviewToken>;
72
73
  list(): Promise<never>;
73
74
  /** Revokes the preview's tokens. Runtime cannot revoke one token alone, so
@@ -98,7 +99,7 @@ export declare class SandboxPreviews {
98
99
  /** The named preview, or a new one when there is none. */
99
100
  createIfNotExists(preview: Preview, force?: boolean): Promise<SandboxPreview>;
100
101
  get(previewName: string): Promise<SandboxPreview>;
101
- /** Stops sharing the port; open connections close within seconds. */
102
+ /** Stops sharing the port; its open connections are closed before this returns. */
102
103
  delete(previewName: string): Promise<Preview>;
103
104
  }
104
105
  /** A private preview of `port` with a token that lasts a while, for