diff --git a/docs/deploy/cloudflare.mdx b/docs/deploy/cloudflare.mdx index 46b0890..0a19448 100644 --- a/docs/deploy/cloudflare.mdx +++ b/docs/deploy/cloudflare.mdx @@ -75,7 +75,16 @@ app.post("/sandbox/:name/prompt", async (c) => { const sandbox = await getReadySandbox(c.req.param("name"), c.env); const sdk = await SandboxAgent.connect({ - fetch: (input, init) => sandbox.containerFetch(input as Request | string | URL, init, PORT), + fetch: (input, init) => + sandbox.containerFetch( + input as Request | string | URL, + { + ...(init ?? {}), + // Avoid passing AbortSignal through containerFetch; it can drop streamed session updates. + signal: undefined, + }, + PORT, + ), }); const session = await sdk.createSession({ agent: "codex" }); @@ -103,6 +112,33 @@ export default app; Create the SDK client inside the Worker using custom `fetch` backed by `sandbox.containerFetch(...)`. This keeps all Sandbox Agent calls inside the Cloudflare sandbox routing path and does not require a `baseUrl`. +## Troubleshooting streaming updates + +If you only receive: +- outbound `session/prompt` +- final `{ stopReason: "end_turn" }` + +then the streamed update channel dropped. In Cloudflare sandbox paths, this is typically caused by forwarding `AbortSignal` from SDK fetch init into `containerFetch(...)`. + +Fix: + +```ts +const sdk = await SandboxAgent.connect({ + fetch: (input, init) => + sandbox.containerFetch( + input as Request | string | URL, + { + ...(init ?? {}), + // Avoid passing AbortSignal through containerFetch; it can drop streamed session updates. + signal: undefined, + }, + PORT, + ), +}); +``` + +This keeps prompt completion behavior the same, but restores streamed text/tool updates. + ## Local development ```bash diff --git a/examples/cloudflare/README.md b/examples/cloudflare/README.md index 415bd39..b8461f2 100644 --- a/examples/cloudflare/README.md +++ b/examples/cloudflare/README.md @@ -39,12 +39,44 @@ curl http://localhost:8787 Test prompt routing through the SDK with a custom sandbox fetch handler: ```bash -curl -X POST "http://localhost:8787/sandbox/demo/prompt" \ +curl -N -X POST "http://localhost:8787/sandbox/demo/prompt" \ -H "Content-Type: application/json" \ + -H "Accept: text/event-stream" \ -d '{"agent":"codex","prompt":"Reply with one short sentence."}' ``` -The response includes `events`, an array of all recorded session events for that prompt. +The response is an SSE stream with events: +- `session.created` +- `session.event` +- `prompt.completed` +- `done` + +### Troubleshooting: only two events + +If you only see: +- outbound `session/prompt` +- inbound prompt result with `stopReason: "end_turn"` + +then ACP `session/update` notifications are not flowing. In Cloudflare sandbox paths this can happen if you forward `AbortSignal` from SDK fetch init into `containerFetch(...)` for long-lived ACP SSE requests. + +Use: + +```ts +const sdk = await SandboxAgent.connect({ + fetch: (input, init) => + sandbox.containerFetch( + input as Request | string | URL, + { + ...(init ?? {}), + // Avoid passing AbortSignal through containerFetch; it can drop ACP SSE updates. + signal: undefined, + }, + PORT, + ), +}); +``` + +Without `session/update` events, assistant text/tool deltas will not appear in UI streams. ## Deploy diff --git a/examples/cloudflare/src/index.ts b/examples/cloudflare/src/index.ts index 4d8ad10..1efa742 100644 --- a/examples/cloudflare/src/index.ts +++ b/examples/cloudflare/src/index.ts @@ -1,7 +1,8 @@ import { getSandbox, type Sandbox } from "@cloudflare/sandbox"; import { Hono } from "hono"; import { HTTPException } from "hono/http-exception"; -import { runPromptTest, type PromptTestRequest } from "./prompt-test"; +import { streamSSE } from "hono/streaming"; +import { runPromptEndpointStream, type PromptRequest } from "./prompt-endpoint"; export { Sandbox } from "@cloudflare/sandbox"; @@ -49,7 +50,15 @@ async function getReadySandbox(name: string, env: Bindings): Promise { async function proxyToSandbox(sandbox: Sandbox, request: Request, path: string): Promise { const query = new URL(request.url).search; - return sandbox.containerFetch(new Request(`http://localhost${path}${query}`, request), PORT); + return sandbox.containerFetch( + `http://localhost${path}${query}`, + { + method: request.method, + headers: request.headers, + body: request.body, + }, + PORT, + ); } const app = new Hono(); @@ -63,15 +72,34 @@ app.post("/sandbox/:name/prompt", async (c) => { throw new HTTPException(400, { message: "Content-Type must be application/json" }); } - let payload: PromptTestRequest; + let payload: PromptRequest; try { - payload = await c.req.json(); + payload = await c.req.json(); } catch { throw new HTTPException(400, { message: "Invalid JSON body" }); } const sandbox = await getReadySandbox(c.req.param("name"), c.env); - return c.json(await runPromptTest(sandbox, payload, PORT)); + return streamSSE(c, async (stream) => { + try { + await runPromptEndpointStream(sandbox, payload, PORT, async (event) => { + await stream.writeSSE({ + event: event.type, + data: JSON.stringify(event), + }); + }); + await stream.writeSSE({ + event: "done", + data: JSON.stringify({ ok: true }), + }); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + await stream.writeSSE({ + event: "error", + data: JSON.stringify({ message }), + }); + } + }); }); app.all("/sandbox/:name/proxy/*", async (c) => { diff --git a/examples/cloudflare/src/prompt-endpoint.ts b/examples/cloudflare/src/prompt-endpoint.ts new file mode 100644 index 0000000..4142fef --- /dev/null +++ b/examples/cloudflare/src/prompt-endpoint.ts @@ -0,0 +1,66 @@ +import type { Sandbox } from "@cloudflare/sandbox"; +import { SandboxAgent } from "sandbox-agent"; + +export type PromptRequest = { + agent?: string; + prompt?: string; +}; + +export async function runPromptEndpointStream( + sandbox: Sandbox, + request: PromptRequest, + port: number, + emit: (event: { type: string; [key: string]: unknown }) => Promise | void, +): Promise { + const client = await SandboxAgent.connect({ + fetch: (req, init) => + sandbox.containerFetch( + req, + { + ...(init ?? {}), + // Cloudflare containerFetch may drop long-lived update streams when + // a forwarded AbortSignal is cancelled; clear it for this path. + signal: undefined, + }, + port, + ), + }); + + let unsubscribe: (() => void) | undefined; + try { + const session = await client.createSession({ + agent: request.agent ?? "codex", + }); + + const promptText = + request.prompt?.trim() || "Reply with a short confirmation."; + await emit({ + type: "session.created", + sessionId: session.id, + agent: session.agent, + prompt: promptText, + }); + + let pendingWrites: Promise = Promise.resolve(); + unsubscribe = session.onEvent((event) => { + pendingWrites = pendingWrites + .then(async () => { + await emit({ type: "session.event", event }); + }) + .catch(() => {}); + }); + + const response = await session.prompt([{ type: "text", text: promptText }]); + await pendingWrites; + await emit({ type: "prompt.response", response }); + await emit({ type: "prompt.completed" }); + } finally { + if (unsubscribe) { + unsubscribe(); + } + await Promise.race([ + client.dispose(), + new Promise((resolve) => setTimeout(resolve, 250)), + ]); + } +} diff --git a/examples/cloudflare/src/prompt-test.ts b/examples/cloudflare/src/prompt-test.ts deleted file mode 100644 index f9bf50c..0000000 --- a/examples/cloudflare/src/prompt-test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import type { Sandbox } from "@cloudflare/sandbox"; -import { SandboxAgent } from "sandbox-agent"; - -export type PromptTestRequest = { - agent?: string; - prompt?: string; -}; - -export type PromptTestResponse = { - sessionId: string; - agent: string; - prompt: string; - events: unknown[]; -}; - -export async function runPromptTest( - sandbox: Sandbox, - request: PromptTestRequest, - port: number, -): Promise { - const client = await SandboxAgent.connect({ - fetch: (req, init) => - sandbox.containerFetch(req, init, port), - }); - - let sessionId: string | null = null; - try { - const session = await client.createSession({ - agent: request.agent ?? "codex", - }); - sessionId = session.id; - - const promptText = - request.prompt?.trim() || "Reply with a short confirmation."; - await session.prompt([{ type: "text", text: promptText }]); - - const events: unknown[] = []; - let cursor: string | undefined; - while (true) { - const page = await client.getEvents({ - sessionId: session.id, - cursor, - limit: 200, - }); - events.push(...page.items); - if (!page.nextCursor) break; - cursor = page.nextCursor; - } - - return { - sessionId: session.id, - agent: session.agent, - prompt: promptText, - events, - }; - } finally { - if (sessionId) { - try { - await client.destroySession(sessionId); - } catch { - // Ignore cleanup failures; session teardown is best-effort. - } - } - await client.dispose(); - } -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ec77fb6..1463987 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,6 +19,28 @@ importers: specifier: ^3.0.0 version: 3.2.4(@types/debug@4.1.12)(@types/node@25.3.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + examples/boxlite: + dependencies: + '@boxlite-ai/boxlite': + specifier: latest + version: 0.2.11 + '@sandbox-agent/example-shared': + specifier: workspace:* + version: link:../shared + sandbox-agent: + specifier: workspace:* + version: link:../../sdks/typescript + devDependencies: + '@types/node': + specifier: latest + version: 25.3.0 + tsx: + specifier: latest + version: 4.21.0 + typescript: + specifier: latest + version: 5.9.3 + examples/cloudflare: dependencies: '@cloudflare/sandbox': @@ -39,7 +61,7 @@ importers: devDependencies: '@cloudflare/workers-types': specifier: latest - version: 4.20260302.0 + version: 4.20260304.0 '@types/node': specifier: latest version: 25.3.0 @@ -63,7 +85,7 @@ importers: version: 3.2.4(@types/debug@4.1.12)(@types/node@25.3.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) wrangler: specifier: latest - version: 4.67.1(@cloudflare/workers-types@4.20260302.0) + version: 4.68.1(@cloudflare/workers-types@4.20260304.0) examples/computesdk: dependencies: @@ -72,7 +94,7 @@ importers: version: link:../shared computesdk: specifier: latest - version: 2.2.1 + version: 2.3.0 sandbox-agent: specifier: workspace:* version: link:../../sdks/typescript @@ -94,7 +116,7 @@ importers: dependencies: '@daytonaio/sdk': specifier: latest - version: 0.144.0(ws@8.19.0) + version: 0.145.0(ws@8.19.0) '@sandbox-agent/example-shared': specifier: workspace:* version: link:../shared @@ -210,7 +232,7 @@ importers: dependencies: '@modelcontextprotocol/sdk': specifier: latest - version: 1.26.0(zod@4.3.6) + version: 1.27.1(zod@4.3.6) '@sandbox-agent/example-shared': specifier: workspace:* version: link:../shared @@ -379,7 +401,7 @@ importers: version: link:../shared '@vercel/sandbox': specifier: latest - version: 1.6.0 + version: 1.7.1 sandbox-agent: specifier: workspace:* version: link:../../sdks/typescript @@ -534,7 +556,7 @@ importers: dependencies: '@daytonaio/sdk': specifier: latest - version: 0.144.0(ws@8.19.0) + version: 0.145.0(ws@8.19.0) '@e2b/code-interpreter': specifier: latest version: 2.3.3 @@ -1101,6 +1123,27 @@ packages: '@balena/dockerignore@1.0.2': resolution: {integrity: sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==} + '@boxlite-ai/boxlite-darwin-arm64@0.2.11': + resolution: {integrity: sha512-JjNf6S/+XqooWvFX2Zn9XjmeML/e6Errk0jzG77v8YV0k2nNmt8P1nMANb2kMPbsQn93ap9v74VnYesYdKRoNg==} + engines: {node: '>=18.0.0'} + cpu: [arm64] + os: [darwin] + + '@boxlite-ai/boxlite-linux-x64-gnu@0.2.11': + resolution: {integrity: sha512-H3a8FMc6X4KVsmlQKs2xTIlSh4KhiI52MnXV16OwcC6OWQBBadR1N6GCCKojfwpqn6yIsZc2dxoyy25YTYYf9g==} + engines: {node: '>=18.0.0'} + cpu: [x64] + os: [linux] + + '@boxlite-ai/boxlite@0.2.11': + resolution: {integrity: sha512-IJ+jyYdsc1hmZknDtqGpRyMAMxoQfF1VFDVuPhiO59fBmoDEI5u69DzoMtyax4gzL3Q46tjYkVBvJhNtSDaxBw==} + engines: {node: '>=18.0.0'} + peerDependencies: + playwright-core: '>=1.58.0' + peerDependenciesMeta: + playwright-core: + optional: true + '@bufbuild/protobuf@2.11.0': resolution: {integrity: sha512-sBXGT13cpmPR5BMgHE6UEEfEaShh5Ror6rfN3yEK5si7QVrtZg8LEPQb0VVhiLRUslD2yLnXtnRzG035J/mZXQ==} @@ -1198,8 +1241,8 @@ packages: cpu: [x64] os: [win32] - '@cloudflare/workers-types@4.20260302.0': - resolution: {integrity: sha512-mbFRnlu1lNCScMpXZk/X/uBPufYx5OSbq+euGonGRcY+DgOwm2kczGdK401rUh52NB0fFMEcOy/zqwxv7CdDNA==} + '@cloudflare/workers-types@4.20260304.0': + resolution: {integrity: sha512-oQ0QJpWnCWK9tx5q/ZHQeSsf5EcQWa4KqdDMY/R5Ln0ojFzv6UYO0RWsfDPsoXUAwK671VwaXqAW0Mx0uWz7yw==} '@computesdk/cmd@0.4.1': resolution: {integrity: sha512-hhcYrwMnOpRSwWma3gkUeAVsDFG56nURwSaQx8vCepv0IuUv39bK4mMkgszolnUQrVjBDdW7b3lV+l5B2S8fRA==} @@ -1219,14 +1262,14 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} - '@daytonaio/api-client@0.144.0': - resolution: {integrity: sha512-qr9c6YLntqmxbGAwYNIvHqZxA5zWl0nGY5aH3oK++1x03uDc5YnCwfcX7M7WCemt2iBUtLjQshdRKwFv0sDYsA==} + '@daytonaio/api-client@0.145.0': + resolution: {integrity: sha512-8xLJ1G7C3QJs2KfONcGd4O4ktHtGM4qxWVAcQERHSE1w4hJVrlaUzutMm2qy+HoXtMU1L5h/eFazoxrJ0xWzPw==} - '@daytonaio/sdk@0.144.0': - resolution: {integrity: sha512-Le8auU/h4xOlcTBQZWEx8jJwDEHeyKT/7oTUzkvONCp50agcuKjd5CDf79wsR9IqMuoCtlYcvhWXCNsdEuWkYg==} + '@daytonaio/sdk@0.145.0': + resolution: {integrity: sha512-RZhe5oz9EdC9PP3g95g+jXFkCiQbPJTfSALe9wi4W5n97hA9O6rM5zYRuwB2PJbHA8YC0m2t5pyHRJA9+88r5A==} - '@daytonaio/toolbox-api-client@0.144.0': - resolution: {integrity: sha512-ll5IXlH3nzhFtN+sW5fbAvT0mculP/GZCKnhHge/UlyG0cXKvlb3aoG2xWE1qpl5xWv2aQJbVdGhyuiGG/kPsQ==} + '@daytonaio/toolbox-api-client@0.145.0': + resolution: {integrity: sha512-Twh8FIoPAen+pjFeW03Fcom0fYT+k2grw8Q18aHdMAKQtXmMvA3+Ntim5ooE8AsHHLpCL6w+9ycdsovvzZOAEg==} '@e2b/code-interpreter@2.3.3': resolution: {integrity: sha512-WOpSwc1WpvxyOijf6WMbR76BUuvd2O9ddXgCHHi65lkuy6YgQGq7oyd8PNsT331O9Tqbccjy6uF4xanSdLX1UA==} @@ -2062,8 +2105,8 @@ packages: '@js-sdsl/ordered-map@4.4.2': resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} - '@modelcontextprotocol/sdk@1.26.0': - resolution: {integrity: sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg==} + '@modelcontextprotocol/sdk@1.27.1': + resolution: {integrity: sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==} engines: {node: '>=18'} peerDependencies: '@cfworker/json-schema': ^4.1.1 @@ -2818,12 +2861,12 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - '@vercel/oidc@3.1.0': - resolution: {integrity: sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==} + '@vercel/oidc@3.2.0': + resolution: {integrity: sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==} engines: {node: '>= 20'} - '@vercel/sandbox@1.6.0': - resolution: {integrity: sha512-T204S3RZIdo+BCR5gpErTQBYz+ruXjTMRiZyf+HV/UQeKjPKAVKWu27T65kahDvVvJrbadHhxR2Cds28rXXF/Q==} + '@vercel/sandbox@1.7.1': + resolution: {integrity: sha512-TI9InUQe7sqyO4/TIiGXC/3RHA0hTt5PpFaTWeWunkbKZae26nuPVsd+p10W/WN2THUKE+NPtTJ21dhp1Yw48w==} '@vitejs/plugin-react@4.7.0': resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} @@ -3196,8 +3239,8 @@ packages: compare-versions@6.1.1: resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} - computesdk@2.2.1: - resolution: {integrity: sha512-u4xAtvuTNTquaN57hJq030aeGJtmxQ6Pzd/8kXB7uaCgwyyePK4W0hPDeDOFzyNd9QgoDDUD9r1j1sdO+UqVXg==} + computesdk@2.3.0: + resolution: {integrity: sha512-4B7CRN2qB6XkuAnN7dZ0aMYqHaFrh2qdSuh02lM+cgMEQ7wZy9v44FAjBGfWebHXuPNA/nZRx7211U6CEiGdTw==} confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -5446,8 +5489,8 @@ packages: engines: {node: '>=16'} hasBin: true - wrangler@4.67.1: - resolution: {integrity: sha512-5GXz8cQNN/2KCMQ/22oe9Vf9xwVNillOowhKq6W2+ZuveU4/IrTm61K4iIUOsBYmrhYGopSfk0GmyCTuNh2rsA==} + wrangler@4.68.1: + resolution: {integrity: sha512-G+TI3k/olEGBAVkPtUlhAX/DIbL/190fv3aK+r+45/wPclNEymjxCc35T8QGTDhc2fEMXiw51L5bH9aNsBg+yQ==} engines: {node: '>=20.0.0'} hasBin: true peerDependencies: @@ -6331,6 +6374,17 @@ snapshots: '@balena/dockerignore@1.0.2': {} + '@boxlite-ai/boxlite-darwin-arm64@0.2.11': + optional: true + + '@boxlite-ai/boxlite-linux-x64-gnu@0.2.11': + optional: true + + '@boxlite-ai/boxlite@0.2.11': + optionalDependencies: + '@boxlite-ai/boxlite-darwin-arm64': 0.2.11 + '@boxlite-ai/boxlite-linux-x64-gnu': 0.2.11 + '@bufbuild/protobuf@2.11.0': {} '@capsizecss/unpack@4.0.0': @@ -6385,7 +6439,7 @@ snapshots: '@cloudflare/workerd-windows-64@1.20260302.0': optional: true - '@cloudflare/workers-types@4.20260302.0': {} + '@cloudflare/workers-types@4.20260304.0': {} '@computesdk/cmd@0.4.1': {} @@ -6402,18 +6456,18 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 - '@daytonaio/api-client@0.144.0': + '@daytonaio/api-client@0.145.0': dependencies: axios: 1.13.5 transitivePeerDependencies: - debug - '@daytonaio/sdk@0.144.0(ws@8.19.0)': + '@daytonaio/sdk@0.145.0(ws@8.19.0)': dependencies: '@aws-sdk/client-s3': 3.975.0 '@aws-sdk/lib-storage': 3.975.0(@aws-sdk/client-s3@3.975.0) - '@daytonaio/api-client': 0.144.0 - '@daytonaio/toolbox-api-client': 0.144.0 + '@daytonaio/api-client': 0.145.0 + '@daytonaio/toolbox-api-client': 0.145.0 '@iarna/toml': 2.2.5 '@opentelemetry/api': 1.9.0 '@opentelemetry/exporter-trace-otlp-http': 0.207.0(@opentelemetry/api@1.9.0) @@ -6439,7 +6493,7 @@ snapshots: - supports-color - ws - '@daytonaio/toolbox-api-client@0.144.0': + '@daytonaio/toolbox-api-client@0.145.0': dependencies: axios: 1.13.5 transitivePeerDependencies: @@ -6943,7 +6997,7 @@ snapshots: '@js-sdsl/ordered-map@4.4.2': {} - '@modelcontextprotocol/sdk@1.26.0(zod@4.3.6)': + '@modelcontextprotocol/sdk@1.27.1(zod@4.3.6)': dependencies: '@hono/node-server': 1.19.9(hono@4.11.8) ajv: 8.17.1 @@ -7782,7 +7836,7 @@ snapshots: '@types/better-sqlite3@7.6.13': dependencies: - '@types/node': 24.10.9 + '@types/node': 25.3.0 '@types/chai@5.2.3': dependencies: @@ -7844,7 +7898,7 @@ snapshots: '@types/pg@8.16.0': dependencies: - '@types/node': 24.10.9 + '@types/node': 25.3.0 pg-protocol: 1.11.0 pg-types: 2.2.0 @@ -7863,7 +7917,7 @@ snapshots: '@types/sax@1.2.7': dependencies: - '@types/node': 24.10.9 + '@types/node': 25.3.0 '@types/semver@7.7.1': {} @@ -7875,11 +7929,11 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vercel/oidc@3.1.0': {} + '@vercel/oidc@3.2.0': {} - '@vercel/sandbox@1.6.0': + '@vercel/sandbox@1.7.1': dependencies: - '@vercel/oidc': 3.1.0 + '@vercel/oidc': 3.2.0 async-retry: 1.3.3 jsonlines: 0.1.1 ms: 2.1.3 @@ -7924,14 +7978,6 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@5.4.21(@types/node@22.19.7))': - dependencies: - '@vitest/spy': 3.2.4 - estree-walker: 3.0.3 - magic-string: 0.30.21 - optionalDependencies: - vite: 5.4.21(@types/node@22.19.7) - '@vitest/mocker@3.2.4(vite@5.4.21(@types/node@25.3.0))': dependencies: '@vitest/spy': 3.2.4 @@ -8378,7 +8424,7 @@ snapshots: compare-versions@6.1.1: {} - computesdk@2.2.1: + computesdk@2.3.0: dependencies: '@computesdk/cmd': 0.4.1 @@ -10971,7 +11017,7 @@ snapshots: dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@22.19.7)) + '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@25.3.0)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -11080,7 +11126,7 @@ snapshots: '@cloudflare/workerd-linux-arm64': 1.20260302.0 '@cloudflare/workerd-windows-64': 1.20260302.0 - wrangler@4.67.1(@cloudflare/workers-types@4.20260302.0): + wrangler@4.68.1(@cloudflare/workers-types@4.20260304.0): dependencies: '@cloudflare/kv-asset-handler': 0.4.2 '@cloudflare/unenv-preset': 2.14.0(unenv@2.0.0-rc.24)(workerd@1.20260302.0) @@ -11091,7 +11137,7 @@ snapshots: unenv: 2.0.0-rc.24 workerd: 1.20260302.0 optionalDependencies: - '@cloudflare/workers-types': 4.20260302.0 + '@cloudflare/workers-types': 4.20260304.0 fsevents: 2.3.3 transitivePeerDependencies: - bufferutil