experimental-a2 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +360 -0
- package/dist/{actor-ohPC-81x.d.ts → actor-DBbe5xeE.d.ts} +21 -11
- package/dist/actor-DBbe5xeE.d.ts.map +1 -0
- package/dist/actor-client.d.ts +2 -5
- package/dist/actor-client.d.ts.map +1 -1
- package/dist/actor-client.js +13 -4
- package/dist/actor-client.js.map +1 -1
- package/dist/actor-react.d.ts +5 -3
- package/dist/actor-react.d.ts.map +1 -1
- package/dist/actor-react.js +20 -10
- package/dist/actor-react.js.map +1 -1
- package/dist/{actor-shared-B5tJfzt-.js → actor-shared-t7w8xIKP.js} +12 -7
- package/dist/actor-shared-t7w8xIKP.js.map +1 -0
- package/dist/actor.d.ts +1 -1
- package/dist/actor.js +42 -23
- package/dist/actor.js.map +1 -1
- package/dist/{ai-CrLYwNEx.js → ai-UrWfKeuv.js} +966 -541
- package/dist/ai-UrWfKeuv.js.map +1 -0
- package/dist/ai-client.d.ts +27 -0
- package/dist/ai-client.d.ts.map +1 -0
- package/dist/ai-client.js +29 -0
- package/dist/ai-client.js.map +1 -0
- package/dist/ai-react.d.ts +96 -0
- package/dist/ai-react.d.ts.map +1 -0
- package/dist/ai-react.js +142 -0
- package/dist/ai-react.js.map +1 -0
- package/dist/ai-server.browser.js +2 -2
- package/dist/ai-server.browser.js.map +1 -1
- package/dist/ai-server.d.ts +80 -36
- package/dist/ai-server.d.ts.map +1 -1
- package/dist/ai-server.js +466 -265
- package/dist/ai-server.js.map +1 -1
- package/dist/{ai-HJ9fHfYI.d.ts → ai-vpGtcaCB.d.ts} +115 -101
- package/dist/ai-vpGtcaCB.d.ts.map +1 -0
- package/dist/ai.d.ts +2 -2
- package/dist/ai.js +2 -2
- package/dist/{client-BYzHjkwU.js → client-COaiaDub.js} +447 -80
- package/dist/client-COaiaDub.js.map +1 -0
- package/dist/{client-CzyacQpJ.d.ts → client-qRnRUzBS.d.ts} +14 -13
- package/dist/client-qRnRUzBS.d.ts.map +1 -0
- package/dist/client.d.ts +4 -2
- package/dist/client.js +1 -1
- package/dist/{contract-CKRg_E4q.js → contract-BYKASlCV.js} +12 -21
- package/dist/contract-BYKASlCV.js.map +1 -0
- package/dist/{idempotent-replay-DVOlyYbx.js → idempotent-replay-JdgMQRRm.js} +2 -2
- package/dist/{idempotent-replay-DVOlyYbx.js.map → idempotent-replay-JdgMQRRm.js.map} +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/{errors-DvhSXnxk.d.ts → initial-snapshot-BrLso5x_.d.ts} +7 -3
- package/dist/initial-snapshot-BrLso5x_.d.ts.map +1 -0
- package/dist/{internal-Dq2qYxou.js → internal-CbVvEwad.js} +23 -2
- package/dist/internal-CbVvEwad.js.map +1 -0
- package/dist/otel.d.ts +1 -1
- package/dist/react-BbJ-g6Uu.d.ts +86 -0
- package/dist/react-BbJ-g6Uu.d.ts.map +1 -0
- package/dist/react.d.ts +2 -122
- package/dist/react.js +107 -100
- package/dist/react.js.map +1 -1
- package/dist/reducer-BAXc8JyF.js +87 -0
- package/dist/reducer-BAXc8JyF.js.map +1 -0
- package/dist/{reducer-otzHjuJj.d.ts → reducer-BYu6DT7h.d.ts} +45 -29
- package/dist/reducer-BYu6DT7h.d.ts.map +1 -0
- package/dist/reducer-runtime-DQwz_J59.js +28 -0
- package/dist/reducer-runtime-DQwz_J59.js.map +1 -0
- package/dist/scheduler-qstash.d.ts +3 -3
- package/dist/scheduler-qstash.d.ts.map +1 -1
- package/dist/scheduler-qstash.js +33 -10
- package/dist/scheduler-qstash.js.map +1 -1
- package/dist/{scheduler-task-BpzhPnRS.js → scheduler-task-X1SToDjP.js} +18 -3
- package/dist/scheduler-task-X1SToDjP.js.map +1 -0
- package/dist/scheduler-vercel.d.ts +4 -9
- package/dist/scheduler-vercel.d.ts.map +1 -1
- package/dist/scheduler-vercel.js +25 -44
- package/dist/scheduler-vercel.js.map +1 -1
- package/dist/{server-DbD7IJVK.d.ts → server-CGM8WzRG.d.ts} +87 -26
- package/dist/server-CGM8WzRG.d.ts.map +1 -0
- package/dist/{server-BD5ckxZb.js → server-Rj64fNvX.js} +854 -202
- package/dist/server-Rj64fNvX.js.map +1 -0
- package/dist/server.d.ts +4 -4
- package/dist/server.js +2 -2
- package/dist/{errors-DCk6ch5n.js → session-clear-DGI4jTQ5.js} +17 -2
- package/dist/session-clear-DGI4jTQ5.js.map +1 -0
- package/dist/session-clear-Dshpuhff.d.ts +12 -0
- package/dist/session-clear-Dshpuhff.d.ts.map +1 -0
- package/dist/{store-DyZM6fS5.d.ts → store-Gpkq7WBo.d.ts} +44 -3
- package/dist/store-Gpkq7WBo.d.ts.map +1 -0
- package/dist/store-N8PXxDAS.js.map +1 -1
- package/dist/store-memory.d.ts +1 -1
- package/dist/store-memory.d.ts.map +1 -1
- package/dist/store-memory.js +182 -69
- package/dist/store-memory.js.map +1 -1
- package/dist/{store-polling-CmxUbV93.js → store-polling-4_y8lETm.js} +21 -4
- package/dist/store-polling-4_y8lETm.js.map +1 -0
- package/dist/store-postgres.d.ts +1 -1
- package/dist/store-postgres.d.ts.map +1 -1
- package/dist/store-postgres.js +399 -108
- package/dist/store-postgres.js.map +1 -1
- package/dist/{store-presence-polling-C7-XZyW9.js → store-presence-polling-Q1C-k2dd.js} +3 -3
- package/dist/{store-presence-polling-C7-XZyW9.js.map → store-presence-polling-Q1C-k2dd.js.map} +1 -1
- package/dist/store-redis-http.d.ts +1 -1
- package/dist/store-redis-http.d.ts.map +1 -1
- package/dist/store-redis-http.js +293 -11
- package/dist/store-redis-http.js.map +1 -1
- package/dist/store-redis-notify-tqWNnMRu.js +2374 -0
- package/dist/store-redis-notify-tqWNnMRu.js.map +1 -0
- package/dist/store-redis.d.ts +1 -1
- package/dist/store-redis.d.ts.map +1 -1
- package/dist/store-redis.js +11 -11
- package/dist/store-redis.js.map +1 -1
- package/dist/store-sqlite.d.ts +1 -1
- package/dist/store-sqlite.d.ts.map +1 -1
- package/dist/store-sqlite.js +166 -32
- package/dist/store-sqlite.js.map +1 -1
- package/dist/stream-buffer-Cx7AAPGq.js +23 -0
- package/dist/stream-buffer-Cx7AAPGq.js.map +1 -0
- package/dist/{telemetry-B5jzpy6y.d.ts → telemetry-cZH-cibj.d.ts} +2 -2
- package/dist/telemetry-cZH-cibj.d.ts.map +1 -0
- package/dist/{wire-BO5wWCb1.js → wire-DjfHOvdW.js} +132 -10
- package/dist/wire-DjfHOvdW.js.map +1 -0
- package/docs/01-quickstart.mdx +2 -2
- package/docs/actors/01-introduction.mdx +4 -0
- package/docs/actors/04-routes.mdx +14 -1
- package/docs/concepts/01-contracts.mdx +95 -0
- package/docs/concepts/04-state.mdx +3 -3
- package/docs/guides/01-timers.mdx +22 -14
- package/docs/guides/02-cancellation.mdx +1 -1
- package/docs/guides/03-react.mdx +268 -328
- package/docs/guides/04-local-first.mdx +32 -73
- package/docs/guides/05-production.mdx +40 -27
- package/docs/guides/06-ai-agents.mdx +680 -580
- package/docs/guides/09-presence.mdx +3 -7
- package/docs/guides/10-transports.mdx +5 -5
- package/docs/index.mdx +10 -18
- package/docs/reference/01-api.mdx +662 -195
- package/docs/reference/02-errors.mdx +2 -1
- package/examples/playground/DEPLOY.md +52 -6
- package/examples/playground/app/a0/[appId]/loading.tsx +16 -0
- package/examples/playground/app/a0/[appId]/page.tsx +48 -0
- package/examples/playground/app/a0/a0.css +818 -0
- package/examples/playground/app/a0/app-list.tsx +211 -0
- package/examples/playground/app/a0/app-view.tsx +55 -0
- package/examples/playground/app/a0/apps/[appId]/preview/route.ts +27 -0
- package/examples/playground/app/a0/apps/[appId]/route.ts +23 -0
- package/examples/playground/app/a0/apps.test.ts +116 -0
- package/examples/playground/app/a0/apps.ts +87 -0
- package/examples/playground/app/a0/chat.tsx +364 -0
- package/examples/playground/app/a0/columns.tsx +109 -0
- package/examples/playground/app/a0/context-menu.tsx +116 -0
- package/examples/playground/app/a0/cookies.ts +46 -0
- package/examples/playground/app/a0/crash-on-request.ts +72 -0
- package/examples/playground/app/a0/crashes/route.ts +3 -0
- package/examples/playground/app/a0/crashes.test.ts +33 -0
- package/examples/playground/app/a0/crashes.ts +28 -0
- package/examples/playground/app/a0/devtools.tsx +164 -0
- package/examples/playground/app/a0/events/route.ts +6 -0
- package/examples/playground/app/a0/flags.ts +30 -0
- package/examples/playground/app/a0/layout.tsx +38 -0
- package/examples/playground/app/a0/list/route.ts +10 -0
- package/examples/playground/app/a0/model.test.ts +56 -0
- package/examples/playground/app/a0/model.ts +58 -0
- package/examples/playground/app/a0/page.tsx +14 -0
- package/examples/playground/app/a0/preview-pane.tsx +145 -0
- package/examples/playground/app/a0/preview.test.ts +53 -0
- package/examples/playground/app/a0/preview.ts +26 -0
- package/examples/playground/app/a0/sandbox-log.ts +69 -0
- package/examples/playground/app/a0/sandbox.ts +191 -0
- package/examples/playground/app/a0/sandboxes/scheduler/route.ts +6 -0
- package/examples/playground/app/a0/scheduler/route.ts +7 -0
- package/examples/playground/app/a0/server.ts +158 -0
- package/examples/playground/app/a0/session.ts +47 -0
- package/examples/playground/app/a0/shell.tsx +150 -0
- package/examples/playground/app/a0/short/events/route.ts +9 -0
- package/examples/playground/app/a0/splitter.tsx +120 -0
- package/examples/playground/app/agent/[agentId]/agent-client.tsx +144 -174
- package/examples/playground/app/agent/[agentId]/command-receipt.test.tsx +65 -0
- package/examples/playground/app/agent/[agentId]/command-receipt.tsx +27 -0
- package/examples/playground/app/agent/[agentId]/compaction-event.tsx +25 -24
- package/examples/playground/app/agent/[agentId]/compaction-panel.test.tsx +119 -0
- package/examples/playground/app/agent/[agentId]/compaction-panel.tsx +208 -165
- package/examples/playground/app/agent/[agentId]/page.tsx +2 -16
- package/examples/playground/app/agent/events/route.ts +5 -2
- package/examples/playground/app/agent/ingress.test.ts +98 -0
- package/examples/playground/app/agent/model-input.test.tsx +58 -0
- package/examples/playground/app/agent/model-input.tsx +115 -0
- package/examples/playground/app/agent/model.test.ts +73 -0
- package/examples/playground/app/agent/model.ts +58 -26
- package/examples/playground/app/agent/new-agent-session.tsx +37 -19
- package/examples/playground/app/agent/page.tsx +4 -4
- package/examples/playground/app/agent/server.ts +15 -14
- package/examples/playground/app/agent/session.ts +5 -6
- package/examples/playground/app/agent/telemetry.test.ts +168 -0
- package/examples/playground/app/agent/telemetry.ts +30 -0
- package/examples/playground/app/agent/trace.test.ts +23 -0
- package/examples/playground/app/agent/trace.ts +18 -0
- package/examples/playground/app/canvas/[canvasId]/canvas-client.tsx +11 -11
- package/examples/playground/app/canvas/[canvasId]/page.tsx +1 -2
- package/examples/playground/app/canvas/[canvasId]/session.ts +2 -2
- package/examples/playground/app/canvas/model.ts +53 -53
- package/examples/playground/app/chat/[chatId]/agent-state.test.ts +176 -0
- package/examples/playground/app/chat/[chatId]/agent-stream-drawer.tsx +16 -1
- package/examples/playground/app/chat/[chatId]/chat-client.tsx +55 -77
- package/examples/playground/app/chat/[chatId]/chat-view.ts +37 -3
- package/examples/playground/app/chat/[chatId]/page.tsx +7 -15
- package/examples/playground/app/chat/[chatId]/session.ts +2 -19
- package/examples/playground/app/chat/agent/route.ts +9 -0
- package/examples/playground/app/chat/model.test.ts +46 -119
- package/examples/playground/app/chat/model.ts +82 -128
- package/examples/playground/app/chat/scheduler/route.ts +2 -2
- package/examples/playground/app/chat/server.test.ts +108 -0
- package/examples/playground/app/chat/server.ts +69 -73
- package/examples/playground/app/components/activity-feed.tsx +30 -1
- package/examples/playground/app/components/activity-history.test.tsx +35 -0
- package/examples/playground/app/components/demo-icons.tsx +89 -0
- package/examples/playground/app/components/demos.tsx +33 -0
- package/examples/playground/app/components/fast-link.test.tsx +58 -0
- package/examples/playground/app/components/fast-link.tsx +55 -0
- package/examples/playground/app/components/site-header.tsx +96 -0
- package/examples/playground/app/counter/counter-client.tsx +3 -3
- package/examples/playground/app/counter/model.test.ts +3 -3
- package/examples/playground/app/counter/model.ts +11 -21
- package/examples/playground/app/counter/page.tsx +2 -15
- package/examples/playground/app/counter/session.ts +2 -2
- package/examples/playground/app/documents/[documentId]/code-editor.tsx +12 -1
- package/examples/playground/app/documents/[documentId]/document-client.tsx +10 -11
- package/examples/playground/app/documents/[documentId]/page.tsx +1 -2
- package/examples/playground/app/documents/[documentId]/session.ts +2 -2
- package/examples/playground/app/documents/model.ts +27 -27
- package/examples/playground/app/globals.css +420 -207
- package/examples/playground/app/initial-state.test.tsx +54 -0
- package/examples/playground/app/layout.tsx +7 -23
- package/examples/playground/app/orders/[orderId]/page.tsx +1 -2
- package/examples/playground/app/orders/[orderId]/session.ts +2 -2
- package/examples/playground/app/orders/model.ts +49 -49
- package/examples/playground/app/page.tsx +13 -102
- package/examples/playground/app/recovery/[recoveryId]/page.tsx +1 -2
- package/examples/playground/app/recovery/[recoveryId]/session.ts +2 -2
- package/examples/playground/app/recovery/model.ts +30 -30
- package/examples/playground/instrumentation.ts +5 -0
- package/examples/playground/package.json +10 -2
- package/examples/playground/scripts/a0-template.ts +77 -0
- package/examples/playground/vercel.json +18 -0
- package/package.json +3 -1
- package/src/actor-client.ts +16 -4
- package/src/actor-react.ts +25 -11
- package/src/actor-shared.ts +21 -6
- package/src/actor.ts +76 -31
- package/src/ai-agent-actions.ts +219 -0
- package/src/ai-agent.ts +2343 -0
- package/src/ai-app-state.ts +91 -0
- package/src/ai-client-state.ts +39 -2
- package/src/ai-client.ts +62 -0
- package/src/ai-context-schema.ts +25 -5
- package/src/ai-context.ts +90 -40
- package/src/ai-control-server.ts +94 -55
- package/src/ai-control.ts +2 -0
- package/src/ai-coordinator.ts +23 -22
- package/src/ai-message-base.ts +209 -0
- package/src/ai-message-projection.ts +382 -58
- package/src/ai-progress-batches.ts +26 -0
- package/src/ai-projector.ts +95 -14
- package/src/ai-react.ts +146 -0
- package/src/ai-server.browser.ts +2 -2
- package/src/ai-server.ts +20 -1951
- package/src/ai-stored-state.ts +48 -163
- package/src/ai.ts +343 -276
- package/src/bootstrap-stream.ts +72 -0
- package/src/bounded-cache.ts +55 -0
- package/src/client-render-session.ts +49 -0
- package/src/client.ts +688 -151
- package/src/contract.ts +92 -42
- package/src/deterministic-id.ts +37 -0
- package/src/equal-json.ts +32 -0
- package/src/errors.ts +13 -1
- package/src/index.ts +5 -1
- package/src/initial-snapshot.ts +39 -0
- package/src/internal.ts +45 -0
- package/src/postgres-notification-scope.ts +14 -3
- package/src/react.ts +171 -206
- package/src/redis-http-reply.ts +256 -0
- package/src/redis-http-stream.ts +73 -0
- package/src/redis-http-subscriptions.ts +13 -5
- package/src/reducer-runtime.ts +52 -0
- package/src/reducer.ts +92 -10
- package/src/scheduler-qstash.ts +49 -20
- package/src/scheduler-task.ts +34 -2
- package/src/scheduler-vercel.ts +32 -84
- package/src/server-fetch.ts +139 -35
- package/src/server.ts +957 -237
- package/src/session-clear.ts +23 -0
- package/src/session-socket.ts +154 -49
- package/src/sse.ts +71 -4
- package/src/store-memory.ts +220 -78
- package/src/store-polling.ts +18 -4
- package/src/store-postgres.ts +461 -114
- package/src/store-redis-core.ts +1260 -434
- package/src/store-redis-http.ts +18 -2
- package/src/store-redis-notify.ts +260 -85
- package/src/store-redis.ts +19 -9
- package/src/store-sqlite.ts +259 -45
- package/src/store.ts +46 -1
- package/src/stream-buffer.ts +43 -0
- package/src/telemetry.ts +13 -1
- package/src/wire.ts +241 -13
- package/dist/actor-ohPC-81x.d.ts.map +0 -1
- package/dist/actor-shared-B5tJfzt-.js.map +0 -1
- package/dist/ai-CrLYwNEx.js.map +0 -1
- package/dist/ai-HJ9fHfYI.d.ts.map +0 -1
- package/dist/client-BYzHjkwU.js.map +0 -1
- package/dist/client-CzyacQpJ.d.ts.map +0 -1
- package/dist/contract-CKRg_E4q.js.map +0 -1
- package/dist/errors-DCk6ch5n.js.map +0 -1
- package/dist/errors-DvhSXnxk.d.ts.map +0 -1
- package/dist/internal-Dq2qYxou.js.map +0 -1
- package/dist/react.d.ts.map +0 -1
- package/dist/reducer-DEMjEY_O.js +0 -29
- package/dist/reducer-DEMjEY_O.js.map +0 -1
- package/dist/reducer-otzHjuJj.d.ts.map +0 -1
- package/dist/scheduler-task-BpzhPnRS.js.map +0 -1
- package/dist/server-BD5ckxZb.js.map +0 -1
- package/dist/server-DbD7IJVK.d.ts.map +0 -1
- package/dist/store-DyZM6fS5.d.ts.map +0 -1
- package/dist/store-polling-CmxUbV93.js.map +0 -1
- package/dist/store-redis-notify-BVLUfI3j.js +0 -1583
- package/dist/store-redis-notify-BVLUfI3j.js.map +0 -1
- package/dist/telemetry-B5jzpy6y.d.ts.map +0 -1
- package/dist/validate-XKT4FSNn.js +0 -30
- package/dist/validate-XKT4FSNn.js.map +0 -1
- package/dist/wire-BO5wWCb1.js.map +0 -1
- package/examples/playground/app/agent/[agentId]/compaction/route.ts +0 -14
- package/examples/playground/app/agent/compaction-settings.test.ts +0 -144
- package/examples/playground/app/agent/compaction-settings.ts +0 -49
- package/examples/playground/app/agent/compaction-timeline.test.ts +0 -377
- package/examples/playground/app/agent/compaction-timeline.ts +0 -208
package/src/ai-stored-state.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { assertMessageBase, restoreMessageBase } from './ai-message-base.ts'
|
|
2
|
+
import { sameValue } from './equal-json.ts'
|
|
1
3
|
import type { UIMessage } from 'ai'
|
|
2
4
|
import type { AIState } from './ai.ts'
|
|
3
5
|
import type { MessageProjection } from './ai-message-projection.ts'
|
|
4
6
|
import type { EventDefs } from './contract.ts'
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
+
import type { Reducer } from './reducer.ts'
|
|
8
|
+
import { withReducerRuntime } from './reducer-runtime.ts'
|
|
7
9
|
|
|
8
10
|
type Value =
|
|
9
11
|
null | boolean | number | string | Value[] | { [key: string]: Value }
|
|
@@ -15,13 +17,11 @@ type Undo =
|
|
|
15
17
|
|
|
16
18
|
type Projection = {
|
|
17
19
|
fields: Value
|
|
18
|
-
hasMessage: boolean
|
|
19
|
-
message?: Undo
|
|
20
20
|
tools?: Undo
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
export type AIStoredState = {
|
|
24
|
-
version:
|
|
24
|
+
version: 3
|
|
25
25
|
fields: Value
|
|
26
26
|
projection: Projection | null
|
|
27
27
|
values: Payload[]
|
|
@@ -30,22 +30,11 @@ export type AIStoredState = {
|
|
|
30
30
|
export type AIStoredView = {
|
|
31
31
|
messages: UIMessage[]
|
|
32
32
|
activeProjection:
|
|
33
|
-
(MessageProjection
|
|
33
|
+
(MessageProjection & { baseTools?: AIState['tools'] }) | null
|
|
34
34
|
tools?: AIState['tools']
|
|
35
35
|
usage?: AIState['usage']
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
export const aiStateReducer: unique symbol = Symbol('a2.ai.stateReducer')
|
|
39
|
-
|
|
40
|
-
export type AIStoredReducer<
|
|
41
|
-
D extends EventDefs,
|
|
42
|
-
S extends AIStoredView,
|
|
43
|
-
> = Reducer<D, AIStoredState, Record<never, never>, S> & {
|
|
44
|
-
readonly [aiStateReducer]: Reducer<D, S>
|
|
45
|
-
view(state: AIStoredState): S
|
|
46
|
-
fromView(state: S): AIStoredState
|
|
47
|
-
}
|
|
48
|
-
|
|
49
38
|
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
50
39
|
typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
51
40
|
|
|
@@ -87,39 +76,6 @@ const payloadFields = new Set([
|
|
|
87
76
|
const keyFor = (value: unknown): string =>
|
|
88
77
|
value === undefined ? 'undefined' : JSON.stringify(value)
|
|
89
78
|
|
|
90
|
-
const sameValue = (left: unknown, right: unknown): boolean => {
|
|
91
|
-
if (Object.is(left, right)) return true
|
|
92
|
-
if (
|
|
93
|
-
typeof left !== 'object' ||
|
|
94
|
-
left === null ||
|
|
95
|
-
typeof right !== 'object' ||
|
|
96
|
-
right === null
|
|
97
|
-
)
|
|
98
|
-
return false
|
|
99
|
-
const prototype = Object.getPrototypeOf(left)
|
|
100
|
-
if (
|
|
101
|
-
prototype !== Object.getPrototypeOf(right) ||
|
|
102
|
-
(prototype !== Object.prototype &&
|
|
103
|
-
prototype !== Array.prototype &&
|
|
104
|
-
prototype !== null)
|
|
105
|
-
)
|
|
106
|
-
return false
|
|
107
|
-
if (
|
|
108
|
-
Array.isArray(left) &&
|
|
109
|
-
(!Array.isArray(right) || left.length !== right.length)
|
|
110
|
-
)
|
|
111
|
-
return false
|
|
112
|
-
const keys = Reflect.ownKeys(left)
|
|
113
|
-
return (
|
|
114
|
-
keys.length === Reflect.ownKeys(right).length &&
|
|
115
|
-
keys.every(
|
|
116
|
-
(key) =>
|
|
117
|
-
Object.hasOwn(right, key) &&
|
|
118
|
-
sameValue(Reflect.get(left, key), Reflect.get(right, key)),
|
|
119
|
-
)
|
|
120
|
-
)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
79
|
const restore = (current: Value, undo: Undo | undefined): Value => {
|
|
124
80
|
if (undo === undefined) return current
|
|
125
81
|
if (!isRecord(undo)) throw new TypeError('invalid AI recovery change')
|
|
@@ -284,25 +240,15 @@ const storeState = <S extends AIStoredView>(state: S): AIStoredState => {
|
|
|
284
240
|
}
|
|
285
241
|
const saveProjection = (
|
|
286
242
|
projection: NonNullable<AIStoredView['activeProjection']>,
|
|
287
|
-
messages: UIMessage[],
|
|
288
243
|
tools: AIStoredView['tools'],
|
|
289
244
|
): Projection => {
|
|
290
|
-
const {
|
|
291
|
-
const current = messages.find(
|
|
292
|
-
(message) => message.id === projection.responseMessageId,
|
|
293
|
-
)
|
|
294
|
-
const message =
|
|
295
|
-
baseMessage === undefined
|
|
296
|
-
? undefined
|
|
297
|
-
: difference(pack(current), pack(baseMessage))
|
|
245
|
+
const { baseTools, ...fields } = projection
|
|
298
246
|
const toolPatch =
|
|
299
247
|
baseTools === undefined
|
|
300
248
|
? undefined
|
|
301
249
|
: difference(pack(tools), pack(baseTools))
|
|
302
250
|
return {
|
|
303
251
|
fields: pack(fields),
|
|
304
|
-
hasMessage: baseMessage !== undefined,
|
|
305
|
-
...(message === undefined ? {} : { message }),
|
|
306
252
|
...(toolPatch === undefined ? {} : { tools: toolPatch }),
|
|
307
253
|
}
|
|
308
254
|
}
|
|
@@ -310,9 +256,9 @@ const storeState = <S extends AIStoredView>(state: S): AIStoredState => {
|
|
|
310
256
|
const projection =
|
|
311
257
|
activeProjection === null
|
|
312
258
|
? null
|
|
313
|
-
: saveProjection(activeProjection, state.
|
|
259
|
+
: saveProjection(activeProjection, state.tools)
|
|
314
260
|
return {
|
|
315
|
-
version:
|
|
261
|
+
version: 3,
|
|
316
262
|
fields: pack(fields),
|
|
317
263
|
projection,
|
|
318
264
|
values,
|
|
@@ -352,33 +298,30 @@ const loadState = <S extends AIStoredView>(stored: AIStoredState): S => {
|
|
|
352
298
|
const state = unpack(stored.fields) as S
|
|
353
299
|
const loadProjection = (
|
|
354
300
|
saved: Projection,
|
|
355
|
-
messages: Value,
|
|
356
301
|
tools: Value | undefined,
|
|
357
302
|
): AIStoredView['activeProjection'] => {
|
|
358
303
|
if (
|
|
359
304
|
!hasKeys(saved, {
|
|
360
|
-
required: ['fields'
|
|
361
|
-
optional: ['
|
|
305
|
+
required: ['fields'],
|
|
306
|
+
optional: ['tools'],
|
|
362
307
|
}) ||
|
|
363
|
-
typeof saved.hasMessage !== 'boolean' ||
|
|
364
308
|
!isRecord(saved.fields) ||
|
|
365
|
-
('message' in saved &&
|
|
366
|
-
(!saved.hasMessage || saved.message === undefined)) ||
|
|
367
309
|
('tools' in saved && saved.tools === undefined)
|
|
368
310
|
)
|
|
369
311
|
throw new TypeError('invalid AI projection recovery')
|
|
370
312
|
const projection = unpack(saved.fields) as NonNullable<
|
|
371
313
|
AIStoredView['activeProjection']
|
|
372
314
|
>
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
)
|
|
315
|
+
if (projection.base !== undefined) {
|
|
316
|
+
assertMessageBase(projection.base)
|
|
317
|
+
const current = state.messages.find(
|
|
318
|
+
(message) => message.id === projection.responseMessageId,
|
|
319
|
+
)
|
|
320
|
+
if (
|
|
321
|
+
current !== undefined &&
|
|
322
|
+
restoreMessageBase({ current, base: projection.base }) === undefined
|
|
323
|
+
)
|
|
324
|
+
throw new TypeError('AI message base does not match its message')
|
|
382
325
|
}
|
|
383
326
|
if (tools !== undefined)
|
|
384
327
|
projection.baseTools = unpack(
|
|
@@ -391,94 +334,36 @@ const loadState = <S extends AIStoredView>(stored: AIStoredState): S => {
|
|
|
391
334
|
state.activeProjection =
|
|
392
335
|
stored.projection === null
|
|
393
336
|
? null
|
|
394
|
-
: loadProjection(stored.projection, fields['
|
|
337
|
+
: loadProjection(stored.projection, fields['tools']!)
|
|
395
338
|
return state
|
|
396
339
|
}
|
|
397
340
|
|
|
398
|
-
export const
|
|
341
|
+
export const withAIStorage = <D extends EventDefs, S extends AIStoredView>(
|
|
399
342
|
source: Reducer<D, S>,
|
|
400
|
-
):
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
}
|
|
425
|
-
views.set(state, next)
|
|
426
|
-
return state
|
|
427
|
-
}
|
|
428
|
-
return {
|
|
429
|
-
...source,
|
|
430
|
-
name: `${source.name}:records-v2`,
|
|
431
|
-
initialState: storeState(source.initialState),
|
|
432
|
-
[aiStateReducer]: source,
|
|
433
|
-
view,
|
|
434
|
-
fromView: (state) => storeState(state),
|
|
435
|
-
[clientStateProjection]: (state) =>
|
|
436
|
-
source[clientStateProjection]?.(view(state)) ?? view(state),
|
|
437
|
-
stateSchema: {
|
|
438
|
-
'~standard': {
|
|
439
|
-
version: 1,
|
|
440
|
-
vendor: 'a2-ai',
|
|
441
|
-
validate(value) {
|
|
442
|
-
try {
|
|
443
|
-
if (
|
|
444
|
-
!hasKeys(value, {
|
|
445
|
-
required: ['version', 'fields', 'projection', 'values'],
|
|
446
|
-
}) ||
|
|
447
|
-
value['version'] !== 2 ||
|
|
448
|
-
!Array.isArray(value['values']) ||
|
|
449
|
-
!isRecord(value['fields']) ||
|
|
450
|
-
(value['projection'] !== null && !isRecord(value['projection']))
|
|
451
|
-
)
|
|
452
|
-
return { issues: [{ message: 'invalid AI stored state' }] }
|
|
453
|
-
const state = value as AIStoredState
|
|
454
|
-
if (Object.keys(state.values).length !== state.values.length)
|
|
455
|
-
return { issues: [{ message: 'invalid AI payload table' }] }
|
|
456
|
-
for (const payload of state.values) {
|
|
457
|
-
if (!hasKeys(payload, { required: [], optional: ['value'] }))
|
|
458
|
-
return { issues: [{ message: 'invalid AI payload table' }] }
|
|
459
|
-
}
|
|
460
|
-
const decoded = loadState<S>(state)
|
|
461
|
-
if (source.stateSchema) {
|
|
462
|
-
const result = validateSync(
|
|
463
|
-
source.stateSchema,
|
|
464
|
-
decoded,
|
|
465
|
-
'AI view stateSchema',
|
|
466
|
-
)
|
|
467
|
-
if (result.issues) return result
|
|
468
|
-
return { value: storeState(result.value) }
|
|
469
|
-
}
|
|
470
|
-
return { value: state }
|
|
471
|
-
} catch {
|
|
472
|
-
return { issues: [{ message: 'invalid AI stored state' }] }
|
|
473
|
-
}
|
|
474
|
-
},
|
|
343
|
+
): Reducer<D, S> =>
|
|
344
|
+
withReducerRuntime({
|
|
345
|
+
reducer: source,
|
|
346
|
+
storage: {
|
|
347
|
+
encode: (state: S) => storeState(state),
|
|
348
|
+
decode(value: unknown): S {
|
|
349
|
+
if (
|
|
350
|
+
!hasKeys(value, {
|
|
351
|
+
required: ['version', 'fields', 'projection', 'values'],
|
|
352
|
+
}) ||
|
|
353
|
+
value['version'] !== 3 ||
|
|
354
|
+
!Array.isArray(value['values']) ||
|
|
355
|
+
!isRecord(value['fields']) ||
|
|
356
|
+
(value['projection'] !== null && !isRecord(value['projection']))
|
|
357
|
+
)
|
|
358
|
+
throw new TypeError('invalid AI stored state')
|
|
359
|
+
const state = value as AIStoredState
|
|
360
|
+
if (Object.keys(state.values).length !== state.values.length)
|
|
361
|
+
throw new TypeError('invalid AI payload table')
|
|
362
|
+
for (const payload of state.values) {
|
|
363
|
+
if (!hasKeys(payload, { required: [], optional: ['value'] }))
|
|
364
|
+
throw new TypeError('invalid AI payload table')
|
|
365
|
+
}
|
|
366
|
+
return loadState<S>(state)
|
|
475
367
|
},
|
|
476
368
|
},
|
|
477
|
-
|
|
478
|
-
const current = view(state)
|
|
479
|
-
const next = source.fold(current, event)
|
|
480
|
-
if (next === current) return state
|
|
481
|
-
return defer(next)
|
|
482
|
-
},
|
|
483
|
-
}
|
|
484
|
-
}
|
|
369
|
+
})
|