experimental-a2 0.20.0 → 0.22.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 +55 -0
- package/README.md +1 -1
- package/dist/{actor-C7b-1arn.d.ts → actor-CqibLgjQ.d.ts} +15 -7
- package/dist/actor-CqibLgjQ.d.ts.map +1 -0
- package/dist/actor-client.d.ts +1 -1
- package/dist/actor-client.js +2 -2
- package/dist/actor-react.d.ts +3 -3
- package/dist/actor-react.js +5 -5
- package/dist/{actor-shared-t7w8xIKP.js → actor-shared-DFET5q16.js} +3 -3
- package/dist/actor-shared-DFET5q16.js.map +1 -0
- package/dist/actor.d.ts +1 -1
- package/dist/actor.js +54 -43
- package/dist/actor.js.map +1 -1
- package/dist/{ai-Cz3hqVhk.d.ts → ai-DAu77CDr.d.ts} +8 -8
- package/dist/{ai-Cz3hqVhk.d.ts.map → ai-DAu77CDr.d.ts.map} +1 -1
- package/dist/{ai-mMiWul1T.js → ai-EEfKyc-z.js} +9 -9
- package/dist/ai-EEfKyc-z.js.map +1 -0
- package/dist/ai-client.d.ts +2 -2
- package/dist/ai-client.js +2 -2
- package/dist/ai-fx.d.ts +4 -2
- package/dist/ai-fx.d.ts.map +1 -1
- package/dist/ai-fx.js +214 -67
- package/dist/ai-fx.js.map +1 -1
- package/dist/{ai-harness-CV6rXbB3.d.ts → ai-harness-DTjkAr2T.d.ts} +2 -2
- package/dist/{ai-harness-CV6rXbB3.d.ts.map → ai-harness-DTjkAr2T.d.ts.map} +1 -1
- package/dist/{ai-harness-Clbg5ei7.js → ai-harness-dQeJaR1t.js} +7 -3
- package/dist/ai-harness-dQeJaR1t.js.map +1 -0
- package/dist/ai-pi.d.ts +1 -1
- package/dist/ai-pi.js +3 -3
- package/dist/ai-pi.js.map +1 -1
- package/dist/ai-react.d.ts +5 -5
- package/dist/ai-react.js +2 -2
- package/dist/ai-server.d.ts +14 -17
- package/dist/ai-server.d.ts.map +1 -1
- package/dist/ai-server.js +86 -73
- package/dist/ai-server.js.map +1 -1
- package/dist/ai.d.ts +2 -2
- package/dist/ai.js +2 -2
- package/dist/{client-BhHLoNKF.js → client-BQS4i_V9.js} +29 -6
- package/dist/client-BQS4i_V9.js.map +1 -0
- package/dist/{client-h_DKFAjj.d.ts → client-CUMbS_38.d.ts} +3 -3
- package/dist/{client-h_DKFAjj.d.ts.map → client-CUMbS_38.d.ts.map} +1 -1
- package/dist/client.d.ts +3 -3
- package/dist/client.js +1 -1
- package/dist/{contract-BYKASlCV.js → contract-CWukt01d.js} +2 -2
- package/dist/contract-CWukt01d.js.map +1 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.js +3 -3
- package/dist/{initial-snapshot-Bx-c0pDP.d.ts → initial-snapshot-D3Lve43o.d.ts} +4 -4
- package/dist/initial-snapshot-D3Lve43o.d.ts.map +1 -0
- package/dist/{internal-CscSY7K_.js → internal-CvsrprnU.js} +40 -16
- package/dist/internal-CvsrprnU.js.map +1 -0
- package/dist/otel.d.ts +1 -1
- package/dist/otel.js +1 -1
- package/dist/otel.js.map +1 -1
- package/dist/{react-BBXgHWFc.d.ts → react-BoHvC3v9.d.ts} +4 -4
- package/dist/{react-BBXgHWFc.d.ts.map → react-BoHvC3v9.d.ts.map} +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/{reducer-CqA59Q6U.d.ts → reducer-CYPHsSmd.d.ts} +2 -2
- package/dist/{reducer-CqA59Q6U.d.ts.map → reducer-CYPHsSmd.d.ts.map} +1 -1
- package/dist/{reducer-BAXc8JyF.js → reducer-CjmvZSAb.js} +2 -2
- package/dist/{reducer-BAXc8JyF.js.map → reducer-CjmvZSAb.js.map} +1 -1
- package/dist/runtime-consumer-CIeL33wj.js +12 -0
- package/dist/runtime-consumer-CIeL33wj.js.map +1 -0
- package/dist/scheduler-qstash.d.ts +2 -2
- package/dist/scheduler-qstash.js +3 -3
- package/dist/scheduler-task-X1SToDjP.js.map +1 -1
- package/dist/scheduler-vercel.d.ts +2 -2
- package/dist/scheduler-vercel.js +3 -3
- package/dist/scheduler-vercel.js.map +1 -1
- package/dist/{server-qyb5aJJG.js → server-DtFrWxi3.js} +412 -116
- package/dist/server-DtFrWxi3.js.map +1 -0
- package/dist/{server-DYAATFuT.d.ts → server-qgez0Xny.d.ts} +108 -41
- package/dist/server-qgez0Xny.d.ts.map +1 -0
- package/dist/server.browser.js +1 -1
- package/dist/server.browser.js.map +1 -1
- package/dist/server.d.ts +4 -4
- package/dist/server.js +2 -2
- package/dist/{session-clear-C-QwTXV1.d.ts → session-clear-D1PFe7xl.d.ts} +2 -2
- package/dist/session-clear-D1PFe7xl.d.ts.map +1 -0
- package/dist/{session-clear-DGI4jTQ5.js → session-clear-wHd5GCpZ.js} +5 -4
- package/dist/session-clear-wHd5GCpZ.js.map +1 -0
- package/dist/store-D0MhBvg6.d.ts +532 -0
- package/dist/store-D0MhBvg6.d.ts.map +1 -0
- package/dist/store-N8PXxDAS.js.map +1 -1
- package/dist/store-codec-DwrWlgQx.js +65 -0
- package/dist/store-codec-DwrWlgQx.js.map +1 -0
- package/dist/store-memory.d.ts +1 -1
- package/dist/store-memory.d.ts.map +1 -1
- package/dist/store-memory.js +406 -225
- package/dist/store-memory.js.map +1 -1
- package/dist/{store-polling-7WJV0YWP.js → store-polling-BZt2Rf3D.js} +2 -2
- package/dist/{store-polling-7WJV0YWP.js.map → store-polling-BZt2Rf3D.js.map} +1 -1
- package/dist/store-postgres.d.ts +1 -1
- package/dist/store-postgres.d.ts.map +1 -1
- package/dist/store-postgres.js +1598 -587
- package/dist/store-postgres.js.map +1 -1
- package/dist/store-presence-polling-JuAy2Ck2.js +111 -0
- package/dist/store-presence-polling-JuAy2Ck2.js.map +1 -0
- package/dist/store-redis-http.d.ts +1 -1
- package/dist/store-redis-http.js +4 -4
- package/dist/store-redis-notify-CsJw_hfD.js +3060 -0
- package/dist/store-redis-notify-CsJw_hfD.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 +4 -5
- 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 +527 -299
- package/dist/store-sqlite.js.map +1 -1
- package/dist/stream-buffer-DrTyiIuo.js +57 -0
- package/dist/stream-buffer-DrTyiIuo.js.map +1 -0
- package/dist/{telemetry-Cyfqo6Qt.d.ts → telemetry-CWwsh-Gx.d.ts} +3 -3
- package/dist/telemetry-CWwsh-Gx.d.ts.map +1 -0
- package/dist/{wire-BKxH1vbP.js → wire-CV-Z7wz-.js} +6 -5
- package/dist/wire-CV-Z7wz-.js.map +1 -0
- package/docs/01-quickstart.mdx +21 -15
- package/docs/02-examples.mdx +1 -1
- package/docs/actors/01-introduction.mdx +13 -2
- package/docs/actors/02-concurrency.mdx +1 -1
- package/docs/agents/01-introduction.mdx +1 -1
- package/docs/agents/02-tools.mdx +12 -11
- package/docs/agents/03-conversations.mdx +36 -25
- package/docs/agents/04-harnesses.mdx +14 -7
- package/docs/client/03-presence.mdx +18 -14
- package/docs/contract/01-events.mdx +2 -2
- package/docs/contract/02-state.mdx +18 -14
- package/docs/contract/03-sessions.mdx +32 -25
- package/docs/index.mdx +29 -24
- package/docs/reference/01-core.mdx +7 -6
- package/docs/reference/02-server.mdx +250 -191
- package/docs/reference/04-ai.mdx +33 -23
- package/docs/reference/05-telemetry.mdx +27 -13
- package/docs/reference/06-errors.mdx +25 -19
- package/docs/reference/meta.ts +1 -1
- package/docs/schedulers/01-overview.mdx +8 -8
- package/docs/schedulers/02-vercel-queues.mdx +2 -2
- package/docs/schedulers/03-qstash.mdx +4 -4
- package/docs/server/01-consumers.mdx +418 -0
- package/docs/server/02-timers.mdx +31 -21
- package/docs/server/03-cancellation.mdx +52 -44
- package/docs/server/04-routes.mdx +4 -1
- package/docs/server/05-sql-projections.mdx +391 -0
- package/docs/server/06-guarantees.mdx +61 -51
- package/docs/stores/01-overview.mdx +3 -3
- package/docs/stores/02-redis.mdx +24 -10
- package/docs/stores/03-redis-http.mdx +8 -6
- package/docs/stores/04-postgres.mdx +65 -14
- package/docs/stores/05-sqlite.mdx +5 -3
- package/docs/upgrades/01-overview.mdx +31 -0
- package/docs/upgrades/78-0-22.mdx +115 -0
- package/docs/upgrades/79-0-21.mdx +165 -0
- package/docs/upgrades/80-0-20.mdx +43 -0
- package/docs/upgrades/81-0-19.mdx +33 -0
- package/docs/upgrades/82-0-18.mdx +33 -0
- package/docs/upgrades/83-0-17.mdx +69 -0
- package/docs/upgrades/meta.ts +3 -0
- package/examples/playground/DEPLOY.md +39 -7
- package/examples/playground/app/a0/chat.test.tsx +2 -2
- package/examples/playground/app/a0/sandbox-log.ts +17 -15
- package/examples/playground/app/a0/sandbox.ts +58 -13
- package/examples/playground/app/a0/server.ts +4 -4
- package/examples/playground/app/a2slack/a2slack.css +1067 -0
- package/examples/playground/app/a2slack/c/[channel]/page.tsx +20 -0
- package/examples/playground/app/a2slack/consumers/agent.ts +63 -0
- package/examples/playground/app/a2slack/consumers/feed.ts +164 -0
- package/examples/playground/app/a2slack/consumers/notify.ts +116 -0
- package/examples/playground/app/a2slack/consumers/search.ts +37 -0
- package/examples/playground/app/a2slack/consumers/triage.ts +31 -0
- package/examples/playground/app/a2slack/consumers/welcome.ts +25 -0
- package/examples/playground/app/a2slack/db/a2.ts +209 -0
- package/examples/playground/app/a2slack/db/index.ts +73 -0
- package/examples/playground/app/a2slack/db/migrations/0000_extensions.sql +4 -0
- package/examples/playground/app/a2slack/db/migrations/0001_workspace.sql +74 -0
- package/examples/playground/app/a2slack/db/migrations/0002_a2.sql +215 -0
- package/examples/playground/app/a2slack/db/migrations/0003_a2_batch.sql +67 -0
- package/examples/playground/app/a2slack/db/migrations/0004_a2_session_event_ids.sql +2 -0
- package/examples/playground/app/a2slack/db/migrations/meta/0000_snapshot.json +18 -0
- package/examples/playground/app/a2slack/db/migrations/meta/0001_snapshot.json +500 -0
- package/examples/playground/app/a2slack/db/migrations/meta/0002_snapshot.json +1159 -0
- package/examples/playground/app/a2slack/db/migrations/meta/0003_snapshot.json +1159 -0
- package/examples/playground/app/a2slack/db/migrations/meta/0004_snapshot.json +1165 -0
- package/examples/playground/app/a2slack/db/migrations/meta/_journal.json +41 -0
- package/examples/playground/app/a2slack/db/queries.ts +263 -0
- package/examples/playground/app/a2slack/db/schema.ts +145 -0
- package/examples/playground/app/a2slack/drills/a2slack.drill.ts +708 -0
- package/examples/playground/app/a2slack/drills/harness.ts +244 -0
- package/examples/playground/app/a2slack/events/route.ts +36 -0
- package/examples/playground/app/a2slack/identity.ts +44 -0
- package/examples/playground/app/a2slack/inbox/route.ts +8 -0
- package/examples/playground/app/a2slack/lag/data/route.ts +8 -0
- package/examples/playground/app/a2slack/lag/page.tsx +101 -0
- package/examples/playground/app/a2slack/lag.ts +73 -0
- package/examples/playground/app/a2slack/layout.tsx +43 -0
- package/examples/playground/app/a2slack/messages/route.ts +17 -0
- package/examples/playground/app/a2slack/model.test.ts +208 -0
- package/examples/playground/app/a2slack/model.ts +369 -0
- package/examples/playground/app/a2slack/models.test.ts +72 -0
- package/examples/playground/app/a2slack/page.tsx +10 -0
- package/examples/playground/app/a2slack/scheduler/route.ts +5 -0
- package/examples/playground/app/a2slack/search/route.ts +40 -0
- package/examples/playground/app/a2slack/search-index.ts +108 -0
- package/examples/playground/app/a2slack/server.test.ts +315 -0
- package/examples/playground/app/a2slack/server.ts +55 -0
- package/examples/playground/app/a2slack/sessions.ts +50 -0
- package/examples/playground/app/a2slack/thread/route.ts +8 -0
- package/examples/playground/app/a2slack/ui/ChannelView.tsx +87 -0
- package/examples/playground/app/a2slack/ui/Composer.tsx +117 -0
- package/examples/playground/app/a2slack/ui/DotsShadow.tsx +42 -0
- package/examples/playground/app/a2slack/ui/Feed.tsx +157 -0
- package/examples/playground/app/a2slack/ui/InboxContext.tsx +63 -0
- package/examples/playground/app/a2slack/ui/InboxView.tsx +82 -0
- package/examples/playground/app/a2slack/ui/Menu.tsx +128 -0
- package/examples/playground/app/a2slack/ui/MessageRow.tsx +314 -0
- package/examples/playground/app/a2slack/ui/NameGate.tsx +35 -0
- package/examples/playground/app/a2slack/ui/SearchContext.tsx +146 -0
- package/examples/playground/app/a2slack/ui/SearchResults.tsx +97 -0
- package/examples/playground/app/a2slack/ui/Shell.tsx +34 -0
- package/examples/playground/app/a2slack/ui/Sidebar.tsx +199 -0
- package/examples/playground/app/a2slack/ui/ThreadPanel.tsx +134 -0
- package/examples/playground/app/a2slack/ui/useInbox.ts +71 -0
- package/examples/playground/app/agent/server.ts +3 -3
- package/examples/playground/app/chat/[chatId]/chat-client.tsx +1 -1
- package/examples/playground/app/chat/server.ts +45 -35
- package/examples/playground/app/components/demo-icons.tsx +7 -0
- package/examples/playground/app/components/demos.tsx +7 -0
- package/examples/playground/app/orders/[orderId]/order-client.tsx +2 -2
- package/examples/playground/app/orders/page.tsx +1 -1
- package/examples/playground/app/orders/server.ts +49 -30
- package/examples/playground/app/recovery/[recoveryId]/recovery-client.tsx +14 -15
- package/examples/playground/app/recovery/page.tsx +4 -4
- package/examples/playground/app/recovery/server.ts +23 -32
- package/examples/playground/drizzle.config.ts +14 -0
- package/examples/playground/lib/store.ts +1 -1
- package/examples/playground/next.config.ts +6 -1
- package/examples/playground/package.json +12 -1
- package/examples/playground/scripts/migrate.mjs +31 -0
- package/examples/playground/vercel.json +9 -0
- package/examples/playground/vitest.drills.config.ts +32 -0
- package/package.json +5 -2
- package/sql/postgres/drizzle-schema.ts +209 -0
- package/sql/postgres/schema.sql +227 -67
- package/src/actor-shared.ts +10 -2
- package/src/actor.ts +101 -71
- package/src/ai-agent.ts +162 -111
- package/src/ai-control-server.ts +8 -8
- package/src/ai-fx.ts +324 -82
- package/src/ai-harness.ts +17 -2
- package/src/ai-pi.ts +2 -2
- package/src/ai-server.ts +2 -2
- package/src/ai.ts +7 -7
- package/src/client.ts +19 -2
- package/src/contract.ts +1 -1
- package/src/deterministic-id.ts +27 -4
- package/src/errors.ts +8 -5
- package/src/idempotent-replay.ts +0 -1
- package/src/index.ts +1 -1
- package/src/internal.ts +57 -16
- package/src/otel.ts +1 -1
- package/src/postgres-schema.ts +98 -57
- package/src/presence-recovery.ts +18 -11
- package/src/presence-tombstones.ts +52 -0
- package/src/push-envelope.ts +20 -0
- package/src/runtime-consumer.ts +10 -0
- package/src/scheduler-task.ts +2 -2
- package/src/scheduler-vercel.ts +1 -1
- package/src/server.browser.ts +1 -1
- package/src/server.ts +819 -218
- package/src/session-socket.ts +1 -1
- package/src/store-codec.ts +66 -0
- package/src/store-memory.ts +604 -286
- package/src/store-postgres.ts +2006 -857
- package/src/store-presence-polling.ts +59 -34
- package/src/store-redis-core.ts +1961 -1333
- package/src/store-redis-notify.ts +76 -26
- package/src/store-redis.ts +2 -3
- package/src/store-sqlite.ts +915 -516
- package/src/store.ts +241 -102
- package/src/telemetry.ts +2 -1
- package/src/wire.ts +1 -0
- package/dist/actor-C7b-1arn.d.ts.map +0 -1
- package/dist/actor-shared-t7w8xIKP.js.map +0 -1
- package/dist/ai-harness-Clbg5ei7.js.map +0 -1
- package/dist/ai-mMiWul1T.js.map +0 -1
- package/dist/client-BhHLoNKF.js.map +0 -1
- package/dist/contract-BYKASlCV.js.map +0 -1
- package/dist/idempotent-replay-JdgMQRRm.js +0 -21
- package/dist/idempotent-replay-JdgMQRRm.js.map +0 -1
- package/dist/initial-snapshot-Bx-c0pDP.d.ts.map +0 -1
- package/dist/internal-CscSY7K_.js.map +0 -1
- package/dist/server-DYAATFuT.d.ts.map +0 -1
- package/dist/server-qyb5aJJG.js.map +0 -1
- package/dist/session-clear-C-QwTXV1.d.ts.map +0 -1
- package/dist/session-clear-DGI4jTQ5.js.map +0 -1
- package/dist/store-CyLUy86v.d.ts +0 -404
- package/dist/store-CyLUy86v.d.ts.map +0 -1
- package/dist/store-codec-DTG0Ftek.js +0 -10
- package/dist/store-codec-DTG0Ftek.js.map +0 -1
- package/dist/store-presence-polling-B1ixeqIS.js +0 -94
- package/dist/store-presence-polling-B1ixeqIS.js.map +0 -1
- package/dist/store-redis-notify-CM0AfLY0.js +0 -2544
- package/dist/store-redis-notify-CM0AfLY0.js.map +0 -1
- package/dist/stream-buffer-Cx7AAPGq.js +0 -23
- package/dist/stream-buffer-Cx7AAPGq.js.map +0 -1
- package/dist/telemetry-Cyfqo6Qt.d.ts.map +0 -1
- package/dist/wire-BKxH1vbP.js.map +0 -1
- package/docs/server/01-handlers.mdx +0 -227
package/docs/index.mdx
CHANGED
|
@@ -42,8 +42,8 @@ export const orders = a2.contract({
|
|
|
42
42
|
|
|
43
43
|
## Implement the server
|
|
44
44
|
|
|
45
|
-
Bind the contract to a store, a scheduler, and the
|
|
46
|
-
events.
|
|
45
|
+
Bind the contract to a store, a scheduler, and the consumers that react to
|
|
46
|
+
its events.
|
|
47
47
|
|
|
48
48
|
```ts server/orders.ts
|
|
49
49
|
import { createServer } from 'experimental-a2/server'
|
|
@@ -55,14 +55,18 @@ export const ordersServer = createServer({
|
|
|
55
55
|
contract: orders,
|
|
56
56
|
store: redis({ url: process.env.REDIS_URL }),
|
|
57
57
|
scheduler: vercelQueues(),
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
consumers: [
|
|
59
|
+
{
|
|
60
|
+
name: 'notify-shop',
|
|
61
|
+
types: ['order.created'],
|
|
62
|
+
run: async ({ event }) => {
|
|
63
|
+
// your side effect; event.id makes a stable idempotency key:
|
|
64
|
+
// await sendEmailToShop(event.payload, { idempotencyKey: event.id })
|
|
65
|
+
const { shopId } = event.payload
|
|
66
|
+
return { type: 'shop.notified', payload: { shopId } }
|
|
67
|
+
},
|
|
64
68
|
},
|
|
65
|
-
|
|
69
|
+
],
|
|
66
70
|
})
|
|
67
71
|
```
|
|
68
72
|
|
|
@@ -130,18 +134,18 @@ from the log.
|
|
|
130
134
|
|
|
131
135
|
- Appends are effectively-once.
|
|
132
136
|
- The log stays ordered.
|
|
133
|
-
-
|
|
134
|
-
- Returned events commit with the
|
|
135
|
-
-
|
|
137
|
+
- Consumers are at-least-once.
|
|
138
|
+
- Returned events commit with the consumer's completion.
|
|
139
|
+
- Consumers run concurrently, unless they share a lane.
|
|
136
140
|
- Failures stay contained.
|
|
137
|
-
- A failing
|
|
141
|
+
- A failing consumer never makes `append` throw.
|
|
138
142
|
|
|
139
143
|
[Guarantees](/server/guarantees) has the details and the limits.
|
|
140
144
|
|
|
141
145
|
## Go further...
|
|
142
146
|
|
|
143
147
|
<CardGroup cols={2}>
|
|
144
|
-
<Card title="
|
|
148
|
+
<Card title="Consumers" href="/server/consumers" icon="zap">
|
|
145
149
|
Retries, lanes, and idempotency.
|
|
146
150
|
</Card>
|
|
147
151
|
<Card title="State" href="/contract/state" icon="layers">
|
|
@@ -164,14 +168,14 @@ from the log.
|
|
|
164
168
|
## FAQ
|
|
165
169
|
|
|
166
170
|
<details>
|
|
167
|
-
<summary>Can I use A2 without
|
|
171
|
+
<summary>Can I use A2 without consumers?</summary>
|
|
168
172
|
|
|
169
|
-
Yes. Omit `
|
|
173
|
+
Yes. Omit `consumers` and use `append`, `history`, reducers, and live streams as
|
|
170
174
|
a durable event log. Events settle in their append transaction, with no drain,
|
|
171
|
-
claim, or queue message. A contract can also mix
|
|
172
|
-
types. A2 decides per event type.
|
|
175
|
+
claim, or queue message. A contract can also mix consumed and history-only
|
|
176
|
+
event types. A2 decides per event type.
|
|
173
177
|
|
|
174
|
-
See [
|
|
178
|
+
See [Servers without consumers](/server/consumers#servers-without-consumers).
|
|
175
179
|
|
|
176
180
|
</details>
|
|
177
181
|
|
|
@@ -188,18 +192,19 @@ event ids stay stable across retries. See [Timers](/server/timers).
|
|
|
188
192
|
<details>
|
|
189
193
|
<summary>How do I cancel work that's already running?</summary>
|
|
190
194
|
|
|
191
|
-
Cancellation is an event too: same route, same auth, same log.
|
|
195
|
+
Cancellation is an event too: same route, same auth, same log. Consumers
|
|
192
196
|
opt in with `abortOn` and receive a live `AbortSignal`; reducers cut the
|
|
193
197
|
derived view exactly. See [Cancellation](/server/cancellation).
|
|
194
198
|
|
|
195
199
|
</details>
|
|
196
200
|
|
|
197
201
|
<details>
|
|
198
|
-
<summary>What happens when a
|
|
202
|
+
<summary>What happens when a consumer keeps failing?</summary>
|
|
199
203
|
|
|
200
204
|
It retries with backoff, then dead-letters after ten failed attempts, whether
|
|
201
|
-
the
|
|
202
|
-
until you retry or skip it; unlaned events and other
|
|
205
|
+
the consumer threw or its process ended. Later events in the same lane wait
|
|
206
|
+
until you retry or skip it; unlaned events, other lanes, and other consumers
|
|
207
|
+
continue.
|
|
203
208
|
[Guarantees](/server/guarantees) has the exact guarantees and the
|
|
204
209
|
recovery story behind them.
|
|
205
210
|
|
|
@@ -209,7 +214,7 @@ recovery story behind them.
|
|
|
209
214
|
<summary>What does production need?</summary>
|
|
210
215
|
|
|
211
216
|
A durable store backend, such as Postgres or Redis. Add a queue-backed scheduler
|
|
212
|
-
when the
|
|
217
|
+
when the server has consumers or calls `session.schedule`. A history-only
|
|
213
218
|
contract with no timers needs no reaction infrastructure. Development needs
|
|
214
219
|
neither: SQLite appears under `.a2/` and state survives restarts. See
|
|
215
220
|
[Stores](/stores/overview) and [Schedulers](/schedulers/overview).
|
|
@@ -11,7 +11,7 @@ description: "Every entry point, and the isomorphic `experimental-a2` core: cont
|
|
|
11
11
|
| `experimental-a2/server` | `createServer`: implement a contract | none |
|
|
12
12
|
| `experimental-a2/client` | `createClient`: framework-agnostic session client | none |
|
|
13
13
|
| `experimental-a2/react` | `createReact` | `react` |
|
|
14
|
-
| `experimental-a2/ai` | `agentContract`, `
|
|
14
|
+
| `experimental-a2/ai` | `agentContract`, `consumerContext`, `inputs`, and the AI reducer: isomorphic | `ai` |
|
|
15
15
|
| `experimental-a2/ai/server` | `agent`: an agent's loop as an A2 server | `ai` |
|
|
16
16
|
| `experimental-a2/ai/fx` | `fx`: the FX harness for `agent()` | `ai`, `libfx` |
|
|
17
17
|
| `experimental-a2/ai/pi` | `pi`: the Pi harness for `agent()` | `ai`, `@earendil-works/pi-coding-agent`, `@earendil-works/pi-ai` |
|
|
@@ -63,8 +63,8 @@ ones are rejected at definition time. The validated output is what's stored.
|
|
|
63
63
|
### `contract.batch(...events)`
|
|
64
64
|
|
|
65
65
|
Returns the same events as a readonly tuple, preserving each literal type in a
|
|
66
|
-
heterogeneous
|
|
67
|
-
completes. See [
|
|
66
|
+
heterogeneous array a consumer returns. A2 validates them when the consumer
|
|
67
|
+
completes. See [Consumers](/server/consumers#return-what-happens-after-success).
|
|
68
68
|
|
|
69
69
|
### `reducer(options)`
|
|
70
70
|
|
|
@@ -110,8 +110,9 @@ export const id = await idempotentId('orders', 'shop-7', 'request-42')
|
|
|
110
110
|
- String boundaries, order, and case matter; strings are not normalized. Empty
|
|
111
111
|
strings and an empty tuple are valid.
|
|
112
112
|
- Every argument has the same role; a prefix such as `'orders'` is a namespace
|
|
113
|
-
by convention. Include enough context to distinguish operations
|
|
114
|
-
|
|
113
|
+
by convention. Include enough context to distinguish operations within a
|
|
114
|
+
session: event IDs are unique per session, so the same ID in another session
|
|
115
|
+
names a different event.
|
|
115
116
|
- A2 preserves explicit IDs and does not change its automatic ID generation.
|
|
116
117
|
Changing an existing recipe changes retry identity, so retries of already
|
|
117
118
|
committed requests must keep their original IDs.
|
|
@@ -120,7 +121,7 @@ export const id = await idempotentId('orders', 'shop-7', 'request-42')
|
|
|
120
121
|
|
|
121
122
|
An `Event` whose `type` is `'a2.cleared'` and whose `payload` is `null`: the
|
|
122
123
|
marker a [clear](/reference/server#sessionclearoptions) leaves in
|
|
123
|
-
`session.stream()`. It never reaches
|
|
124
|
+
`session.stream()`. It never reaches consumers or `history()`. Comparing
|
|
124
125
|
`event.type` with that string narrows a stream item to `SessionCleared`. The
|
|
125
126
|
session client handles the marker itself, so it matters only when you read the
|
|
126
127
|
server stream yourself.
|