experimental-a2 0.16.1 → 0.18.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 +373 -0
- package/README.md +1 -1
- package/dist/{actor-ohPC-81x.d.ts → actor-Bjce9_5U.d.ts} +21 -11
- package/dist/actor-Bjce9_5U.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-DgOBltJ_.js → ai-BpOGm-zB.js} +621 -216
- package/dist/ai-BpOGm-zB.js.map +1 -0
- package/dist/{ai-CrEf6p_W.d.ts → ai-DrUaMyRt.d.ts} +114 -100
- package/dist/ai-DrUaMyRt.d.ts.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-fx.browser.d.ts +1 -0
- package/dist/ai-fx.browser.js +6 -0
- package/dist/ai-fx.browser.js.map +1 -0
- package/dist/ai-fx.d.ts +10 -0
- package/dist/ai-fx.d.ts.map +1 -0
- package/dist/ai-fx.js +634 -0
- package/dist/ai-fx.js.map +1 -0
- package/dist/ai-harness-BuLh_EYi.js +273 -0
- package/dist/ai-harness-BuLh_EYi.js.map +1 -0
- package/dist/ai-harness-DvsPeJeB.d.ts +26 -0
- package/dist/ai-harness-DvsPeJeB.d.ts.map +1 -0
- package/dist/ai-pi.browser.d.ts +1 -0
- package/dist/ai-pi.browser.js +6 -0
- package/dist/ai-pi.browser.js.map +1 -0
- package/dist/ai-pi.d.ts +17 -0
- package/dist/ai-pi.d.ts.map +1 -0
- package/dist/ai-pi.js +904 -0
- package/dist/ai-pi.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 +109 -43
- package/dist/ai-server.d.ts.map +1 -1
- package/dist/ai-server.js +526 -283
- package/dist/ai-server.js.map +1 -1
- package/dist/ai.d.ts +2 -2
- package/dist/ai.js +2 -2
- package/dist/bounded-cache-CPHWF-8h.js +41 -0
- package/dist/bounded-cache-CPHWF-8h.js.map +1 -0
- package/dist/{client-BYzHjkwU.js → client-BReKqwZC.js} +447 -80
- package/dist/client-BReKqwZC.js.map +1 -0
- package/dist/{client-CzyacQpJ.d.ts → client-h_DKFAjj.d.ts} +14 -13
- package/dist/client-h_DKFAjj.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-Bx-c0pDP.d.ts} +7 -3
- package/dist/initial-snapshot-Bx-c0pDP.d.ts.map +1 -0
- package/dist/{internal-Dq2qYxou.js → internal-B2T3U4Rq.js} +29 -2
- package/dist/internal-B2T3U4Rq.js.map +1 -0
- package/dist/otel.d.ts +1 -1
- package/dist/react-BBXgHWFc.d.ts +86 -0
- package/dist/react-BBXgHWFc.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-CqA59Q6U.d.ts} +46 -30
- package/dist/reducer-CqA59Q6U.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-BD5ckxZb.js → server-Dw_k_7kO.js} +904 -219
- package/dist/server-Dw_k_7kO.js.map +1 -0
- package/dist/{server-DbD7IJVK.d.ts → server-En7cbi3v.d.ts} +116 -26
- package/dist/server-En7cbi3v.d.ts.map +1 -0
- package/dist/server.d.ts +4 -4
- package/dist/server.js +2 -2
- package/dist/session-clear-Bo-XTFEy.d.ts +12 -0
- package/dist/session-clear-Bo-XTFEy.d.ts.map +1 -0
- package/dist/{errors-DCk6ch5n.js → session-clear-DGI4jTQ5.js} +17 -2
- package/dist/session-clear-DGI4jTQ5.js.map +1 -0
- package/dist/{store-DyZM6fS5.d.ts → store-Djdv0bnZ.d.ts} +73 -3
- package/dist/store-Djdv0bnZ.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 +205 -66
- package/dist/store-memory.js.map +1 -1
- package/dist/{store-polling-CmxUbV93.js → store-polling-B5FcwJfo.js} +21 -4
- package/dist/store-polling-B5FcwJfo.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 +450 -108
- package/dist/store-postgres.js.map +1 -1
- package/dist/{store-presence-polling-C7-XZyW9.js → store-presence-polling-BAwS8RWn.js} +3 -3
- package/dist/{store-presence-polling-C7-XZyW9.js.map → store-presence-polling-BAwS8RWn.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-BRITti_o.js +2493 -0
- package/dist/store-redis-notify-BRITti_o.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 +197 -33
- 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-Cyfqo6Qt.d.ts} +2 -2
- package/dist/telemetry-Cyfqo6Qt.d.ts.map +1 -0
- package/dist/{wire-BO5wWCb1.js → wire-rSUglYo8.js} +132 -10
- package/dist/wire-rSUglYo8.js.map +1 -0
- package/docs/01-quickstart.mdx +50 -84
- package/docs/{guides/07-examples.mdx → 02-examples.mdx} +10 -20
- package/docs/actors/01-introduction.mdx +48 -82
- package/docs/actors/02-concurrency.mdx +43 -70
- package/docs/actors/03-timers.mdx +28 -42
- package/docs/actors/04-routes.mdx +110 -137
- package/docs/actors/meta.ts +1 -1
- package/docs/agents/01-introduction.mdx +257 -0
- package/docs/agents/02-tools.mdx +247 -0
- package/docs/agents/03-conversations.mdx +538 -0
- package/docs/agents/04-harnesses.mdx +136 -0
- package/docs/agents/meta.ts +1 -0
- package/docs/client/01-react.mdx +294 -0
- package/docs/client/02-transports.mdx +86 -0
- package/docs/client/03-presence.mdx +224 -0
- package/docs/client/meta.ts +1 -0
- package/docs/contract/01-events.mdx +57 -0
- package/docs/contract/02-state.mdx +142 -0
- package/docs/contract/03-sessions.mdx +175 -0
- package/docs/index.mdx +112 -156
- package/docs/reference/01-core.mdx +139 -0
- package/docs/reference/02-server.mdx +855 -0
- package/docs/reference/03-client.mdx +301 -0
- package/docs/reference/04-ai.mdx +722 -0
- package/docs/reference/05-adapters.mdx +351 -0
- package/docs/reference/06-errors.mdx +138 -0
- package/docs/reference/meta.ts +1 -1
- package/docs/server/01-handlers.mdx +200 -0
- package/docs/server/02-timers.mdx +130 -0
- package/docs/server/03-cancellation.mdx +141 -0
- package/docs/server/04-routes.mdx +243 -0
- package/docs/server/05-production.mdx +322 -0
- package/docs/server/06-guarantees.mdx +123 -0
- package/examples/playground/DEPLOY.md +53 -7
- package/examples/playground/app/a0/[appId]/loading.tsx +16 -0
- package/examples/playground/app/a0/[appId]/page.tsx +53 -0
- package/examples/playground/app/a0/a0.css +818 -0
- package/examples/playground/app/a0/app-list.tsx +218 -0
- package/examples/playground/app/a0/app-view.tsx +63 -0
- package/examples/playground/app/a0/apps/[appId]/preview/route.ts +27 -0
- package/examples/playground/app/a0/apps/[appId]/route.ts +28 -0
- package/examples/playground/app/a0/apps.test.ts +128 -0
- package/examples/playground/app/a0/apps.ts +102 -0
- package/examples/playground/app/a0/chat.tsx +410 -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/fx/events/route.ts +9 -0
- package/examples/playground/app/a0/fx/scheduler/route.ts +7 -0
- package/examples/playground/app/a0/fx/short/events/route.ts +11 -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 +73 -0
- package/examples/playground/app/a0/model.ts +95 -0
- package/examples/playground/app/a0/no-photon.cjs +4 -0
- package/examples/playground/app/a0/no-quickjs.cjs +3 -0
- package/examples/playground/app/a0/page.tsx +14 -0
- package/examples/playground/app/a0/pi/events/route.ts +9 -0
- package/examples/playground/app/a0/pi/scheduler/route.ts +7 -0
- package/examples/playground/app/a0/pi/short/events/route.ts +11 -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 +75 -0
- package/examples/playground/app/a0/sandbox-session.ts +152 -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 +213 -0
- package/examples/playground/app/a0/session.ts +59 -0
- package/examples/playground/app/a0/shell.tsx +158 -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 +101 -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 +19 -15
- package/examples/playground/app/agent/session.ts +5 -6
- package/examples/playground/app/agent/telemetry.test.ts +189 -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 +12 -12
- 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 +112 -0
- package/examples/playground/app/chat/server.ts +113 -117
- 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/next.config.ts +17 -5
- package/examples/playground/package.json +13 -2
- package/examples/playground/scripts/a0-template.ts +77 -0
- package/examples/playground/vercel.json +36 -0
- package/package.json +29 -3
- 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 +2517 -0
- package/src/ai-app-state.ts +91 -0
- package/src/ai-client-state.ts +6 -3
- 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 +92 -72
- package/src/ai-coordinator.ts +23 -22
- package/src/ai-fx.browser.ts +5 -0
- package/src/ai-fx.ts +833 -0
- package/src/ai-harness.ts +518 -0
- package/src/ai-message-base.ts +209 -0
- package/src/ai-message-projection.ts +262 -64
- package/src/ai-model-metadata.ts +11 -6
- package/src/ai-pi.browser.ts +5 -0
- package/src/ai-pi.ts +1263 -0
- 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-sdk-step.ts +2 -2
- package/src/ai-server.browser.ts +2 -2
- package/src/ai-server.ts +23 -1965
- package/src/ai-stored-state.ts +48 -163
- package/src/ai.ts +339 -155
- 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 +52 -0
- package/src/libfx.d.ts +34 -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 +93 -11
- 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 +1133 -255
- 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 +252 -75
- package/src/store-polling.ts +18 -4
- package/src/store-postgres.ts +541 -114
- package/src/store-redis-core.ts +1450 -493
- package/src/store-redis-http.ts +18 -2
- package/src/store-redis-notify.ts +262 -85
- package/src/store-redis.ts +19 -9
- package/src/store-sqlite.ts +319 -45
- package/src/store.ts +79 -1
- package/src/stream-buffer.ts +43 -0
- package/src/telemetry.ts +14 -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-CrEf6p_W.d.ts.map +0 -1
- package/dist/ai-DgOBltJ_.js.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/docs/concepts/01-contracts.mdx +0 -142
- package/docs/concepts/02-handlers.mdx +0 -284
- package/docs/concepts/03-durability.mdx +0 -314
- package/docs/concepts/04-state.mdx +0 -209
- package/docs/guides/01-timers.mdx +0 -185
- package/docs/guides/02-cancellation.mdx +0 -161
- package/docs/guides/03-react.mdx +0 -384
- package/docs/guides/04-local-first.mdx +0 -88
- package/docs/guides/05-production.mdx +0 -521
- package/docs/guides/06-ai-agents.mdx +0 -1318
- package/docs/guides/08-application-data.mdx +0 -113
- package/docs/guides/09-presence.mdx +0 -266
- package/docs/guides/10-transports.mdx +0 -221
- package/docs/reference/01-api.mdx +0 -1896
- package/docs/reference/02-errors.mdx +0 -149
- 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
- /package/docs/{concepts → contract}/meta.ts +0 -0
- /package/docs/{guides → server}/meta.ts +0 -0
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Errors
|
|
3
|
-
description: Stable server and client error codes, transport details, and append guarantees.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
## `A2Error`
|
|
7
|
-
|
|
8
|
-
A2 failures carry an `A2Error` with a stable `code`. The session client exposes
|
|
9
|
-
`A2ClientError`, which extends `A2Error`, for both server failures and failures
|
|
10
|
-
observed locally. Existing `instanceof A2Error` checks also match client errors.
|
|
11
|
-
|
|
12
|
-
```ts
|
|
13
|
-
// e.g. in a route handler:
|
|
14
|
-
import { A2Error } from 'experimental-a2'
|
|
15
|
-
|
|
16
|
-
export async function POST(req: Request) {
|
|
17
|
-
const { orderId, payload } = await req.json()
|
|
18
|
-
try {
|
|
19
|
-
const events = await ordersServer
|
|
20
|
-
.session(orderId)
|
|
21
|
-
.append({ type: 'created', payload })
|
|
22
|
-
return Response.json(events)
|
|
23
|
-
} catch (err) {
|
|
24
|
-
if (err instanceof A2Error && err.code === 'INVALID_PAYLOAD') {
|
|
25
|
-
// err.details carries the schema issues, in Standard Schema format
|
|
26
|
-
return Response.json({ issues: err.details }, { status: 400 })
|
|
27
|
-
}
|
|
28
|
-
throw err
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## The codes
|
|
34
|
-
|
|
35
|
-
| Code | Thrown when | Retryable |
|
|
36
|
-
| ------------------------- | ------------------------------------------------------------------ | --------- |
|
|
37
|
-
| `INVALID_PAYLOAD` | a payload fails its schema; nothing was written, and `details` carries the issues ([Standard Schema](https://standardschema.dev) format) | no |
|
|
38
|
-
| `FORBIDDEN` | `server.fetch` authorization denies a parsed stream, history read, push, or presence update | no |
|
|
39
|
-
| `UNKNOWN_EVENT_TYPE` | an event type isn't in the contract's `events` map | no |
|
|
40
|
-
| `UNKNOWN_PRESENCE_FIELD` | a presence field isn't in the contract's `presence` map | no |
|
|
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
|
-
| `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, the successor owns the event. Also the abort reason on that handler's `ctx.signal` | no |
|
|
44
|
-
| `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
|
-
| `STORE_UNAVAILABLE` | the store backend failed; nothing was written, original error as `cause` | **yes** |
|
|
46
|
-
| `STORE_NOT_CONFIGURED` | production boot with no `store` configured (during `next build` page collection, deferred to first use) | no |
|
|
47
|
-
|
|
48
|
-
Of these server codes, only `STORE_UNAVAILABLE` is automatically retried by
|
|
49
|
-
client pushes. Reconnection has its own caller-configurable policy.
|
|
50
|
-
|
|
51
|
-
## `A2ClientError`
|
|
52
|
-
|
|
53
|
-
Import `A2ClientError` from `experimental-a2/client`. Connection failures,
|
|
54
|
-
push failures, history read failures, and local A2 validation failures use
|
|
55
|
-
this class. Server failures keep their `code`, `message`, and `details`.
|
|
56
|
-
Unexpected thrown values are retained as `cause`. Invalid API arguments can
|
|
57
|
-
still throw native `TypeError` or `RangeError` exceptions.
|
|
58
|
-
|
|
59
|
-
| Client code | Meaning |
|
|
60
|
-
| --- | --- |
|
|
61
|
-
| `TIMEOUT` | A2 detected a stream stall or an unconfirmed subscription. `phase` is `stream` or `subscribe`; `timeoutMs` is the expired deadline. |
|
|
62
|
-
| `HTTP_ERROR` | An unsuccessful HTTP response without a recognized A2 error body. `status` carries the HTTP status. |
|
|
63
|
-
| `CONNECTION_FAILED` | The transport could not establish or retain a connection. WebSocket close events preserve `closeCode` and `closeReason` when available. |
|
|
64
|
-
| `UNKNOWN` | An unexpected client failure. The original value is available as `cause`. |
|
|
65
|
-
|
|
66
|
-
HTTP failures retain `status` even when they carry a recognized server code.
|
|
67
|
-
A browser WebSocket handshake rejection has no readable HTTP status or body;
|
|
68
|
-
it remains `CONNECTION_FAILED`. A2 does not infer an authorization failure or
|
|
69
|
-
a timeout from an opaque socket error.
|
|
70
|
-
|
|
71
|
-
The stream watchdog detects 35 seconds of silence after connection. A
|
|
72
|
-
multiplexed subscription also has 35 seconds to receive confirmation. There
|
|
73
|
-
is no A2-owned initial connection deadline for HTTP or single-session
|
|
74
|
-
WebSockets. Clean stream termination has no error: the reconnection callback
|
|
75
|
-
and connection snapshot carry `null`.
|
|
76
|
-
|
|
77
|
-
Pushes retain their three-attempt budget for `STORE_UNAVAILABLE` and client
|
|
78
|
-
transport failures. The reconnection callback controls only the live stream.
|
|
79
|
-
Pausing that stream preserves the writer; it does not guarantee that a push
|
|
80
|
-
can succeed while its WebSocket is unavailable.
|
|
81
|
-
|
|
82
|
-
On `PARTIAL_DUPLICATE_BATCH`: retrying an *identical* batch is not an
|
|
83
|
-
error. It's an idempotent success, and you get the previously appended
|
|
84
|
-
events back. Mixing already-sent events with fresh ones in a single batch
|
|
85
|
-
is always a caller bug, so A2 refuses it rather than quietly reinterpret
|
|
86
|
-
what "atomic" meant. The same code covers two adjacent bugs: a batch that
|
|
87
|
-
contains the same id twice, and an id that was already used in a
|
|
88
|
-
*different* session (event ids are globally unique). In every case,
|
|
89
|
-
nothing is written.
|
|
90
|
-
|
|
91
|
-
## NonRetriableError
|
|
92
|
-
|
|
93
|
-
Throw it (or a subclass, matched by
|
|
94
|
-
`instanceof`) from a handler when the failure is deterministic: the
|
|
95
|
-
event dead-letters immediately instead of consuming the ten-failure
|
|
96
|
-
retry budget, because a guard that refuses this attempt will refuse
|
|
97
|
-
every retry identically. Any other thrown error keeps the ordinary
|
|
98
|
-
retry contract.
|
|
99
|
-
|
|
100
|
-
```ts
|
|
101
|
-
import { z } from 'zod'
|
|
102
|
-
import * as a2 from 'experimental-a2'
|
|
103
|
-
import { NonRetriableError } from 'experimental-a2'
|
|
104
|
-
import { createServer } from 'experimental-a2/server'
|
|
105
|
-
|
|
106
|
-
const orders = a2.contract({
|
|
107
|
-
name: 'orders',
|
|
108
|
-
events: { created: z.object({ chargeable: z.boolean() }) },
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
export const ordersServer = createServer({
|
|
112
|
-
contract: orders,
|
|
113
|
-
handlers: {
|
|
114
|
-
created: async ({ event }) => {
|
|
115
|
-
if (!event.payload.chargeable) {
|
|
116
|
-
throw new NonRetriableError('this order cannot be charged')
|
|
117
|
-
}
|
|
118
|
-
// transient failures below retry as usual
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
})
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
## What append never throws for
|
|
125
|
-
|
|
126
|
-
- **A failing handler.** Appends always land; handler failures are retried
|
|
127
|
-
and, if persistent, [dead-letter the event](/concepts/durability#when-a-handler-keeps-failing).
|
|
128
|
-
`append` never fails because a downstream handler is failing.
|
|
129
|
-
- **A duplicate of an identical batch.** That's a lost ack, not a bug.
|
|
130
|
-
|
|
131
|
-
## Over the wire
|
|
132
|
-
|
|
133
|
-
The push route serializes an `A2Error` as:
|
|
134
|
-
|
|
135
|
-
```json
|
|
136
|
-
{ "error": { "code": "INVALID_PAYLOAD", "message": "...", "details": [] } }
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
with a mapped status: `INVALID_PAYLOAD`, `UNKNOWN_EVENT_TYPE`, and
|
|
140
|
-
`PARTIAL_DUPLICATE_BATCH` are 400; `FORBIDDEN` is 403;
|
|
141
|
-
`SUPERSEDED_ATTEMPT` is 409; `STORE_UNAVAILABLE` is 503.
|
|
142
|
-
|
|
143
|
-
The session client deserializes the body into an `A2ClientError`, so client
|
|
144
|
-
and server code branch on identical server codes. `server.fetch` owns HTTP
|
|
145
|
-
serialization. Multiplexed WebSocket subscription failures carry the same
|
|
146
|
-
error envelope in their `unsubscribed` frame, alongside the legacy `reason`
|
|
147
|
-
string. Older reason-only frames remain readable as `CONNECTION_FAILED`.
|
|
148
|
-
Unknown server exceptions become `STORE_UNAVAILABLE`; their private causes
|
|
149
|
-
are not sent to clients.
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { updateCompactionSettings } from '../../compaction-settings'
|
|
2
|
-
import { agentServer } from '../../server'
|
|
3
|
-
|
|
4
|
-
export async function POST(
|
|
5
|
-
request: Request,
|
|
6
|
-
context: { params: Promise<{ agentId: string }> },
|
|
7
|
-
): Promise<Response> {
|
|
8
|
-
const { agentId } = await context.params
|
|
9
|
-
return updateCompactionSettings({
|
|
10
|
-
request,
|
|
11
|
-
sessionId: agentId,
|
|
12
|
-
append: (event) => agentServer.session(agentId).append(event),
|
|
13
|
-
})
|
|
14
|
-
}
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { expect, it } from 'vitest'
|
|
2
|
-
import { createAgentServer } from 'experimental-a2/ai/server'
|
|
3
|
-
import { memory } from 'experimental-a2/store-memory'
|
|
4
|
-
import {
|
|
5
|
-
compactionOptions,
|
|
6
|
-
compactionSettings,
|
|
7
|
-
demoAgent,
|
|
8
|
-
latestCompactionSettings,
|
|
9
|
-
} from './model'
|
|
10
|
-
import { updateCompactionSettings } from './compaction-settings'
|
|
11
|
-
|
|
12
|
-
const request = (
|
|
13
|
-
settings: unknown,
|
|
14
|
-
options: { origin?: string; contentType?: string; id?: string } = {},
|
|
15
|
-
): Request =>
|
|
16
|
-
new Request('https://example.test/agent/session/compaction', {
|
|
17
|
-
method: 'POST',
|
|
18
|
-
headers: {
|
|
19
|
-
origin: options.origin ?? 'https://example.test',
|
|
20
|
-
'content-type': options.contentType ?? 'application/json',
|
|
21
|
-
},
|
|
22
|
-
body: JSON.stringify({ id: options.id ?? crypto.randomUUID(), settings }),
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
it('uses the request Host when Next normalizes the internal URL', async () => {
|
|
26
|
-
let writes = 0
|
|
27
|
-
const response = await updateCompactionSettings({
|
|
28
|
-
request: new Request('http://localhost:3107/agent/s/compaction', {
|
|
29
|
-
method: 'POST',
|
|
30
|
-
headers: {
|
|
31
|
-
host: '127.0.0.1:3107',
|
|
32
|
-
origin: 'http://127.0.0.1:3107',
|
|
33
|
-
'content-type': 'application/json',
|
|
34
|
-
},
|
|
35
|
-
body: JSON.stringify({
|
|
36
|
-
id: crypto.randomUUID(),
|
|
37
|
-
settings: { mode: 'manual', thresholdTokens: 1 },
|
|
38
|
-
}),
|
|
39
|
-
}),
|
|
40
|
-
sessionId: 's',
|
|
41
|
-
append: async () => {
|
|
42
|
-
writes += 1
|
|
43
|
-
},
|
|
44
|
-
})
|
|
45
|
-
expect(response.status).toBe(200)
|
|
46
|
-
expect(writes).toBe(1)
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it('saves session settings durably and idempotently without starting a turn', async () => {
|
|
50
|
-
let generations = 0
|
|
51
|
-
const server = createAgentServer({
|
|
52
|
-
agent: demoAgent,
|
|
53
|
-
store: memory(),
|
|
54
|
-
model: 'test/model',
|
|
55
|
-
compaction: async ({ session }) =>
|
|
56
|
-
compactionOptions((await session.state(compactionSettings)).state),
|
|
57
|
-
generate: () => {
|
|
58
|
-
generations += 1
|
|
59
|
-
return new ReadableStream({
|
|
60
|
-
start(controller) {
|
|
61
|
-
controller.close()
|
|
62
|
-
},
|
|
63
|
-
})
|
|
64
|
-
},
|
|
65
|
-
})
|
|
66
|
-
const session = server.session('settings-test')
|
|
67
|
-
const id = crypto.randomUUID()
|
|
68
|
-
const save = () =>
|
|
69
|
-
updateCompactionSettings({
|
|
70
|
-
request: request({ mode: 'manual', thresholdTokens: 1 }, { id }),
|
|
71
|
-
sessionId: session.id,
|
|
72
|
-
append: (event) => session.append(event),
|
|
73
|
-
})
|
|
74
|
-
expect((await save()).status).toBe(200)
|
|
75
|
-
expect((await save()).status).toBe(200)
|
|
76
|
-
await server.drain(session.id)
|
|
77
|
-
const history = await session.history()
|
|
78
|
-
expect(history.map((event) => event.type)).toEqual([
|
|
79
|
-
'compaction.settings.updated',
|
|
80
|
-
])
|
|
81
|
-
expect(latestCompactionSettings(history).settings).toEqual({
|
|
82
|
-
mode: 'manual',
|
|
83
|
-
thresholdTokens: 1,
|
|
84
|
-
})
|
|
85
|
-
expect(
|
|
86
|
-
compactionOptions((await session.state(compactionSettings)).state),
|
|
87
|
-
).toEqual({ thresholdTokens: 1 })
|
|
88
|
-
expect(
|
|
89
|
-
compactionOptions(
|
|
90
|
-
(await server.session('other').state(compactionSettings)).state,
|
|
91
|
-
),
|
|
92
|
-
).toEqual({})
|
|
93
|
-
expect(generations).toBe(0)
|
|
94
|
-
|
|
95
|
-
await updateCompactionSettings({
|
|
96
|
-
request: request({ mode: 'disabled' }),
|
|
97
|
-
sessionId: session.id,
|
|
98
|
-
append: (event) => session.append(event),
|
|
99
|
-
})
|
|
100
|
-
expect(
|
|
101
|
-
compactionOptions((await session.state(compactionSettings)).state),
|
|
102
|
-
).toBe(false)
|
|
103
|
-
await updateCompactionSettings({
|
|
104
|
-
request: request({ mode: 'automatic' }),
|
|
105
|
-
sessionId: session.id,
|
|
106
|
-
append: (event) => session.append(event),
|
|
107
|
-
})
|
|
108
|
-
expect(
|
|
109
|
-
compactionOptions((await session.state(compactionSettings)).state),
|
|
110
|
-
).toEqual({})
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
it.each([0, -1, 1.5, Number.MAX_SAFE_INTEGER + 1, '1', null])(
|
|
114
|
-
'rejects invalid threshold %s',
|
|
115
|
-
async (thresholdTokens) => {
|
|
116
|
-
let writes = 0
|
|
117
|
-
const response = await updateCompactionSettings({
|
|
118
|
-
request: request({ mode: 'manual', thresholdTokens }),
|
|
119
|
-
sessionId: 's',
|
|
120
|
-
append: async () => {
|
|
121
|
-
writes += 1
|
|
122
|
-
},
|
|
123
|
-
})
|
|
124
|
-
expect(response.status).toBe(400)
|
|
125
|
-
expect(writes).toBe(0)
|
|
126
|
-
},
|
|
127
|
-
)
|
|
128
|
-
|
|
129
|
-
it.each([
|
|
130
|
-
{ origin: 'https://other.test', status: 403 },
|
|
131
|
-
{ contentType: 'text/plain', status: 415 },
|
|
132
|
-
{ id: 'not-an-id', status: 400 },
|
|
133
|
-
])('rejects invalid request boundaries %j', async ({ status, ...options }) => {
|
|
134
|
-
let writes = 0
|
|
135
|
-
const response = await updateCompactionSettings({
|
|
136
|
-
request: request({ mode: 'automatic' }, options),
|
|
137
|
-
sessionId: 's',
|
|
138
|
-
append: async () => {
|
|
139
|
-
writes += 1
|
|
140
|
-
},
|
|
141
|
-
})
|
|
142
|
-
expect(response.status).toBe(status)
|
|
143
|
-
expect(writes).toBe(0)
|
|
144
|
-
})
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod'
|
|
2
|
-
import { compactionSettingsSchema, type CompactionSettings } from './model'
|
|
3
|
-
|
|
4
|
-
const updateSchema = z.strictObject({
|
|
5
|
-
id: z.uuid(),
|
|
6
|
-
settings: compactionSettingsSchema,
|
|
7
|
-
})
|
|
8
|
-
|
|
9
|
-
export async function updateCompactionSettings(options: {
|
|
10
|
-
request: Request
|
|
11
|
-
sessionId: string
|
|
12
|
-
append: (event: {
|
|
13
|
-
id: string
|
|
14
|
-
type: 'compaction.settings.updated'
|
|
15
|
-
payload: CompactionSettings
|
|
16
|
-
}) => Promise<unknown>
|
|
17
|
-
}): Promise<Response> {
|
|
18
|
-
const { request, sessionId } = options
|
|
19
|
-
const origin = request.headers.get('origin')
|
|
20
|
-
const requestUrl = new URL(request.url)
|
|
21
|
-
requestUrl.host = request.headers.get('host') ?? requestUrl.host
|
|
22
|
-
if (origin !== null && origin !== requestUrl.origin) {
|
|
23
|
-
return Response.json(
|
|
24
|
-
{ error: 'Use this page to update compaction settings.' },
|
|
25
|
-
{ status: 403 },
|
|
26
|
-
)
|
|
27
|
-
}
|
|
28
|
-
if (
|
|
29
|
-
request.headers.get('content-type')?.split(';')[0]?.trim() !==
|
|
30
|
-
'application/json'
|
|
31
|
-
) {
|
|
32
|
-
return Response.json({ error: 'Expected JSON settings.' }, { status: 415 })
|
|
33
|
-
}
|
|
34
|
-
if (sessionId.length === 0)
|
|
35
|
-
return Response.json({ error: 'Session is required.' }, { status: 400 })
|
|
36
|
-
const parsed = updateSchema.safeParse(await request.json().catch(() => null))
|
|
37
|
-
if (!parsed.success) {
|
|
38
|
-
return Response.json(
|
|
39
|
-
{ error: 'Choose a mode and a positive whole-number threshold.' },
|
|
40
|
-
{ status: 400 },
|
|
41
|
-
)
|
|
42
|
-
}
|
|
43
|
-
await options.append({
|
|
44
|
-
id: `agent.compaction.settings:${encodeURIComponent(sessionId)}:${parsed.data.id}`,
|
|
45
|
-
type: 'compaction.settings.updated',
|
|
46
|
-
payload: parsed.data.settings,
|
|
47
|
-
})
|
|
48
|
-
return Response.json({ settings: parsed.data.settings })
|
|
49
|
-
}
|