withruntime 0.11.2 → 0.14.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 (171) hide show
  1. package/BLAXEL.md +2 -2
  2. package/COMPATIBILITY.md +74 -9
  3. package/DAYTONA.md +33 -5
  4. package/E2B.md +85 -24
  5. package/README.md +11 -10
  6. package/README.src.md +10 -9
  7. package/VERCEL.md +43 -5
  8. package/compatibility-lock.json +58 -49
  9. package/dist/billing-cli.d.ts +1 -1
  10. package/dist/billing-cli.js +85 -5
  11. package/dist/blaxel/errors.d.ts +14 -0
  12. package/dist/blaxel/errors.js +29 -0
  13. package/dist/blaxel/index.d.ts +2 -2
  14. package/dist/blaxel/index.js +4 -4
  15. package/dist/blaxel/interpreter.d.ts +2 -5
  16. package/dist/blaxel/sandbox.d.ts +15 -6
  17. package/dist/blaxel/sandbox.js +64 -8
  18. package/dist/blaxel/snapshot.d.ts +4 -0
  19. package/dist/blaxel/snapshot.js +4 -0
  20. package/dist/cli/logs.d.ts +21 -0
  21. package/dist/cli/logs.js +188 -0
  22. package/dist/cli-extras.d.ts +3 -3
  23. package/dist/cli-extras.js +17 -12
  24. package/dist/cli-words.d.ts +10 -1
  25. package/dist/cli-words.js +18 -0
  26. package/dist/cli.d.ts +22 -3
  27. package/dist/cli.js +647 -273
  28. package/dist/client.d.ts +2 -4
  29. package/dist/client.js +27 -11
  30. package/dist/cloudflare/errors.d.ts +143 -0
  31. package/dist/cloudflare/errors.js +167 -0
  32. package/dist/cloudflare/index.d.ts +175 -6
  33. package/dist/cloudflare/index.js +416 -26
  34. package/dist/cloudflare/interpreter.d.ts +119 -0
  35. package/dist/cloudflare/interpreter.js +223 -0
  36. package/dist/cloudflare/streams.d.ts +38 -0
  37. package/dist/cloudflare/streams.js +145 -0
  38. package/dist/cloudflare/watch.d.ts +9 -0
  39. package/dist/cloudflare/watch.js +24 -0
  40. package/dist/codesandbox/index.d.ts +216 -28
  41. package/dist/codesandbox/index.js +478 -78
  42. package/dist/compat/core.d.ts +18 -0
  43. package/dist/compat/core.js +29 -0
  44. package/dist/compat/files.d.ts +1 -0
  45. package/dist/compat/files.js +25 -5
  46. package/dist/credentials.d.ts +3 -0
  47. package/dist/credentials.js +15 -0
  48. package/dist/daytona/computer-use.d.ts +13 -4
  49. package/dist/daytona/computer-use.js +66 -8
  50. package/dist/daytona/daytona.d.ts +7 -1
  51. package/dist/daytona/daytona.js +31 -4
  52. package/dist/daytona/errors.d.ts +11 -0
  53. package/dist/daytona/errors.js +18 -0
  54. package/dist/daytona/filesystem.js +2 -1
  55. package/dist/daytona/image.d.ts +13 -9
  56. package/dist/daytona/image.js +18 -12
  57. package/dist/daytona/index.d.ts +1 -1
  58. package/dist/daytona/sandbox.d.ts +8 -2
  59. package/dist/daytona/sandbox.js +16 -2
  60. package/dist/domains/index.d.ts +9 -0
  61. package/dist/domains/index.js +10 -0
  62. package/dist/e2b/commands.d.ts +1 -1
  63. package/dist/e2b/commands.js +6 -7
  64. package/dist/e2b/errors.d.ts +17 -0
  65. package/dist/e2b/errors.js +40 -1
  66. package/dist/e2b/index.d.ts +2 -2
  67. package/dist/e2b/index.js +1 -1
  68. package/dist/e2b/sandbox.d.ts +28 -22
  69. package/dist/e2b/sandbox.js +34 -8
  70. package/dist/e2b/unsupported.js +1 -1
  71. package/dist/errors.d.ts +11 -2
  72. package/dist/errors.js +17 -5
  73. package/dist/freestyle/index.d.ts +285 -37
  74. package/dist/freestyle/index.js +656 -144
  75. package/dist/identity.d.ts +3 -0
  76. package/dist/identity.js +27 -0
  77. package/dist/images/index.d.ts +9 -0
  78. package/dist/images/index.js +10 -0
  79. package/dist/index.d.ts +3 -1
  80. package/dist/ips/index.d.ts +9 -0
  81. package/dist/ips/index.js +10 -0
  82. package/dist/jobs/index.d.ts +9 -0
  83. package/dist/jobs/index.js +10 -0
  84. package/dist/keys.js +2 -0
  85. package/dist/login.js +2 -0
  86. package/dist/machine.d.ts +27 -4
  87. package/dist/machine.js +46 -14
  88. package/dist/mcp.js +144 -20
  89. package/dist/modal/index.d.ts +339 -61
  90. package/dist/modal/index.js +781 -121
  91. package/dist/network-cli.d.ts +3 -1
  92. package/dist/network-cli.js +78 -36
  93. package/dist/networks/index.d.ts +11 -0
  94. package/dist/networks/index.js +10 -0
  95. package/dist/ports/index.d.ts +9 -0
  96. package/dist/ports/index.js +10 -0
  97. package/dist/product-names.d.ts +52 -0
  98. package/dist/product-names.js +164 -0
  99. package/dist/product-renames.d.ts +103 -0
  100. package/dist/product-renames.js +189 -0
  101. package/dist/products/api-keys.d.ts +73 -0
  102. package/dist/products/api-keys.js +23 -0
  103. package/dist/products/apps.d.ts +157 -0
  104. package/dist/products/apps.js +60 -0
  105. package/dist/products/balancers.d.ts +87 -0
  106. package/dist/products/balancers.js +8 -0
  107. package/dist/products/billing.d.ts +41 -0
  108. package/dist/products/billing.js +13 -0
  109. package/dist/products/browser.d.ts +10 -0
  110. package/dist/products/browsers.d.ts +71 -0
  111. package/dist/products/browsers.js +102 -0
  112. package/dist/products/builds.d.ts +156 -0
  113. package/dist/products/builds.js +227 -0
  114. package/dist/products/index.d.ts +5 -16
  115. package/dist/products/index.js +5 -14
  116. package/dist/products/jobs.d.ts +19 -2
  117. package/dist/products/jobs.js +28 -11
  118. package/dist/products/logs.d.ts +245 -0
  119. package/dist/products/logs.js +274 -0
  120. package/dist/products/network-products.d.ts +38 -7
  121. package/dist/products/network-products.js +31 -18
  122. package/dist/products/observability.d.ts +8 -2
  123. package/dist/products/private-network.js +1 -1
  124. package/dist/products/queues.d.ts +149 -0
  125. package/dist/products/queues.js +213 -0
  126. package/dist/products/referrals.d.ts +21 -7
  127. package/dist/products/referrals.js +3 -3
  128. package/dist/products/resources.d.ts +54 -0
  129. package/dist/products/resources.js +122 -0
  130. package/dist/products/secrets.d.ts +29 -3
  131. package/dist/products/secrets.js +47 -18
  132. package/dist/products/signed-requests.d.ts +21 -0
  133. package/dist/products/signed-requests.js +11 -0
  134. package/dist/products/streams.d.ts +73 -0
  135. package/dist/products/streams.js +17 -0
  136. package/dist/products/switching.d.ts +35 -7
  137. package/dist/products/switching.js +4 -3
  138. package/dist/products/volumes.d.ts +6 -0
  139. package/dist/record-cli.d.ts +23 -0
  140. package/dist/record-cli.js +308 -0
  141. package/dist/renamed-products.d.ts +38 -0
  142. package/dist/renamed-products.js +34 -0
  143. package/dist/runloop/index.d.ts +9 -2
  144. package/dist/runloop/index.js +29 -8
  145. package/dist/runloop/sdk.d.ts +131 -0
  146. package/dist/runloop/sdk.js +167 -0
  147. package/dist/sandbox.d.ts +7 -2
  148. package/dist/sandbox.js +41 -11
  149. package/dist/sandboxes/index.d.ts +11 -0
  150. package/dist/sandboxes/index.js +12 -0
  151. package/dist/snapshots/index.d.ts +9 -0
  152. package/dist/snapshots/index.js +11 -0
  153. package/dist/snapshots.d.ts +7 -4
  154. package/dist/sprites/index.d.ts +343 -31
  155. package/dist/sprites/index.js +866 -84
  156. package/dist/ssh.d.ts +1 -1
  157. package/dist/ssh.js +11 -11
  158. package/dist/terminal.d.ts +24 -0
  159. package/dist/terminal.js +32 -0
  160. package/dist/transport.d.ts +18 -1
  161. package/dist/transport.js +80 -6
  162. package/dist/tunnel.js +1 -1
  163. package/dist/types.d.ts +71 -4
  164. package/dist/vercel/sandbox.d.ts +1 -1
  165. package/dist/vercel/sandbox.js +6 -4
  166. package/dist/vercel/snapshot.js +10 -2
  167. package/dist/volumes/index.d.ts +9 -0
  168. package/dist/volumes/index.js +10 -0
  169. package/dist/wallet.d.ts +4 -1
  170. package/dist/wallet.js +2 -1
  171. package/package.json +48 -14
@@ -0,0 +1,245 @@
1
+ import { Page } from "../page.js";
2
+ import type { RequestOptions, Transport } from "../transport.js";
3
+ /** Native logsd hit_json. Nanoseconds stay strings so no precision is lost. */
4
+ export type LogLine = {
5
+ time: string;
6
+ timeUnixNano: string;
7
+ severity: number;
8
+ severityText: string;
9
+ body: unknown;
10
+ labels: Record<string, string>;
11
+ attributes: Record<string, unknown>;
12
+ traceId: string | null;
13
+ spanId: string | null;
14
+ };
15
+ export type LogSearch = {
16
+ query: string;
17
+ start?: string;
18
+ end?: string;
19
+ limit?: number;
20
+ direction?: "forward" | "backward";
21
+ cursor?: string;
22
+ };
23
+ export type LogSearchResult = {
24
+ lines: LogLine[];
25
+ next?: string | null;
26
+ stats: {
27
+ ms: number;
28
+ blocks: number;
29
+ skippedByTime: number;
30
+ skippedByLabels: number;
31
+ skippedByWords: number;
32
+ scanned: number;
33
+ bytesRead: number;
34
+ };
35
+ };
36
+ export type TailGap = {
37
+ gap: true;
38
+ from: string;
39
+ to: string;
40
+ };
41
+ export type TailLine = LogLine & {
42
+ cursor: string;
43
+ gap?: false;
44
+ };
45
+ export type TailEvent = TailLine | TailGap;
46
+ export type LogQuery = {
47
+ query: string;
48
+ time?: string;
49
+ limit?: number;
50
+ direction?: "forward" | "backward";
51
+ };
52
+ export type LogRange = Omit<LogQuery, "time"> & {
53
+ start?: string;
54
+ end?: string;
55
+ step?: string;
56
+ interval?: string;
57
+ };
58
+ export type LokiResult = {
59
+ status: "success";
60
+ data: ({
61
+ resultType: "streams";
62
+ result: {
63
+ stream: Record<string, string>;
64
+ values: [string, string, Record<string, string>?][];
65
+ }[];
66
+ } | {
67
+ resultType: "matrix";
68
+ result: {
69
+ metric: Record<string, string>;
70
+ values: [number, string][];
71
+ }[];
72
+ } | {
73
+ resultType: "vector";
74
+ result: {
75
+ metric: Record<string, string>;
76
+ value: [number, string];
77
+ }[];
78
+ } | {
79
+ resultType: "scalar";
80
+ result: [number, string];
81
+ }) & {
82
+ stats?: Record<string, unknown>;
83
+ };
84
+ };
85
+ export type LabelResult = {
86
+ status: "success";
87
+ data: string[];
88
+ };
89
+ export type ViewInput = {
90
+ name: string;
91
+ labels: Record<string, string>;
92
+ query: string;
93
+ defaultRange?: string;
94
+ };
95
+ export type SavedView = ViewInput & {
96
+ id: string;
97
+ state: string;
98
+ createdAt: string;
99
+ };
100
+ export type AlertInput = {
101
+ name: string;
102
+ labels: Record<string, string>;
103
+ query: string;
104
+ condition: string;
105
+ for: string;
106
+ actions: Record<string, unknown>[];
107
+ };
108
+ export type Alert = AlertInput & {
109
+ id: string;
110
+ state: string;
111
+ createdAt: string;
112
+ };
113
+ /** OTLP/HTTP JSON; the server validates the signal's complete OTLP schema. */
114
+ export type OtlpLogs = {
115
+ resourceLogs: Record<string, unknown>[];
116
+ };
117
+ export type OtlpTraces = {
118
+ resourceSpans: Record<string, unknown>[];
119
+ };
120
+ export type TraceSpan = {
121
+ traceId: string;
122
+ spanId: string;
123
+ parentSpanId?: string;
124
+ name: string;
125
+ startTimeUnixNano: string;
126
+ endTimeUnixNano: string;
127
+ attributes?: {
128
+ key: string;
129
+ value: Record<string, unknown>;
130
+ }[];
131
+ status?: {
132
+ code?: number;
133
+ message?: string;
134
+ };
135
+ };
136
+ export type Trace = {
137
+ resourceSpans: {
138
+ resource?: {
139
+ attributes?: {
140
+ key: string;
141
+ value: Record<string, unknown>;
142
+ }[];
143
+ };
144
+ scopeSpans: {
145
+ spans: TraceSpan[];
146
+ }[];
147
+ }[];
148
+ };
149
+ export type TraceSearchResult = {
150
+ traces: {
151
+ traceID: string;
152
+ rootServiceName: string;
153
+ rootTraceName: string;
154
+ startTimeUnixNano: string;
155
+ durationMs: number;
156
+ }[];
157
+ metrics?: Record<string, unknown>;
158
+ };
159
+ /** Hidden until Logs launches. */
160
+ export declare function logs(t: Transport): {
161
+ search: (body: LogSearch, options?: RequestOptions) => Promise<LogSearchResult>;
162
+ pages(input: LogSearch, options?: RequestOptions): AsyncGenerator<LogSearchResult>;
163
+ /** The record's cursor, not timestamp or text, identifies a line. The
164
+ * server replays strictly after it. An echoed boundary is ignored; two
165
+ * identical lines at different record positions are both delivered. */
166
+ tail(query: string, options?: RequestOptions & {
167
+ cursor?: string;
168
+ start?: string;
169
+ reconnectMs?: number;
170
+ }): AsyncGenerator<TailEvent>;
171
+ query: (query: LogQuery, options?: RequestOptions) => Promise<LokiResult>;
172
+ queryRange: (query: LogRange, options?: RequestOptions) => Promise<LokiResult>;
173
+ labels: (query?: {
174
+ start?: string;
175
+ end?: string;
176
+ }, options?: RequestOptions) => Promise<LabelResult>;
177
+ labelValues: (name: string, query?: {
178
+ start?: string;
179
+ end?: string;
180
+ }, options?: RequestOptions) => Promise<LabelResult>;
181
+ views: {
182
+ create: (body: ViewInput, options?: RequestOptions) => Promise<SavedView>;
183
+ get: (id: string, options?: RequestOptions) => Promise<SavedView>;
184
+ list: (query?: {
185
+ limit?: number;
186
+ cursor?: string;
187
+ }, options?: RequestOptions) => Promise<Page<SavedView>>;
188
+ update: (id: string, body: Partial<ViewInput>, options?: RequestOptions) => Promise<SavedView>;
189
+ delete: (id: string, options?: RequestOptions) => Promise<void>;
190
+ };
191
+ ingest: (body: OtlpLogs, options?: RequestOptions) => Promise<{
192
+ partialSuccess?: {
193
+ rejectedLogRecords?: string;
194
+ rejectedSpans?: string;
195
+ errorMessage?: string;
196
+ };
197
+ }>;
198
+ };
199
+ export declare function traces(t: Transport): {
200
+ get: (id: string, options?: RequestOptions) => Promise<Trace>;
201
+ search: (q: string, options?: RequestOptions) => Promise<TraceSearchResult>;
202
+ tags: (options?: RequestOptions) => Promise<{
203
+ tagNames: string[];
204
+ }>;
205
+ views: {
206
+ create: (body: ViewInput, options?: RequestOptions) => Promise<SavedView>;
207
+ get: (id: string, options?: RequestOptions) => Promise<SavedView>;
208
+ list: (query?: {
209
+ limit?: number;
210
+ cursor?: string;
211
+ }, options?: RequestOptions) => Promise<Page<SavedView>>;
212
+ update: (id: string, body: Partial<ViewInput>, options?: RequestOptions) => Promise<SavedView>;
213
+ delete: (id: string, options?: RequestOptions) => Promise<void>;
214
+ };
215
+ ingest: (body: OtlpTraces, options?: RequestOptions) => Promise<{
216
+ partialSuccess?: {
217
+ rejectedLogRecords?: string;
218
+ rejectedSpans?: string;
219
+ errorMessage?: string;
220
+ };
221
+ }>;
222
+ };
223
+ export declare function alerts(t: Transport): {
224
+ test: (id: string, options?: RequestOptions) => Promise<{
225
+ firing: boolean;
226
+ matches: number;
227
+ }>;
228
+ silence: (id: string, input: {
229
+ until: string;
230
+ reason?: string;
231
+ }, options?: RequestOptions) => Promise<Alert>;
232
+ create: (body: AlertInput, options?: RequestOptions) => Promise<Alert>;
233
+ get: (id: string, options?: RequestOptions) => Promise<Alert>;
234
+ list: (query?: {
235
+ limit?: number;
236
+ cursor?: string;
237
+ }, options?: RequestOptions) => Promise<Page<Alert>>;
238
+ update: (id: string, body: Partial<AlertInput>, options?: RequestOptions) => Promise<Alert>;
239
+ delete: (id: string, options?: RequestOptions) => Promise<void>;
240
+ };
241
+ export type ObservabilityClient = {
242
+ logs: ReturnType<typeof logs>;
243
+ traces: ReturnType<typeof traces>;
244
+ alerts: ReturnType<typeof alerts>;
245
+ };
@@ -0,0 +1,274 @@
1
+ import { RuntimeError, InvalidRequestError } from "../errors.js";
2
+ import { Page } from "../page.js";
3
+ const enc = encodeURIComponent;
4
+ const protocol = (message) => new RuntimeError({
5
+ code: "invalid_stream",
6
+ status: 422,
7
+ message,
8
+ hint: "Reconnect the log tail. If this repeats, report the request to support.",
9
+ });
10
+ /** Shared CRUD keeps the saved log and trace views on identical contracts. */
11
+ function resources(t, path) {
12
+ const list = async (query = {}, options) => {
13
+ const page = await t.json({
14
+ method: "GET",
15
+ path,
16
+ query,
17
+ ...options,
18
+ });
19
+ return new Page(page.data, page.nextCursor, (cursor) => list({ ...query, cursor }, options));
20
+ };
21
+ return {
22
+ create: (body, options) => t.json({ method: "POST", path, body, ...options }),
23
+ get: (id, options) => t.json({ method: "GET", path: `${path}/${enc(id)}`, ...options }),
24
+ list,
25
+ update: (id, body, options) => t.json({ method: "PUT", path: `${path}/${enc(id)}`, body, ...options }),
26
+ delete: (id, options) => t.json({ method: "DELETE", path: `${path}/${enc(id)}`, ...options }),
27
+ };
28
+ }
29
+ function ingest(t, path, body, options) {
30
+ if (new TextEncoder().encode(JSON.stringify(body)).length > 1_048_576)
31
+ throw new InvalidRequestError({
32
+ code: "payload_too_large",
33
+ status: 413,
34
+ message: "OTLP JSON exceeds 1 MiB.",
35
+ hint: "Split the write into smaller batches, each with its own idempotency key.",
36
+ });
37
+ return t.json({ method: "POST", path, body, ...options });
38
+ }
39
+ /** Parse SSE incrementally, including split UTF-8, CRLF and multi-line data.
40
+ * Incomplete events at disconnect are discarded and replayed from the cursor.
41
+ * A finite event bound prevents a broken peer from growing memory forever. */
42
+ async function* events(stream, signal) {
43
+ const reader = stream.getReader();
44
+ const decoder = new TextDecoder();
45
+ let buffer = "", id = "", event = "", data = [], size = 0;
46
+ const cancel = () => {
47
+ void reader.cancel(signal?.reason).catch(() => undefined);
48
+ };
49
+ if (signal?.aborted)
50
+ cancel();
51
+ else
52
+ signal?.addEventListener("abort", cancel, { once: true });
53
+ try {
54
+ for (;;) {
55
+ signal?.throwIfAborted();
56
+ const chunk = await reader.read().catch((cause) => {
57
+ signal?.throwIfAborted();
58
+ throw new RuntimeError({
59
+ code: "tail_connection_lost",
60
+ status: 503,
61
+ message: "The log stream disconnected.",
62
+ hint: "The SDK resumes from the last delivered cursor.",
63
+ cause,
64
+ });
65
+ });
66
+ signal?.throwIfAborted();
67
+ if (chunk.done)
68
+ break;
69
+ buffer += decoder.decode(chunk.value, { stream: true });
70
+ for (;;) {
71
+ const match = /\r\n|\r|\n/.exec(buffer);
72
+ if (!match || (match[0] === "\r" && match.index === buffer.length - 1))
73
+ break;
74
+ const line = buffer.slice(0, match.index);
75
+ buffer = buffer.slice(match.index + match[0].length);
76
+ size += line.length + 1;
77
+ if (size > 1_048_576)
78
+ throw protocol("A log event exceeds 1 MiB of text.");
79
+ if (!line) {
80
+ if (data.length)
81
+ yield { id, event, data: data.join("\n") };
82
+ id = "";
83
+ event = "";
84
+ data = [];
85
+ size = 0;
86
+ }
87
+ else if (!line.startsWith(":")) {
88
+ const colon = line.indexOf(":");
89
+ const field = colon < 0 ? line : line.slice(0, colon);
90
+ const value = colon < 0 ? "" : line.slice(colon + 1).replace(/^ /, "");
91
+ if (field === "id" && !value.includes("\0"))
92
+ id = value;
93
+ if (field === "event")
94
+ event = value;
95
+ if (field === "data")
96
+ data.push(value);
97
+ }
98
+ }
99
+ if (buffer.length + size > 1_048_576)
100
+ throw protocol("A log event exceeds 1 MiB of text.");
101
+ }
102
+ }
103
+ finally {
104
+ signal?.removeEventListener("abort", cancel);
105
+ await reader.cancel().catch(() => undefined);
106
+ reader.releaseLock();
107
+ }
108
+ }
109
+ function pause(ms, signal) {
110
+ return new Promise((resolve, reject) => {
111
+ const done = () => {
112
+ signal?.removeEventListener("abort", abort);
113
+ resolve();
114
+ };
115
+ const timer = setTimeout(done, ms);
116
+ const abort = () => {
117
+ clearTimeout(timer);
118
+ signal?.removeEventListener("abort", abort);
119
+ reject(signal?.reason instanceof Error ? signal.reason : new DOMException("Aborted", "AbortError"));
120
+ };
121
+ if (signal?.aborted)
122
+ abort();
123
+ else
124
+ signal?.addEventListener("abort", abort, { once: true });
125
+ });
126
+ }
127
+ /** Hidden until Logs launches. */
128
+ export function logs(t) {
129
+ const search = (body, options) => t.json({ method: "POST", path: "/v1/logs:search", body, ...options });
130
+ return {
131
+ search,
132
+ async *pages(input, options) {
133
+ let cursor = input.cursor;
134
+ const seen = new Set();
135
+ if (cursor)
136
+ seen.add(cursor);
137
+ do {
138
+ const page = await search({ ...input, ...(cursor ? { cursor } : {}) }, options);
139
+ yield page;
140
+ cursor = page.next ?? undefined;
141
+ if (cursor && seen.has(cursor))
142
+ throw protocol("Search repeated a paging cursor.");
143
+ if (cursor)
144
+ seen.add(cursor);
145
+ } while (cursor);
146
+ },
147
+ /** The record's cursor, not timestamp or text, identifies a line. The
148
+ * server replays strictly after it. An echoed boundary is ignored; two
149
+ * identical lines at different record positions are both delivered. */
150
+ async *tail(query, options = {}) {
151
+ const { cursor: initial, start, reconnectMs = 250, ...request } = options;
152
+ let cursor = initial, failures = 0;
153
+ if (!Number.isFinite(reconnectMs) || reconnectMs < 0)
154
+ throw protocol("Reconnect delay must be a finite, nonnegative number.");
155
+ for (;;) {
156
+ request.signal?.throwIfAborted();
157
+ try {
158
+ const stream = await t.fileStream({
159
+ method: "GET",
160
+ path: "/v1/logs/tail",
161
+ query: { query, cursor, start },
162
+ accept: "text/event-stream",
163
+ ...request,
164
+ timeoutMs: request.timeoutMs ?? 0,
165
+ onResponse(response) {
166
+ if (!response.headers.get("content-type")?.toLowerCase().startsWith("text/event-stream"))
167
+ throw protocol("Log tail did not return text/event-stream.");
168
+ },
169
+ });
170
+ for await (const event of events(stream, request.signal)) {
171
+ let value;
172
+ try {
173
+ value = JSON.parse(event.data);
174
+ }
175
+ catch {
176
+ throw protocol("Log tail returned invalid JSON.");
177
+ }
178
+ if (event.event === "error") {
179
+ // A reader failure is retryable, but its resume id has not been
180
+ // delivered as a line. Keep the last acknowledged line cursor.
181
+ throw new RuntimeError({
182
+ code: "tail_interrupted",
183
+ status: 503,
184
+ message: "The log reader stopped.",
185
+ hint: "The SDK resumes from the last delivered cursor.",
186
+ });
187
+ }
188
+ if (!event.id)
189
+ throw protocol("Log tail event has no record cursor.");
190
+ if (event.id === cursor)
191
+ continue;
192
+ if (event.event === "start") {
193
+ // Where the server's tail begins: a reconnect before the first
194
+ // line resumes here, so nothing written meanwhile is missed.
195
+ cursor = event.id;
196
+ continue;
197
+ }
198
+ if (event.event === "gap") {
199
+ const gap = value;
200
+ const from = gap?.from ?? cursor;
201
+ const to = gap?.to ?? gap?.cursor;
202
+ if (typeof from !== "string" || typeof to !== "string" || to !== event.id)
203
+ throw protocol("Log tail gap has invalid cursors.");
204
+ cursor = event.id;
205
+ yield { gap: true, from, to };
206
+ }
207
+ else {
208
+ const line = value;
209
+ if (!line ||
210
+ typeof line.timeUnixNano !== "string" ||
211
+ typeof line.time !== "string" ||
212
+ !line.labels ||
213
+ !("body" in line))
214
+ throw protocol("Log tail returned an invalid line.");
215
+ cursor = event.id;
216
+ yield { ...line, cursor };
217
+ }
218
+ failures = 0;
219
+ }
220
+ }
221
+ catch (error) {
222
+ request.signal?.throwIfAborted();
223
+ if (error instanceof RuntimeError && !error.retryable)
224
+ throw error;
225
+ if (!(error instanceof RuntimeError) && !(error instanceof TypeError))
226
+ throw error;
227
+ }
228
+ await pause(Math.min(10_000, Math.max(0, reconnectMs) * 2 ** Math.min(failures++, 6)), request.signal);
229
+ }
230
+ },
231
+ query: (query, options) => t.json({ method: "GET", path: "/v1/logs/query", query, ...options }),
232
+ queryRange: (query, options) => t.json({ method: "GET", path: "/v1/logs/query_range", query, ...options }),
233
+ labels: (query = {}, options) => t.json({ method: "GET", path: "/v1/logs/labels", query, ...options }),
234
+ labelValues: (name, query = {}, options) => t.json({
235
+ method: "GET",
236
+ path: `/v1/logs/labels/${enc(name)}/values`,
237
+ query,
238
+ ...options,
239
+ }),
240
+ views: resources(t, "/v1/logs/views"),
241
+ ingest: (body, options) => ingest(t, "/v1/logs", body, options),
242
+ };
243
+ }
244
+ export function traces(t) {
245
+ return {
246
+ get: (id, options) => t.json({ method: "GET", path: `/v1/traces/${enc(id)}`, ...options }),
247
+ search: (q, options) => t.json({
248
+ method: "GET",
249
+ path: "/v1/traces:search",
250
+ query: { q },
251
+ ...options,
252
+ }),
253
+ tags: (options) => t.json({ method: "GET", path: "/v1/traces/tags", ...options }),
254
+ views: resources(t, "/v1/traces/views"),
255
+ ingest: (body, options) => ingest(t, "/v1/traces", body, options),
256
+ };
257
+ }
258
+ export function alerts(t) {
259
+ return {
260
+ ...resources(t, "/v1/alerts"),
261
+ test: (id, options) => t.json({
262
+ method: "POST",
263
+ path: `/v1/alerts/${enc(id)}/test`,
264
+ body: {},
265
+ ...options,
266
+ }),
267
+ silence: (id, input, options) => t.json({
268
+ method: "POST",
269
+ path: `/v1/alerts/${enc(id)}/silence`,
270
+ body: input,
271
+ ...options,
272
+ }),
273
+ };
274
+ }
@@ -129,9 +129,9 @@ export declare function ports(t: Transport): {
129
129
  deleted: true;
130
130
  }>;
131
131
  };
132
- /** `runtime.addresses`: a dedicated outbound address every sandbox of the
132
+ /** `runtime.ips`: a dedicated outbound address every sandbox of the
133
133
  * account sends from, for allow-lists. */
134
- export declare function addresses(t: Transport): {
134
+ export declare function ips(t: Transport): {
135
135
  reserve: (input?: {
136
136
  family?: 4 | 6;
137
137
  }, options?: RequestOptions) => Promise<EgressAddress>;
@@ -142,8 +142,8 @@ export declare function addresses(t: Transport): {
142
142
  deleted: true;
143
143
  }>;
144
144
  };
145
- /** `runtime.tunnel`: a WireGuard tunnel from your own network into your sandboxes. */
146
- export declare function tunnel(t: Transport): {
145
+ /** `runtime.networks.wireguard`: a WireGuard tunnel from your own network into your sandboxes. */
146
+ export declare function wireguard(t: Transport): {
147
147
  get: (options?: RequestOptions) => Promise<Tunnel>;
148
148
  /** Idempotent: returns the tunnel you have. */
149
149
  create: (input?: {
@@ -186,15 +186,39 @@ export type SetUpstreamProxy = {
186
186
  * every connection when absent. 1 to 16. */
187
187
  hosts?: string[];
188
188
  };
189
- /** `runtime.network`: the network settings of the whole account.
189
+ /** `runtime.networks`: the networks of the whole account: the WireGuard
190
+ * tunnel in, your sandboxes reaching each other, and the proxy out.
190
191
  *
191
- * await runtime.network.upstreamProxy.set({ url: "http://proxy.example.com:3128" });
192
+ * await runtime.networks.upstreamProxy.set({ url: "http://proxy.example.com:3128" });
192
193
  *
193
194
  * `upstreamProxy`: after Runtime's own rules allow a connection, the host
194
195
  * reaches it with CONNECT through your proxy, so your proxy's controls and
195
196
  * logs apply. A proxy that refuses or cannot be reached fails the connection
196
197
  * (upstream-proxy-failed); nothing goes around it. Needs a kept top-up. */
197
- export declare function network(t: Transport): {
198
+ export declare function networks(t: Transport): {
199
+ /** The WireGuard tunnel from your own network into your sandboxes. */
200
+ wireguard: {
201
+ get: (options?: RequestOptions) => Promise<Tunnel>;
202
+ /** Idempotent: returns the tunnel you have. */
203
+ create: (input?: {
204
+ subnet?: string;
205
+ }, options?: RequestOptions) => Promise<Tunnel>;
206
+ delete: (options?: RequestOptions) => Promise<{
207
+ id: string;
208
+ deleted: true;
209
+ }>;
210
+ /** Leave publicKey out and Runtime generates the pair; the private key is
211
+ * then in `config`, shown once. */
212
+ addPeer: (input: {
213
+ name: string;
214
+ publicKey?: string;
215
+ routes?: string[];
216
+ }, options?: RequestOptions) => Promise<TunnelPeerCreated>;
217
+ rotatePeer: (peerId: string, input?: {
218
+ publicKey?: string;
219
+ }, options?: RequestOptions) => Promise<TunnelPeerCreated>;
220
+ removePeer: (peerId: string, options?: RequestOptions) => Promise<Tunnel>;
221
+ };
198
222
  /** Your sandboxes reaching each other by name (`private-network.ts`). */
199
223
  private: {
200
224
  get: (options?: RequestOptions) => Promise<import("./private-network.js").PrivateNetwork>;
@@ -202,6 +226,13 @@ export declare function network(t: Transport): {
202
226
  enabled: boolean;
203
227
  }, options?: RequestOptions) => Promise<import("./private-network.js").PrivateNetwork>;
204
228
  };
229
+ /** Your sandboxes' requests signed as Runtime's agents (`signed-requests.ts`). */
230
+ signedRequests: {
231
+ get: (options?: RequestOptions) => Promise<import("./signed-requests.js").SignedRequests>;
232
+ set: (input: {
233
+ enabled: boolean;
234
+ }, options?: RequestOptions) => Promise<import("./signed-requests.js").SignedRequests>;
235
+ };
205
236
  upstreamProxy: {
206
237
  /** Send outbound connections through your proxy, replacing any set before. */
207
238
  set: (input: SetUpstreamProxy, options?: RequestOptions) => Promise<UpstreamProxy & {