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
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { AIState } from './ai.ts'
|
|
2
|
+
import type { ContractEvent, EventDefs } from './contract.ts'
|
|
3
|
+
|
|
4
|
+
/** An application reducer folded beside the AI protocol, from events alone. */
|
|
5
|
+
export type AppReducer<D extends EventDefs, X extends object> = {
|
|
6
|
+
/** Snapshot identity of the application state. Rename it when `fold` changes. */
|
|
7
|
+
name: string
|
|
8
|
+
initialState: X
|
|
9
|
+
fold: (state: X, event: ContractEvent<D>) => X
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Every AIState key, so application state is exactly the rest of a merged state.
|
|
13
|
+
const aiStateKeys: Record<keyof AIState, true> = {
|
|
14
|
+
inbox: true,
|
|
15
|
+
pendingQueueCommands: true,
|
|
16
|
+
active: true,
|
|
17
|
+
starting: true,
|
|
18
|
+
receipt: true,
|
|
19
|
+
pausedGenerationIds: true,
|
|
20
|
+
session: true,
|
|
21
|
+
messages: true,
|
|
22
|
+
status: true,
|
|
23
|
+
activeGeneration: true,
|
|
24
|
+
activeRequestId: true,
|
|
25
|
+
activeRequestReason: true,
|
|
26
|
+
activeRequestSourceGenerationId: true,
|
|
27
|
+
activeResponseMessageId: true,
|
|
28
|
+
activeProjection: true,
|
|
29
|
+
responseOwners: true,
|
|
30
|
+
terminalRequestIds: true,
|
|
31
|
+
terminalGenerations: true,
|
|
32
|
+
pendingApprovals: true,
|
|
33
|
+
pendingInputs: true,
|
|
34
|
+
tools: true,
|
|
35
|
+
compaction: true,
|
|
36
|
+
modelMetadata: true,
|
|
37
|
+
usage: true,
|
|
38
|
+
error: true,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const isAIStateKey = (key: string): boolean =>
|
|
42
|
+
Object.hasOwn(aiStateKeys, key)
|
|
43
|
+
|
|
44
|
+
const keep = (state: object, ai: boolean): Record<string, unknown> => {
|
|
45
|
+
const kept: Record<string, unknown> = {}
|
|
46
|
+
for (const [key, value] of Object.entries(state))
|
|
47
|
+
if (isAIStateKey(key) === ai) kept[key] = value
|
|
48
|
+
return kept
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** The application part of a merged state: every key `AIState` does not own. */
|
|
52
|
+
export const appSlice = <X extends object>(state: object): X =>
|
|
53
|
+
keep(state, false) as X
|
|
54
|
+
|
|
55
|
+
/** A merged state with its application part replaced. */
|
|
56
|
+
export const withAppSlice = <S extends object>(state: S, app: object): S =>
|
|
57
|
+
({ ...keep(state, true), ...keep(app, false) }) as S
|
|
58
|
+
|
|
59
|
+
// agentContract() registers every reducer it builds here, keyed by the reducer
|
|
60
|
+
// so spread contracts keep it: agent() serves only these, and folds their
|
|
61
|
+
// application state into the model-context checkpoint every generation reads.
|
|
62
|
+
const agentReducers = new WeakMap<
|
|
63
|
+
object,
|
|
64
|
+
AppReducer<EventDefs, object> | null
|
|
65
|
+
>()
|
|
66
|
+
|
|
67
|
+
export const registerAgentReducer = (
|
|
68
|
+
reducer: object,
|
|
69
|
+
app: AppReducer<EventDefs, object> | undefined,
|
|
70
|
+
): void => {
|
|
71
|
+
agentReducers.set(reducer, app ?? null)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const reducerOf = (contract: { reducer?: unknown }): object | undefined =>
|
|
75
|
+
typeof contract.reducer === 'object' && contract.reducer !== null
|
|
76
|
+
? contract.reducer
|
|
77
|
+
: undefined
|
|
78
|
+
|
|
79
|
+
export const isAgentContract = (contract: { reducer?: unknown }): boolean => {
|
|
80
|
+
const reducer = reducerOf(contract)
|
|
81
|
+
return reducer !== undefined && agentReducers.has(reducer)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export const appReducerOf = (contract: {
|
|
85
|
+
reducer?: unknown
|
|
86
|
+
}): AppReducer<EventDefs, object> | undefined => {
|
|
87
|
+
const reducer = reducerOf(contract)
|
|
88
|
+
return reducer === undefined
|
|
89
|
+
? undefined
|
|
90
|
+
: (agentReducers.get(reducer) ?? undefined)
|
|
91
|
+
}
|
package/src/ai-client-state.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { UIMessage } from 'ai'
|
|
2
2
|
import type { AIState } from './ai.ts'
|
|
3
3
|
import type { ControlCommand, InboxItem } from './ai-control.ts'
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
interruptGenerationProjection,
|
|
6
|
+
settleAbandonedCompaction,
|
|
7
|
+
} from './ai-message-projection.ts'
|
|
5
8
|
|
|
6
9
|
export type QueueCommand<M extends UIMessage> = Extract<
|
|
7
10
|
ControlCommand<M>,
|
|
@@ -200,7 +203,7 @@ export function projectAIClientState<M extends UIMessage>(
|
|
|
200
203
|
projection.responseMessageId,
|
|
201
204
|
stop.lastSeenIndex ?? Number.POSITIVE_INFINITY,
|
|
202
205
|
) ?? displayed)
|
|
203
|
-
return {
|
|
206
|
+
return settleAbandonedCompaction(displayed, {
|
|
204
207
|
...stopped,
|
|
205
208
|
active: null,
|
|
206
209
|
status: paused ? 'paused' : 'idle',
|
|
@@ -213,5 +216,5 @@ export function projectAIClientState<M extends UIMessage>(
|
|
|
213
216
|
pendingApprovals: [],
|
|
214
217
|
pendingInputs: [],
|
|
215
218
|
error: null,
|
|
216
|
-
}
|
|
219
|
+
})
|
|
217
220
|
}
|
package/src/ai-client.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* experimental-a2/ai/client — a client for an `agent()` route that needs no
|
|
3
|
+
* contract: the AI protocol and its `AIState` reducer are library code, and
|
|
4
|
+
* the agent's types arrive through a type-only `typeof` import.
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* import type { assistant } from '@/server/assistant' // erased at build
|
|
8
|
+
* const client = createAgentClient<typeof assistant>({ api: '/api/agent' })
|
|
9
|
+
* await client.session(id).push(...inputs.message(message))
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
agentContract,
|
|
15
|
+
type AI_STATE_REDUCER,
|
|
16
|
+
type AIEventDefs,
|
|
17
|
+
type AIMessageOf,
|
|
18
|
+
type AIState,
|
|
19
|
+
} from './ai.ts'
|
|
20
|
+
import {
|
|
21
|
+
createClient,
|
|
22
|
+
type A2Client,
|
|
23
|
+
type CreateClientOptions,
|
|
24
|
+
} from './client.ts'
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The structural shape of `typeof` an `agent({ name })` server: one whose
|
|
28
|
+
* state the built-in reducer folds. Agents built from an extended contract
|
|
29
|
+
* use `createClient({ contract })` instead.
|
|
30
|
+
*/
|
|
31
|
+
export type AnyAgent = {
|
|
32
|
+
readonly contract: {
|
|
33
|
+
readonly events: object
|
|
34
|
+
readonly reducer: { readonly name: typeof AI_STATE_REDUCER }
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type AgentMessage<A extends AnyAgent> = AIMessageOf<
|
|
39
|
+
A['contract']['events']
|
|
40
|
+
>
|
|
41
|
+
|
|
42
|
+
export type AgentClient<A extends AnyAgent = AnyAgent> = A2Client<
|
|
43
|
+
AIEventDefs<AgentMessage<A>>,
|
|
44
|
+
AIState<AgentMessage<A>>
|
|
45
|
+
>
|
|
46
|
+
|
|
47
|
+
export type CreateAgentClientOptions = Omit<
|
|
48
|
+
CreateClientOptions<AIEventDefs, AIState>,
|
|
49
|
+
'contract'
|
|
50
|
+
>
|
|
51
|
+
|
|
52
|
+
const protocol = agentContract({ name: 'a2.ai' })
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* A client for the built-in AI protocol. Agents built from a shared
|
|
56
|
+
* `agentContract()` use `createClient({ contract })` instead.
|
|
57
|
+
*/
|
|
58
|
+
export function createAgentClient<A extends AnyAgent = AnyAgent>(
|
|
59
|
+
options: CreateAgentClientOptions,
|
|
60
|
+
): AgentClient<A> {
|
|
61
|
+
return createClient({ ...options, contract: protocol }) as AgentClient<A>
|
|
62
|
+
}
|
package/src/ai-context-schema.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { assertMessageBase, restoreMessageBase } from './ai-message-base.ts'
|
|
1
2
|
import type { UIMessage } from 'ai'
|
|
2
3
|
import { events } from './ai.ts'
|
|
3
4
|
import type { AIContextState } from './ai-context.ts'
|
|
@@ -103,6 +104,16 @@ const indexedEvents = (
|
|
|
103
104
|
),
|
|
104
105
|
)
|
|
105
106
|
|
|
107
|
+
const restorableBase = (options: {
|
|
108
|
+
base: unknown
|
|
109
|
+
current: UIMessage | undefined
|
|
110
|
+
}): boolean => {
|
|
111
|
+
assertMessageBase(options.base)
|
|
112
|
+
return isMessage(
|
|
113
|
+
restoreMessageBase({ current: options.current, base: options.base }),
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
|
|
106
117
|
const projection = (value: unknown, messages: UIMessage[]): boolean => {
|
|
107
118
|
if (
|
|
108
119
|
!record(value) ||
|
|
@@ -113,7 +124,7 @@ const projection = (value: unknown, messages: UIMessage[]): boolean => {
|
|
|
113
124
|
'responseMessageId',
|
|
114
125
|
'promptThroughIndex',
|
|
115
126
|
'completionIndex',
|
|
116
|
-
'
|
|
127
|
+
'base',
|
|
117
128
|
'baseCompaction',
|
|
118
129
|
'batches',
|
|
119
130
|
'toolEvents',
|
|
@@ -126,7 +137,13 @@ const projection = (value: unknown, messages: UIMessage[]): boolean => {
|
|
|
126
137
|
!index(value['promptThroughIndex']) ||
|
|
127
138
|
(value['completionIndex'] !== undefined &&
|
|
128
139
|
!index(value['completionIndex'])) ||
|
|
129
|
-
(value['
|
|
140
|
+
(value['base'] !== undefined &&
|
|
141
|
+
!restorableBase({
|
|
142
|
+
base: value['base'],
|
|
143
|
+
current: messages.find(
|
|
144
|
+
(message) => message.id === value['responseMessageId'],
|
|
145
|
+
),
|
|
146
|
+
})) ||
|
|
130
147
|
(value['baseCompaction'] !== undefined &&
|
|
131
148
|
!compaction(value['baseCompaction'])) ||
|
|
132
149
|
!progress(value['batches']) ||
|
|
@@ -200,9 +217,9 @@ const authority = (value: unknown): boolean =>
|
|
|
200
217
|
'paused',
|
|
201
218
|
].includes(String(value['phase']))))
|
|
202
219
|
|
|
203
|
-
export const contextSchema = <M extends UIMessage>(
|
|
204
|
-
|
|
205
|
-
|
|
220
|
+
export const contextSchema = <M extends UIMessage>(
|
|
221
|
+
app?: object,
|
|
222
|
+
): StandardSchemaV1<AIContextState<M>> => ({
|
|
206
223
|
'~standard': {
|
|
207
224
|
version: 1,
|
|
208
225
|
vendor: 'a2-context',
|
|
@@ -217,6 +234,7 @@ export const contextSchema = <M extends UIMessage>(): StandardSchemaV1<
|
|
|
217
234
|
'generation',
|
|
218
235
|
'activeProjection',
|
|
219
236
|
'messageIndexes',
|
|
237
|
+
...(app === undefined ? [] : ['app']),
|
|
220
238
|
]
|
|
221
239
|
try {
|
|
222
240
|
if (
|
|
@@ -254,6 +272,7 @@ export const contextSchema = <M extends UIMessage>(): StandardSchemaV1<
|
|
|
254
272
|
generation !== null &&
|
|
255
273
|
(!record(generation) ||
|
|
256
274
|
!matches(events['ai.generation.started'], generation['owner']) ||
|
|
275
|
+
!index(generation['startIndex']) ||
|
|
257
276
|
![
|
|
258
277
|
'streaming',
|
|
259
278
|
'completed',
|
|
@@ -287,6 +306,7 @@ export const contextSchema = <M extends UIMessage>(): StandardSchemaV1<
|
|
|
287
306
|
return invalid
|
|
288
307
|
if (value['closed'] && (generation !== null || current !== null))
|
|
289
308
|
return invalid
|
|
309
|
+
if (app !== undefined && !record(value['app'])) return invalid
|
|
290
310
|
return { value: value as AIContextState<M> }
|
|
291
311
|
} catch {
|
|
292
312
|
return invalid
|
package/src/ai-context.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { restoreMessageBase } from './ai-message-base.ts'
|
|
2
|
+
import { reducer as makeReducer } from './reducer.ts'
|
|
1
3
|
import type { UIMessage } from 'ai'
|
|
2
4
|
import type {
|
|
3
|
-
AgentDefinition,
|
|
4
5
|
ApprovalRequestedPayload,
|
|
5
6
|
ApprovalRespondedPayload,
|
|
6
7
|
CompactionCompletedPayload,
|
|
@@ -8,7 +9,6 @@ import type {
|
|
|
8
9
|
CompactionState,
|
|
9
10
|
GenerationCompletedPayload,
|
|
10
11
|
GenerationFailedPayload,
|
|
11
|
-
GenerationProgressPayload,
|
|
12
12
|
GenerationRequestedPayload,
|
|
13
13
|
GenerationStartedPayload,
|
|
14
14
|
MessageCreatedPayload,
|
|
@@ -21,9 +21,11 @@ import type {
|
|
|
21
21
|
} from './ai.ts'
|
|
22
22
|
import type { ControlCommit } from './ai-control.ts'
|
|
23
23
|
import { contextSchema } from './ai-context-schema.ts'
|
|
24
|
-
import type { ContractEvent, EventDefs } from './contract.ts'
|
|
24
|
+
import type { Contract, ContractEvent, EventDefs } from './contract.ts'
|
|
25
25
|
import {
|
|
26
26
|
projectedMessage,
|
|
27
|
+
retainMessageBase,
|
|
28
|
+
findMessage,
|
|
27
29
|
advanceProjection,
|
|
28
30
|
reduceToolActivity,
|
|
29
31
|
upsertMessage,
|
|
@@ -34,15 +36,16 @@ import { interruptUIMessage, pauseUIMessage } from './ai-projector.ts'
|
|
|
34
36
|
import {
|
|
35
37
|
flattenProgressBatches,
|
|
36
38
|
progressBatches,
|
|
39
|
+
progressOwnedBy,
|
|
40
|
+
type StoredProgressPayload,
|
|
37
41
|
} from './ai-progress-batches.ts'
|
|
38
|
-
import {
|
|
42
|
+
import { appReducerOf, appSlice } from './ai-app-state.ts'
|
|
43
|
+
import { withAIStorage } from './ai-stored-state.ts'
|
|
44
|
+
import type { Reducer } from './reducer.ts'
|
|
39
45
|
|
|
40
46
|
export type AIModelContext<M extends UIMessage = UIMessage> = {
|
|
41
47
|
messages: M[]
|
|
42
|
-
compaction: Omit<
|
|
43
|
-
CompactionState<M>,
|
|
44
|
-
'messages' | 'retainedMessageIds' | 'usage'
|
|
45
|
-
> | null
|
|
48
|
+
compaction: Omit<CompactionState, 'usage'> | null
|
|
46
49
|
modelMetadata: Record<string, ModelMetadataState>
|
|
47
50
|
}
|
|
48
51
|
|
|
@@ -58,12 +61,16 @@ export type AIContextState<M extends UIMessage> = AIModelContext<M> & {
|
|
|
58
61
|
> | null
|
|
59
62
|
generation: {
|
|
60
63
|
owner: GenerationStartedPayload
|
|
64
|
+
/** Log index of the owner's `ai.generation.started`. */
|
|
65
|
+
startIndex: number
|
|
61
66
|
phase: 'streaming' | 'completed' | 'paused' | 'failed' | 'superseded'
|
|
62
67
|
error?: string
|
|
63
68
|
responseIndex?: number
|
|
64
69
|
} | null
|
|
65
|
-
activeProjection: MessageProjection
|
|
70
|
+
activeProjection: MessageProjection | null
|
|
66
71
|
messageIndexes: Record<string, number>
|
|
72
|
+
/** The contract's application state, when `agentContract()` has a reducer. */
|
|
73
|
+
app?: object
|
|
67
74
|
}
|
|
68
75
|
|
|
69
76
|
const replaceResponse = <M extends UIMessage>({
|
|
@@ -96,12 +103,16 @@ const replaceResponse = <M extends UIMessage>({
|
|
|
96
103
|
}
|
|
97
104
|
}
|
|
98
105
|
|
|
99
|
-
const calledTools = <M extends UIMessage>(
|
|
100
|
-
projection
|
|
101
|
-
|
|
106
|
+
const calledTools = <M extends UIMessage>({
|
|
107
|
+
projection,
|
|
108
|
+
current,
|
|
109
|
+
}: {
|
|
110
|
+
projection: MessageProjection
|
|
111
|
+
current: M | undefined
|
|
112
|
+
}): Set<string> =>
|
|
102
113
|
new Set([
|
|
103
|
-
...(projection.
|
|
104
|
-
'toolCallId' in part ? [part.toolCallId] : [],
|
|
114
|
+
...(restoreMessageBase({ current, base: projection.base })?.parts.flatMap(
|
|
115
|
+
(part) => ('toolCallId' in part ? [part.toolCallId] : []),
|
|
105
116
|
) ?? []),
|
|
106
117
|
...projection.toolEvents
|
|
107
118
|
.filter((event) => event.type === 'ai.tool.called')
|
|
@@ -116,15 +127,19 @@ const renderProjection = <M extends UIMessage>({
|
|
|
116
127
|
index: number
|
|
117
128
|
}): AIContextState<M> => {
|
|
118
129
|
const projection = state.activeProjection!
|
|
119
|
-
|
|
130
|
+
const current = findMessage(state.messages, projection.responseMessageId)
|
|
131
|
+
let message = projectedMessage({ projection, current })
|
|
120
132
|
if (
|
|
121
|
-
projection.
|
|
133
|
+
projection.base === undefined &&
|
|
122
134
|
projection.batches.length === 0 &&
|
|
123
135
|
message.parts.length === 0
|
|
124
136
|
)
|
|
125
137
|
return state
|
|
126
138
|
if (state.generation?.phase === 'paused')
|
|
127
|
-
message = pauseUIMessage({
|
|
139
|
+
message = pauseUIMessage({
|
|
140
|
+
message,
|
|
141
|
+
toolCallIds: calledTools({ projection, current }),
|
|
142
|
+
})
|
|
128
143
|
if (state.generation?.phase === 'failed')
|
|
129
144
|
message = interruptUIMessage(
|
|
130
145
|
message,
|
|
@@ -142,14 +157,18 @@ export const generationBase = <M extends UIMessage>(
|
|
|
142
157
|
): AIContextState<M> => {
|
|
143
158
|
const projection = state.activeProjection
|
|
144
159
|
if (!projection) return state
|
|
160
|
+
const base = restoreMessageBase({
|
|
161
|
+
current: findMessage(state.messages, projection.responseMessageId),
|
|
162
|
+
base: projection.base,
|
|
163
|
+
})
|
|
145
164
|
return {
|
|
146
165
|
...state,
|
|
147
166
|
messages:
|
|
148
|
-
|
|
167
|
+
base === undefined
|
|
149
168
|
? state.messages.filter(
|
|
150
169
|
(message) => message.id !== projection.responseMessageId,
|
|
151
170
|
)
|
|
152
|
-
: upsertMessage(state.messages,
|
|
171
|
+
: upsertMessage(state.messages, base),
|
|
153
172
|
compaction: projection.baseCompaction ?? null,
|
|
154
173
|
}
|
|
155
174
|
}
|
|
@@ -182,10 +201,11 @@ const ownsGeneration = <M extends UIMessage>(
|
|
|
182
201
|
state.generation.phase !== 'superseded'
|
|
183
202
|
|
|
184
203
|
export const createContextReducer = <M extends UIMessage, D extends EventDefs>({
|
|
185
|
-
|
|
204
|
+
contract,
|
|
186
205
|
}: {
|
|
187
|
-
|
|
188
|
-
}):
|
|
206
|
+
contract: Contract<D, Record<never, never>, unknown>
|
|
207
|
+
}): Reducer<D, AIContextState<M>> => {
|
|
208
|
+
const app = appReducerOf(contract)
|
|
189
209
|
const initialState: AIContextState<M> = {
|
|
190
210
|
messages: [],
|
|
191
211
|
compaction: null,
|
|
@@ -195,15 +215,26 @@ export const createContextReducer = <M extends UIMessage, D extends EventDefs>({
|
|
|
195
215
|
generation: null,
|
|
196
216
|
activeProjection: null,
|
|
197
217
|
messageIndexes: {},
|
|
218
|
+
...(app === undefined ? {} : { app: app.initialState }),
|
|
198
219
|
}
|
|
199
|
-
const reducer =
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
220
|
+
const reducer = makeReducer({
|
|
221
|
+
contract,
|
|
222
|
+
// The application state rides in this checkpoint so every generation
|
|
223
|
+
// reads it without another state read.
|
|
224
|
+
name:
|
|
225
|
+
app === undefined ? 'a2.ai.context.v6' : `${app.name}+a2.ai.context.v6`,
|
|
226
|
+
initialState,
|
|
227
|
+
stateSchema: contextSchema<M>(app),
|
|
228
|
+
}).fold((state, event) => {
|
|
229
|
+
const after = retainMessageBase({
|
|
230
|
+
before: state,
|
|
231
|
+
after: reduceContext(state, event),
|
|
204
232
|
})
|
|
205
|
-
|
|
206
|
-
|
|
233
|
+
if (app === undefined) return after
|
|
234
|
+
const next = app.fold(state.app!, event as ContractEvent<EventDefs>)
|
|
235
|
+
return next === state.app ? after : { ...after, app: appSlice(next) }
|
|
236
|
+
})
|
|
237
|
+
return withAIStorage(reducer)
|
|
207
238
|
}
|
|
208
239
|
|
|
209
240
|
const reduceContext = <M extends UIMessage, D extends EventDefs>(
|
|
@@ -297,6 +328,7 @@ const reduceContext = <M extends UIMessage, D extends EventDefs>(
|
|
|
297
328
|
...base,
|
|
298
329
|
generation: {
|
|
299
330
|
owner,
|
|
331
|
+
startIndex: event.index,
|
|
300
332
|
phase: 'streaming',
|
|
301
333
|
...(previous?.owner.responseMessageId === owner.responseMessageId &&
|
|
302
334
|
previous.responseIndex !== undefined
|
|
@@ -307,7 +339,9 @@ const reduceContext = <M extends UIMessage, D extends EventDefs>(
|
|
|
307
339
|
generationId: owner.generationId,
|
|
308
340
|
responseMessageId: owner.responseMessageId,
|
|
309
341
|
promptThroughIndex: owner.promptThroughIndex ?? event.index - 1,
|
|
310
|
-
...(baseMessage === undefined
|
|
342
|
+
...(baseMessage === undefined
|
|
343
|
+
? {}
|
|
344
|
+
: { base: { partCount: baseMessage.parts.length } }),
|
|
311
345
|
baseCompaction: base.compaction,
|
|
312
346
|
batches: progressBatches(),
|
|
313
347
|
toolEvents: [],
|
|
@@ -316,12 +350,16 @@ const reduceContext = <M extends UIMessage, D extends EventDefs>(
|
|
|
316
350
|
}
|
|
317
351
|
}
|
|
318
352
|
case 'ai.generation.progress': {
|
|
319
|
-
const payload = event.payload as
|
|
353
|
+
const payload = event.payload as StoredProgressPayload
|
|
354
|
+
const generation = state.generation
|
|
320
355
|
if (
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
356
|
+
generation === null ||
|
|
357
|
+
generation.phase !== 'streaming' ||
|
|
358
|
+
!progressOwnedBy({
|
|
359
|
+
payload,
|
|
360
|
+
owner: generation.owner,
|
|
361
|
+
startIndex: generation.startIndex,
|
|
362
|
+
}) ||
|
|
325
363
|
!state.activeProjection
|
|
326
364
|
)
|
|
327
365
|
return state
|
|
@@ -433,10 +471,15 @@ const reduceContext = <M extends UIMessage, D extends EventDefs>(
|
|
|
433
471
|
),
|
|
434
472
|
}
|
|
435
473
|
let next = generationBase(state)
|
|
436
|
-
if (retained.
|
|
474
|
+
if (retained.base !== undefined || retained.batches.length > 0)
|
|
437
475
|
next = replaceResponse({
|
|
438
476
|
state: next,
|
|
439
|
-
message: interruptUIMessage(
|
|
477
|
+
message: interruptUIMessage(
|
|
478
|
+
projectedMessage({
|
|
479
|
+
projection: retained,
|
|
480
|
+
current: findMessage(state.messages, retained.responseMessageId),
|
|
481
|
+
}),
|
|
482
|
+
),
|
|
440
483
|
index: event.index,
|
|
441
484
|
})
|
|
442
485
|
return endGeneration(next)
|
|
@@ -458,7 +501,13 @@ const reduceContext = <M extends UIMessage, D extends EventDefs>(
|
|
|
458
501
|
!state.activeProjection
|
|
459
502
|
)
|
|
460
503
|
return state
|
|
461
|
-
const toolCallIds = calledTools(
|
|
504
|
+
const toolCallIds = calledTools({
|
|
505
|
+
projection: state.activeProjection,
|
|
506
|
+
current: findMessage(
|
|
507
|
+
state.messages,
|
|
508
|
+
state.activeProjection.responseMessageId,
|
|
509
|
+
),
|
|
510
|
+
})
|
|
462
511
|
return renderProjection({
|
|
463
512
|
state: {
|
|
464
513
|
...state,
|
|
@@ -617,11 +666,12 @@ const reduceContext = <M extends UIMessage, D extends EventDefs>(
|
|
|
617
666
|
),
|
|
618
667
|
]
|
|
619
668
|
const activeProjection = { ...projection, cursor: null }
|
|
620
|
-
delete activeProjection.
|
|
669
|
+
delete activeProjection.base
|
|
621
670
|
const baseMessage = messages.find(
|
|
622
671
|
(message) => message.id === projection.responseMessageId,
|
|
623
672
|
)
|
|
624
|
-
if (baseMessage !== undefined)
|
|
673
|
+
if (baseMessage !== undefined)
|
|
674
|
+
activeProjection.base = { partCount: baseMessage.parts.length }
|
|
625
675
|
const compaction: AIModelContext<M>['compaction'] = {
|
|
626
676
|
status: 'completed',
|
|
627
677
|
generationId: payload.generationId,
|