experimental-a2 0.16.0 → 0.17.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.
- package/CHANGELOG.md +360 -0
- package/dist/{actor-ohPC-81x.d.ts → actor-DBbe5xeE.d.ts} +21 -11
- package/dist/actor-DBbe5xeE.d.ts.map +1 -0
- package/dist/actor-client.d.ts +2 -5
- package/dist/actor-client.d.ts.map +1 -1
- package/dist/actor-client.js +13 -4
- package/dist/actor-client.js.map +1 -1
- package/dist/actor-react.d.ts +5 -3
- package/dist/actor-react.d.ts.map +1 -1
- package/dist/actor-react.js +20 -10
- package/dist/actor-react.js.map +1 -1
- package/dist/{actor-shared-B5tJfzt-.js → actor-shared-t7w8xIKP.js} +12 -7
- package/dist/actor-shared-t7w8xIKP.js.map +1 -0
- package/dist/actor.d.ts +1 -1
- package/dist/actor.js +42 -23
- package/dist/actor.js.map +1 -1
- package/dist/{ai-CrLYwNEx.js → ai-UrWfKeuv.js} +966 -541
- package/dist/ai-UrWfKeuv.js.map +1 -0
- package/dist/ai-client.d.ts +27 -0
- package/dist/ai-client.d.ts.map +1 -0
- package/dist/ai-client.js +29 -0
- package/dist/ai-client.js.map +1 -0
- package/dist/ai-react.d.ts +96 -0
- package/dist/ai-react.d.ts.map +1 -0
- package/dist/ai-react.js +142 -0
- package/dist/ai-react.js.map +1 -0
- package/dist/ai-server.browser.js +2 -2
- package/dist/ai-server.browser.js.map +1 -1
- package/dist/ai-server.d.ts +80 -36
- package/dist/ai-server.d.ts.map +1 -1
- package/dist/ai-server.js +466 -265
- package/dist/ai-server.js.map +1 -1
- package/dist/{ai-HJ9fHfYI.d.ts → ai-vpGtcaCB.d.ts} +115 -101
- package/dist/ai-vpGtcaCB.d.ts.map +1 -0
- package/dist/ai.d.ts +2 -2
- package/dist/ai.js +2 -2
- package/dist/{client-BYzHjkwU.js → client-COaiaDub.js} +447 -80
- package/dist/client-COaiaDub.js.map +1 -0
- package/dist/{client-CzyacQpJ.d.ts → client-qRnRUzBS.d.ts} +14 -13
- package/dist/client-qRnRUzBS.d.ts.map +1 -0
- package/dist/client.d.ts +4 -2
- package/dist/client.js +1 -1
- package/dist/{contract-CKRg_E4q.js → contract-BYKASlCV.js} +12 -21
- package/dist/contract-BYKASlCV.js.map +1 -0
- package/dist/{idempotent-replay-DVOlyYbx.js → idempotent-replay-JdgMQRRm.js} +2 -2
- package/dist/{idempotent-replay-DVOlyYbx.js.map → idempotent-replay-JdgMQRRm.js.map} +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/{errors-DvhSXnxk.d.ts → initial-snapshot-BrLso5x_.d.ts} +7 -3
- package/dist/initial-snapshot-BrLso5x_.d.ts.map +1 -0
- package/dist/{internal-Dq2qYxou.js → internal-CbVvEwad.js} +23 -2
- package/dist/internal-CbVvEwad.js.map +1 -0
- package/dist/otel.d.ts +1 -1
- package/dist/react-BbJ-g6Uu.d.ts +86 -0
- package/dist/react-BbJ-g6Uu.d.ts.map +1 -0
- package/dist/react.d.ts +2 -122
- package/dist/react.js +107 -100
- package/dist/react.js.map +1 -1
- package/dist/reducer-BAXc8JyF.js +87 -0
- package/dist/reducer-BAXc8JyF.js.map +1 -0
- package/dist/{reducer-otzHjuJj.d.ts → reducer-BYu6DT7h.d.ts} +45 -29
- package/dist/reducer-BYu6DT7h.d.ts.map +1 -0
- package/dist/reducer-runtime-DQwz_J59.js +28 -0
- package/dist/reducer-runtime-DQwz_J59.js.map +1 -0
- package/dist/scheduler-qstash.d.ts +3 -3
- package/dist/scheduler-qstash.d.ts.map +1 -1
- package/dist/scheduler-qstash.js +33 -10
- package/dist/scheduler-qstash.js.map +1 -1
- package/dist/{scheduler-task-BpzhPnRS.js → scheduler-task-X1SToDjP.js} +18 -3
- package/dist/scheduler-task-X1SToDjP.js.map +1 -0
- package/dist/scheduler-vercel.d.ts +4 -9
- package/dist/scheduler-vercel.d.ts.map +1 -1
- package/dist/scheduler-vercel.js +25 -44
- package/dist/scheduler-vercel.js.map +1 -1
- package/dist/{server-DbD7IJVK.d.ts → server-CGM8WzRG.d.ts} +87 -26
- package/dist/server-CGM8WzRG.d.ts.map +1 -0
- package/dist/{server-BD5ckxZb.js → server-Rj64fNvX.js} +854 -202
- package/dist/server-Rj64fNvX.js.map +1 -0
- package/dist/server.d.ts +4 -4
- package/dist/server.js +2 -2
- package/dist/{errors-DCk6ch5n.js → session-clear-DGI4jTQ5.js} +17 -2
- package/dist/session-clear-DGI4jTQ5.js.map +1 -0
- package/dist/session-clear-Dshpuhff.d.ts +12 -0
- package/dist/session-clear-Dshpuhff.d.ts.map +1 -0
- package/dist/{store-DyZM6fS5.d.ts → store-Gpkq7WBo.d.ts} +44 -3
- package/dist/store-Gpkq7WBo.d.ts.map +1 -0
- package/dist/store-N8PXxDAS.js.map +1 -1
- package/dist/store-memory.d.ts +1 -1
- package/dist/store-memory.d.ts.map +1 -1
- package/dist/store-memory.js +182 -69
- package/dist/store-memory.js.map +1 -1
- package/dist/{store-polling-CmxUbV93.js → store-polling-4_y8lETm.js} +21 -4
- package/dist/store-polling-4_y8lETm.js.map +1 -0
- package/dist/store-postgres.d.ts +1 -1
- package/dist/store-postgres.d.ts.map +1 -1
- package/dist/store-postgres.js +399 -108
- package/dist/store-postgres.js.map +1 -1
- package/dist/{store-presence-polling-C7-XZyW9.js → store-presence-polling-Q1C-k2dd.js} +3 -3
- package/dist/{store-presence-polling-C7-XZyW9.js.map → store-presence-polling-Q1C-k2dd.js.map} +1 -1
- package/dist/store-redis-http.d.ts +1 -1
- package/dist/store-redis-http.d.ts.map +1 -1
- package/dist/store-redis-http.js +293 -11
- package/dist/store-redis-http.js.map +1 -1
- package/dist/store-redis-notify-tqWNnMRu.js +2374 -0
- package/dist/store-redis-notify-tqWNnMRu.js.map +1 -0
- package/dist/store-redis.d.ts +1 -1
- package/dist/store-redis.d.ts.map +1 -1
- package/dist/store-redis.js +11 -11
- package/dist/store-redis.js.map +1 -1
- package/dist/store-sqlite.d.ts +1 -1
- package/dist/store-sqlite.d.ts.map +1 -1
- package/dist/store-sqlite.js +166 -32
- package/dist/store-sqlite.js.map +1 -1
- package/dist/stream-buffer-Cx7AAPGq.js +23 -0
- package/dist/stream-buffer-Cx7AAPGq.js.map +1 -0
- package/dist/{telemetry-B5jzpy6y.d.ts → telemetry-cZH-cibj.d.ts} +2 -2
- package/dist/telemetry-cZH-cibj.d.ts.map +1 -0
- package/dist/{wire-BO5wWCb1.js → wire-DjfHOvdW.js} +132 -10
- package/dist/wire-DjfHOvdW.js.map +1 -0
- package/docs/01-quickstart.mdx +2 -2
- package/docs/actors/01-introduction.mdx +4 -0
- package/docs/actors/04-routes.mdx +14 -1
- package/docs/concepts/01-contracts.mdx +95 -0
- package/docs/concepts/04-state.mdx +3 -3
- package/docs/guides/01-timers.mdx +22 -14
- package/docs/guides/02-cancellation.mdx +1 -1
- package/docs/guides/03-react.mdx +268 -328
- package/docs/guides/04-local-first.mdx +32 -73
- package/docs/guides/05-production.mdx +40 -27
- package/docs/guides/06-ai-agents.mdx +680 -580
- package/docs/guides/09-presence.mdx +3 -7
- package/docs/guides/10-transports.mdx +5 -5
- package/docs/index.mdx +10 -18
- package/docs/reference/01-api.mdx +662 -195
- package/docs/reference/02-errors.mdx +2 -1
- package/examples/playground/DEPLOY.md +52 -6
- package/examples/playground/app/a0/[appId]/loading.tsx +16 -0
- package/examples/playground/app/a0/[appId]/page.tsx +48 -0
- package/examples/playground/app/a0/a0.css +818 -0
- package/examples/playground/app/a0/app-list.tsx +211 -0
- package/examples/playground/app/a0/app-view.tsx +55 -0
- package/examples/playground/app/a0/apps/[appId]/preview/route.ts +27 -0
- package/examples/playground/app/a0/apps/[appId]/route.ts +23 -0
- package/examples/playground/app/a0/apps.test.ts +116 -0
- package/examples/playground/app/a0/apps.ts +87 -0
- package/examples/playground/app/a0/chat.tsx +364 -0
- package/examples/playground/app/a0/columns.tsx +109 -0
- package/examples/playground/app/a0/context-menu.tsx +116 -0
- package/examples/playground/app/a0/cookies.ts +46 -0
- package/examples/playground/app/a0/crash-on-request.ts +72 -0
- package/examples/playground/app/a0/crashes/route.ts +3 -0
- package/examples/playground/app/a0/crashes.test.ts +33 -0
- package/examples/playground/app/a0/crashes.ts +28 -0
- package/examples/playground/app/a0/devtools.tsx +164 -0
- package/examples/playground/app/a0/events/route.ts +6 -0
- package/examples/playground/app/a0/flags.ts +30 -0
- package/examples/playground/app/a0/layout.tsx +38 -0
- package/examples/playground/app/a0/list/route.ts +10 -0
- package/examples/playground/app/a0/model.test.ts +56 -0
- package/examples/playground/app/a0/model.ts +58 -0
- package/examples/playground/app/a0/page.tsx +14 -0
- package/examples/playground/app/a0/preview-pane.tsx +145 -0
- package/examples/playground/app/a0/preview.test.ts +53 -0
- package/examples/playground/app/a0/preview.ts +26 -0
- package/examples/playground/app/a0/sandbox-log.ts +69 -0
- package/examples/playground/app/a0/sandbox.ts +191 -0
- package/examples/playground/app/a0/sandboxes/scheduler/route.ts +6 -0
- package/examples/playground/app/a0/scheduler/route.ts +7 -0
- package/examples/playground/app/a0/server.ts +158 -0
- package/examples/playground/app/a0/session.ts +47 -0
- package/examples/playground/app/a0/shell.tsx +150 -0
- package/examples/playground/app/a0/short/events/route.ts +9 -0
- package/examples/playground/app/a0/splitter.tsx +120 -0
- package/examples/playground/app/agent/[agentId]/agent-client.tsx +144 -174
- package/examples/playground/app/agent/[agentId]/command-receipt.test.tsx +65 -0
- package/examples/playground/app/agent/[agentId]/command-receipt.tsx +27 -0
- package/examples/playground/app/agent/[agentId]/compaction-event.tsx +25 -24
- package/examples/playground/app/agent/[agentId]/compaction-panel.test.tsx +119 -0
- package/examples/playground/app/agent/[agentId]/compaction-panel.tsx +208 -165
- package/examples/playground/app/agent/[agentId]/page.tsx +2 -16
- package/examples/playground/app/agent/events/route.ts +5 -2
- package/examples/playground/app/agent/ingress.test.ts +98 -0
- package/examples/playground/app/agent/model-input.test.tsx +58 -0
- package/examples/playground/app/agent/model-input.tsx +115 -0
- package/examples/playground/app/agent/model.test.ts +73 -0
- package/examples/playground/app/agent/model.ts +58 -26
- package/examples/playground/app/agent/new-agent-session.tsx +37 -19
- package/examples/playground/app/agent/page.tsx +4 -4
- package/examples/playground/app/agent/server.ts +15 -14
- package/examples/playground/app/agent/session.ts +5 -6
- package/examples/playground/app/agent/telemetry.test.ts +168 -0
- package/examples/playground/app/agent/telemetry.ts +30 -0
- package/examples/playground/app/agent/trace.test.ts +23 -0
- package/examples/playground/app/agent/trace.ts +18 -0
- package/examples/playground/app/canvas/[canvasId]/canvas-client.tsx +11 -11
- package/examples/playground/app/canvas/[canvasId]/page.tsx +1 -2
- package/examples/playground/app/canvas/[canvasId]/session.ts +2 -2
- package/examples/playground/app/canvas/model.ts +53 -53
- package/examples/playground/app/chat/[chatId]/agent-state.test.ts +176 -0
- package/examples/playground/app/chat/[chatId]/agent-stream-drawer.tsx +16 -1
- package/examples/playground/app/chat/[chatId]/chat-client.tsx +55 -77
- package/examples/playground/app/chat/[chatId]/chat-view.ts +37 -3
- package/examples/playground/app/chat/[chatId]/page.tsx +7 -15
- package/examples/playground/app/chat/[chatId]/session.ts +2 -19
- package/examples/playground/app/chat/agent/route.ts +9 -0
- package/examples/playground/app/chat/model.test.ts +46 -119
- package/examples/playground/app/chat/model.ts +82 -128
- package/examples/playground/app/chat/scheduler/route.ts +2 -2
- package/examples/playground/app/chat/server.test.ts +108 -0
- package/examples/playground/app/chat/server.ts +69 -73
- package/examples/playground/app/components/activity-feed.tsx +30 -1
- package/examples/playground/app/components/activity-history.test.tsx +35 -0
- package/examples/playground/app/components/demo-icons.tsx +89 -0
- package/examples/playground/app/components/demos.tsx +33 -0
- package/examples/playground/app/components/fast-link.test.tsx +58 -0
- package/examples/playground/app/components/fast-link.tsx +55 -0
- package/examples/playground/app/components/site-header.tsx +96 -0
- package/examples/playground/app/counter/counter-client.tsx +3 -3
- package/examples/playground/app/counter/model.test.ts +3 -3
- package/examples/playground/app/counter/model.ts +11 -21
- package/examples/playground/app/counter/page.tsx +2 -15
- package/examples/playground/app/counter/session.ts +2 -2
- package/examples/playground/app/documents/[documentId]/code-editor.tsx +12 -1
- package/examples/playground/app/documents/[documentId]/document-client.tsx +10 -11
- package/examples/playground/app/documents/[documentId]/page.tsx +1 -2
- package/examples/playground/app/documents/[documentId]/session.ts +2 -2
- package/examples/playground/app/documents/model.ts +27 -27
- package/examples/playground/app/globals.css +420 -207
- package/examples/playground/app/initial-state.test.tsx +54 -0
- package/examples/playground/app/layout.tsx +7 -23
- package/examples/playground/app/orders/[orderId]/page.tsx +1 -2
- package/examples/playground/app/orders/[orderId]/session.ts +2 -2
- package/examples/playground/app/orders/model.ts +49 -49
- package/examples/playground/app/page.tsx +13 -102
- package/examples/playground/app/recovery/[recoveryId]/page.tsx +1 -2
- package/examples/playground/app/recovery/[recoveryId]/session.ts +2 -2
- package/examples/playground/app/recovery/model.ts +30 -30
- package/examples/playground/instrumentation.ts +5 -0
- package/examples/playground/package.json +10 -2
- package/examples/playground/scripts/a0-template.ts +77 -0
- package/examples/playground/vercel.json +18 -0
- package/package.json +3 -1
- package/src/actor-client.ts +16 -4
- package/src/actor-react.ts +25 -11
- package/src/actor-shared.ts +21 -6
- package/src/actor.ts +76 -31
- package/src/ai-agent-actions.ts +219 -0
- package/src/ai-agent.ts +2343 -0
- package/src/ai-app-state.ts +91 -0
- package/src/ai-client-state.ts +39 -2
- package/src/ai-client.ts +62 -0
- package/src/ai-context-schema.ts +25 -5
- package/src/ai-context.ts +90 -40
- package/src/ai-control-server.ts +94 -55
- package/src/ai-control.ts +2 -0
- package/src/ai-coordinator.ts +23 -22
- package/src/ai-message-base.ts +209 -0
- package/src/ai-message-projection.ts +382 -58
- package/src/ai-progress-batches.ts +26 -0
- package/src/ai-projector.ts +95 -14
- package/src/ai-react.ts +146 -0
- package/src/ai-server.browser.ts +2 -2
- package/src/ai-server.ts +20 -1951
- package/src/ai-stored-state.ts +48 -163
- package/src/ai.ts +343 -276
- package/src/bootstrap-stream.ts +72 -0
- package/src/bounded-cache.ts +55 -0
- package/src/client-render-session.ts +49 -0
- package/src/client.ts +688 -151
- package/src/contract.ts +92 -42
- package/src/deterministic-id.ts +37 -0
- package/src/equal-json.ts +32 -0
- package/src/errors.ts +13 -1
- package/src/index.ts +5 -1
- package/src/initial-snapshot.ts +39 -0
- package/src/internal.ts +45 -0
- package/src/postgres-notification-scope.ts +14 -3
- package/src/react.ts +171 -206
- package/src/redis-http-reply.ts +256 -0
- package/src/redis-http-stream.ts +73 -0
- package/src/redis-http-subscriptions.ts +13 -5
- package/src/reducer-runtime.ts +52 -0
- package/src/reducer.ts +92 -10
- package/src/scheduler-qstash.ts +49 -20
- package/src/scheduler-task.ts +34 -2
- package/src/scheduler-vercel.ts +32 -84
- package/src/server-fetch.ts +139 -35
- package/src/server.ts +957 -237
- package/src/session-clear.ts +23 -0
- package/src/session-socket.ts +154 -49
- package/src/sse.ts +71 -4
- package/src/store-memory.ts +220 -78
- package/src/store-polling.ts +18 -4
- package/src/store-postgres.ts +461 -114
- package/src/store-redis-core.ts +1260 -434
- package/src/store-redis-http.ts +18 -2
- package/src/store-redis-notify.ts +260 -85
- package/src/store-redis.ts +19 -9
- package/src/store-sqlite.ts +259 -45
- package/src/store.ts +46 -1
- package/src/stream-buffer.ts +43 -0
- package/src/telemetry.ts +13 -1
- package/src/wire.ts +241 -13
- package/dist/actor-ohPC-81x.d.ts.map +0 -1
- package/dist/actor-shared-B5tJfzt-.js.map +0 -1
- package/dist/ai-CrLYwNEx.js.map +0 -1
- package/dist/ai-HJ9fHfYI.d.ts.map +0 -1
- package/dist/client-BYzHjkwU.js.map +0 -1
- package/dist/client-CzyacQpJ.d.ts.map +0 -1
- package/dist/contract-CKRg_E4q.js.map +0 -1
- package/dist/errors-DCk6ch5n.js.map +0 -1
- package/dist/errors-DvhSXnxk.d.ts.map +0 -1
- package/dist/internal-Dq2qYxou.js.map +0 -1
- package/dist/react.d.ts.map +0 -1
- package/dist/reducer-DEMjEY_O.js +0 -29
- package/dist/reducer-DEMjEY_O.js.map +0 -1
- package/dist/reducer-otzHjuJj.d.ts.map +0 -1
- package/dist/scheduler-task-BpzhPnRS.js.map +0 -1
- package/dist/server-BD5ckxZb.js.map +0 -1
- package/dist/server-DbD7IJVK.d.ts.map +0 -1
- package/dist/store-DyZM6fS5.d.ts.map +0 -1
- package/dist/store-polling-CmxUbV93.js.map +0 -1
- package/dist/store-redis-notify-BVLUfI3j.js +0 -1583
- package/dist/store-redis-notify-BVLUfI3j.js.map +0 -1
- package/dist/telemetry-B5jzpy6y.d.ts.map +0 -1
- package/dist/validate-XKT4FSNn.js +0 -30
- package/dist/validate-XKT4FSNn.js.map +0 -1
- package/dist/wire-BO5wWCb1.js.map +0 -1
- package/examples/playground/app/agent/[agentId]/compaction/route.ts +0 -14
- package/examples/playground/app/agent/compaction-settings.test.ts +0 -144
- package/examples/playground/app/agent/compaction-settings.ts +0 -49
- package/examples/playground/app/agent/compaction-timeline.test.ts +0 -377
- package/examples/playground/app/agent/compaction-timeline.ts +0 -208
|
@@ -40,7 +40,8 @@ export async function POST(req: Request) {
|
|
|
40
40
|
| `UNKNOWN_PRESENCE_FIELD` | a presence field isn't in the contract's `presence` map | no |
|
|
41
41
|
| `PRESENCE_NOT_SUPPORTED` | the contract declares `presence` but the configured store has no presence capability (thrown at construction; for environment-resolved stores, deferred to the first store use) | no |
|
|
42
42
|
| `PARTIAL_DUPLICATE_BATCH` | a batch mixed already-appended and fresh events | no |
|
|
43
|
-
| `SUPERSEDED_ATTEMPT` | a handler append from an attempt a recovery claim has replaced; nothing was written
|
|
43
|
+
| `SUPERSEDED_ATTEMPT` | a handler append or clear from an attempt that a recovery claim or a session clear has replaced; nothing was written. Also the abort reason on that handler's `ctx.signal` | no |
|
|
44
|
+
| `SESSION_CLEARED` | a state read reached below the latest clear, a handler read state past a clear of its event, or an actor call was cleared before it received its answer | no |
|
|
44
45
|
| `CLAIM_EXPIRED` | never thrown; only the `ctx.signal` abort reason when the attempt's lease lapsed without renewal (assumed loss, decided locally, not proof) | no |
|
|
45
46
|
| `STORE_UNAVAILABLE` | the store backend failed; nothing was written, original error as `cause` | **yes** |
|
|
46
47
|
| `STORE_NOT_CONFIGURED` | production boot with no `store` configured (during `next build` page collection, deferred to first use) | no |
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Deploying the playground
|
|
2
2
|
|
|
3
3
|
The event log runs with zero setup in development (SQLite at `.a2/dev.db`,
|
|
4
|
-
no scheduler). The Agent demo also
|
|
4
|
+
no scheduler). The Agent demo and A0 also need AI Gateway and Vercel Sandbox
|
|
5
5
|
credentials. Production needs the deliberate pieces from
|
|
6
6
|
`node_modules/experimental-a2/docs/guides/05-production.mdx`.
|
|
7
7
|
|
|
@@ -38,7 +38,7 @@ dependencies of this app.
|
|
|
38
38
|
|
|
39
39
|
## 2. Vercel Queues scheduler
|
|
40
40
|
|
|
41
|
-
Queues need no configuration beyond the triggers in `vercel.json`. Orders,
|
|
41
|
+
Queues need no configuration beyond the triggers in `vercel.json`. A0, Orders,
|
|
42
42
|
Chat, Agent, and Recovery each own a scheduler route and queue topic alongside
|
|
43
43
|
their contract and server. Each topic is created on first send, and its trigger
|
|
44
44
|
makes the scheduler route private (no public URL). Schedulers turn on
|
|
@@ -54,8 +54,11 @@ A2_QUEUES=1 pnpm dev
|
|
|
54
54
|
|
|
55
55
|
## 3. AI Gateway
|
|
56
56
|
|
|
57
|
-
The Agent demo uses the AI SDK with `openai/gpt-5.6-luna`,
|
|
58
|
-
|
|
57
|
+
The Agent demo uses the AI SDK with `openai/gpt-5.6-luna`, the Chat demo uses
|
|
58
|
+
`openai/gpt-5.4`, and A0 defaults to `anthropic/claude-opus-5.5` in fast mode;
|
|
59
|
+
the Agent demo and A0 let you pick another model, which the session keeps and
|
|
60
|
+
every client of it sees. All of them
|
|
61
|
+
resolve through Vercel AI Gateway. Vercel
|
|
59
62
|
deployments use their OIDC token automatically. For local generation, link the
|
|
60
63
|
project and pull its environment or set an `AI_GATEWAY_API_KEY`:
|
|
61
64
|
|
|
@@ -77,7 +80,50 @@ to later Bash calls in that conversation. Vercel deployments authenticate with
|
|
|
77
80
|
OIDC automatically; the `vercel link` and `vercel env pull` commands above
|
|
78
81
|
supply the same credentials during local development.
|
|
79
82
|
|
|
80
|
-
## 5.
|
|
83
|
+
## 5. A0's sandboxes
|
|
84
|
+
|
|
85
|
+
Each A0 app gets its own persistent Vercel Sandbox, started from a template
|
|
86
|
+
snapshot that already holds a blank Next.js app with its dependencies
|
|
87
|
+
installed and its dev cache warm. Build it once per project, with the same
|
|
88
|
+
credentials as above:
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
pnpm --filter playground a0:template
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
It takes about a minute and prints `A0_TEMPLATE_SNAPSHOT_ID=snap_…`. Set that
|
|
95
|
+
variable for local development and for each deployed environment. Add it to
|
|
96
|
+
the project's Development environment too, so `vercel env pull` brings it to
|
|
97
|
+
local runs; without it, A0 throws as soon as it opens a sandbox. The
|
|
98
|
+
snapshot never expires, and nothing else stays behind. Run the script again
|
|
99
|
+
when the recipe in `scripts/a0-template.ts` changes, then update the variable;
|
|
100
|
+
apps that already have a sandbox keep theirs.
|
|
101
|
+
|
|
102
|
+
A new app's sandbox opens as soon as the app is on screen, so it's ready by the
|
|
103
|
+
first prompt. If none comes within 10 minutes, a scheduled check deletes it.
|
|
104
|
+
A sandbox stays up while it's used: each tool call keeps it running at least
|
|
105
|
+
10 more minutes, and so does the preview while it's on screen. Otherwise it
|
|
106
|
+
stops, and resumes with its files the next time it's needed. A new or resumed
|
|
107
|
+
sandbox starts `next dev` in the background, so commands don't wait for it;
|
|
108
|
+
the preview does. Deleting an app stops its turn and deletes its sandbox; its
|
|
109
|
+
conversation stays in the log. An app nobody uses for 14 days loses its files.
|
|
110
|
+
|
|
111
|
+
App ids are the only access control: anyone with an A0 URL can open that app,
|
|
112
|
+
and anyone who can reach the deployment can start new apps, each with its own
|
|
113
|
+
sandbox and a public URL for the app the agent serves. Put
|
|
114
|
+
[Deployment Protection](https://vercel.com/docs/deployment-protection) in front
|
|
115
|
+
of a public deployment. A0's sandboxes are named `a2-a0-*`, which is where to
|
|
116
|
+
look when cleaning up. The sidebar lists the apps this browser opened, from a
|
|
117
|
+
cookie.
|
|
118
|
+
|
|
119
|
+
A0's dev tools have a Crash button, which ends the function instance running
|
|
120
|
+
an app's agent, mid-turn, so the scheduler resumes the turn in a fresh one.
|
|
121
|
+
Crashing ends everything else that instance is serving, so only preview
|
|
122
|
+
deployments allow it, behind Deployment Protection. Set `A0_CRASHES=on` to
|
|
123
|
+
allow it anywhere else. Under `next dev` that takes the dev server down with
|
|
124
|
+
it, so it's for trying recovery, not for everyday local runs.
|
|
125
|
+
|
|
126
|
+
## 6. WebSockets for the canvas
|
|
81
127
|
|
|
82
128
|
Deployed, the canvas demo upgrades its route to a WebSocket
|
|
83
129
|
(`experimental_upgradeWebSocket` from `@vercel/functions`, with `ws`
|
|
@@ -88,7 +134,7 @@ dev server drops the handshake), so the demo's session module picks
|
|
|
88
134
|
the SSE + POST pair in development — same route, same protocol
|
|
89
135
|
semantics, different wire.
|
|
90
136
|
|
|
91
|
-
##
|
|
137
|
+
## 7. Deploy
|
|
92
138
|
|
|
93
139
|
```sh
|
|
94
140
|
vercel deploy
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ReactNode } from 'react'
|
|
2
|
+
import { ColumnEdge } from '../columns'
|
|
3
|
+
|
|
4
|
+
/** The chat and preview columns, empty, while an app the server hasn't sent yet loads. */
|
|
5
|
+
export default function Loading(): ReactNode {
|
|
6
|
+
return (
|
|
7
|
+
<>
|
|
8
|
+
<section aria-label="Chat" aria-busy className="a0-chat">
|
|
9
|
+
<ColumnEdge column="chat" />
|
|
10
|
+
</section>
|
|
11
|
+
<section aria-label="Preview" aria-busy className="a0-preview">
|
|
12
|
+
<div className="a0-placeholder" />
|
|
13
|
+
</section>
|
|
14
|
+
</>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ReactNode } from 'react'
|
|
2
|
+
import { notFound } from 'next/navigation'
|
|
3
|
+
import { AppView } from '../app-view'
|
|
4
|
+
import { isAppId } from '../apps'
|
|
5
|
+
import { DevTools } from '../devtools'
|
|
6
|
+
import { logPage } from '../model'
|
|
7
|
+
import { agentServer, crashesAllowed } from '../server'
|
|
8
|
+
import { SessionProvider } from '../session'
|
|
9
|
+
|
|
10
|
+
/** An app, from its current state; the provider follows its log from there. */
|
|
11
|
+
export default async function A0App({
|
|
12
|
+
params,
|
|
13
|
+
searchParams,
|
|
14
|
+
}: {
|
|
15
|
+
params: Promise<{ appId: string }>
|
|
16
|
+
searchParams: Promise<Record<string, string | string[] | undefined>>
|
|
17
|
+
}): Promise<ReactNode> {
|
|
18
|
+
const { appId } = await params
|
|
19
|
+
if (!isAppId(appId)) notFound()
|
|
20
|
+
const initial = await agentServer.session(appId).state()
|
|
21
|
+
// Open dev tools show the log itself, starting with its latest page.
|
|
22
|
+
const events =
|
|
23
|
+
(await searchParams).devtools !== undefined && initial.index > 0
|
|
24
|
+
? await agentServer.session(appId).history({
|
|
25
|
+
gte: Math.max(1, initial.index - logPage + 1),
|
|
26
|
+
lte: initial.index,
|
|
27
|
+
})
|
|
28
|
+
: undefined
|
|
29
|
+
return (
|
|
30
|
+
<SessionProvider
|
|
31
|
+
key={appId}
|
|
32
|
+
sessionId={appId}
|
|
33
|
+
initial={initial}
|
|
34
|
+
initialEvents={events}
|
|
35
|
+
>
|
|
36
|
+
<AppView
|
|
37
|
+
appId={appId}
|
|
38
|
+
devtools={
|
|
39
|
+
<DevTools
|
|
40
|
+
appId={appId}
|
|
41
|
+
deployed={!!process.env.VERCEL}
|
|
42
|
+
crashesAllowed={crashesAllowed}
|
|
43
|
+
/>
|
|
44
|
+
}
|
|
45
|
+
/>
|
|
46
|
+
</SessionProvider>
|
|
47
|
+
)
|
|
48
|
+
}
|