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
|
@@ -1,13 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
restoreMessageBase,
|
|
3
|
+
updateMessageBase,
|
|
4
|
+
type MessageBase,
|
|
5
|
+
} from './ai-message-base.ts'
|
|
1
6
|
import type { UIMessage, UIMessageChunk } from 'ai'
|
|
2
7
|
import type {
|
|
3
8
|
ActiveGenerationProjection,
|
|
9
|
+
AIState,
|
|
10
|
+
CompactionPart,
|
|
11
|
+
CompactionPartData,
|
|
12
|
+
CompactionRequestedPayload,
|
|
4
13
|
ApprovalRequestedPayload,
|
|
5
14
|
ApprovalRespondedPayload,
|
|
6
15
|
ToolCalledPayload,
|
|
7
16
|
ToolResultPayload,
|
|
8
17
|
ToolActivity,
|
|
9
18
|
} from './ai.ts'
|
|
10
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
type UIMessageCursor,
|
|
21
|
+
type ProjectionChunk,
|
|
22
|
+
projectUIMessageStream,
|
|
23
|
+
interruptUIMessage,
|
|
24
|
+
} from './ai-projector.ts'
|
|
11
25
|
import {
|
|
12
26
|
flattenProgressBatches,
|
|
13
27
|
appendProgressBatch,
|
|
@@ -15,23 +29,26 @@ import {
|
|
|
15
29
|
type ProgressBatches,
|
|
16
30
|
} from './ai-progress-batches.ts'
|
|
17
31
|
|
|
18
|
-
export type MessageProjection
|
|
19
|
-
ActiveGenerationProjection<M>,
|
|
20
|
-
'baseTools'
|
|
21
|
-
>
|
|
32
|
+
export type MessageProjection = Omit<ActiveGenerationProjection, 'baseTools'>
|
|
22
33
|
|
|
23
34
|
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
24
35
|
typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
25
36
|
|
|
37
|
+
const positionOf = (messages: readonly UIMessage[], id: string): number =>
|
|
38
|
+
messages.findLastIndex((message) => message.id === id)
|
|
39
|
+
|
|
40
|
+
export const findMessage = <M extends UIMessage>(
|
|
41
|
+
messages: M[],
|
|
42
|
+
id: string,
|
|
43
|
+
): M | undefined => messages.findLast((message) => message.id === id)
|
|
44
|
+
|
|
26
45
|
export const upsertMessage = <M extends UIMessage>(
|
|
27
46
|
messages: M[],
|
|
28
47
|
message: M,
|
|
29
48
|
): M[] => {
|
|
30
|
-
const index = messages
|
|
49
|
+
const index = positionOf(messages, message.id)
|
|
31
50
|
if (index === -1) return [...messages, message]
|
|
32
|
-
|
|
33
|
-
next[index] = message
|
|
34
|
-
return next
|
|
51
|
+
return messages[index] === message ? messages : messages.with(index, message)
|
|
35
52
|
}
|
|
36
53
|
|
|
37
54
|
export const upsertResponse = <M extends UIMessage>(options: {
|
|
@@ -40,15 +57,11 @@ export const upsertResponse = <M extends UIMessage>(options: {
|
|
|
40
57
|
inputId: string
|
|
41
58
|
}): M[] => {
|
|
42
59
|
const { messages, message, inputId } = options
|
|
43
|
-
if (messages
|
|
60
|
+
if (positionOf(messages, message.id) !== -1)
|
|
44
61
|
return upsertMessage(messages, message)
|
|
45
|
-
const inputIndex = messages
|
|
46
|
-
|
|
47
|
-
return [
|
|
48
|
-
...messages.slice(0, inputIndex + 1),
|
|
49
|
-
message,
|
|
50
|
-
...messages.slice(inputIndex + 1),
|
|
51
|
-
]
|
|
62
|
+
const inputIndex = positionOf(messages, inputId)
|
|
63
|
+
const position = inputIndex === -1 ? messages.length : inputIndex + 1
|
|
64
|
+
return [...messages.slice(0, position), message, ...messages.slice(position)]
|
|
52
65
|
}
|
|
53
66
|
|
|
54
67
|
export const answerApproval = <M extends UIMessage>(
|
|
@@ -103,6 +116,10 @@ export const approvalRespondedChunk = (
|
|
|
103
116
|
...(payload.reason === undefined ? {} : { reason: payload.reason }),
|
|
104
117
|
})
|
|
105
118
|
|
|
119
|
+
export const toolCalledChunk = (
|
|
120
|
+
payload: ToolCalledPayload,
|
|
121
|
+
): ProjectionChunk => ({ type: 'a2-tool-called', call: payload })
|
|
122
|
+
|
|
106
123
|
export const toolResultChunk = (payload: ToolResultPayload): UIMessageChunk => {
|
|
107
124
|
if (payload.phase === 'input') {
|
|
108
125
|
return {
|
|
@@ -166,17 +183,27 @@ export const toolResultChunk = (payload: ToolResultPayload): UIMessageChunk => {
|
|
|
166
183
|
} as UIMessageChunk
|
|
167
184
|
}
|
|
168
185
|
|
|
169
|
-
export const projectedMessageStream = <M extends UIMessage>(
|
|
170
|
-
projection
|
|
171
|
-
|
|
172
|
-
|
|
186
|
+
export const projectedMessageStream = <M extends UIMessage>({
|
|
187
|
+
projection,
|
|
188
|
+
current,
|
|
189
|
+
}: {
|
|
190
|
+
projection: MessageProjection
|
|
191
|
+
current: M | undefined
|
|
192
|
+
}): { message: M; cursor: UIMessageCursor; throughIndex: number } => {
|
|
193
|
+
const base = restoreMessageBase({ current, base: projection.base })
|
|
194
|
+
const projectionEvents: Array<{
|
|
195
|
+
index: number
|
|
196
|
+
chunks: readonly ProjectionChunk[]
|
|
197
|
+
}> = flattenProgressBatches(projection.batches)
|
|
173
198
|
for (const event of projection.toolEvents) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
199
|
+
projectionEvents.push({
|
|
200
|
+
index: event.index,
|
|
201
|
+
chunks: [
|
|
202
|
+
event.type === 'ai.tool.called'
|
|
203
|
+
? toolCalledChunk(event.payload)
|
|
204
|
+
: toolResultChunk(event.payload),
|
|
205
|
+
],
|
|
206
|
+
})
|
|
180
207
|
}
|
|
181
208
|
for (const event of projection.approvalEvents) {
|
|
182
209
|
projectionEvents.push({
|
|
@@ -188,20 +215,23 @@ export const projectedMessageStream = <M extends UIMessage>(
|
|
|
188
215
|
],
|
|
189
216
|
})
|
|
190
217
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
.flatMap((event) => event.chunks),
|
|
199
|
-
|
|
218
|
+
const ordered = projectionEvents.toSorted(
|
|
219
|
+
(left, right) => left.index - right.index,
|
|
220
|
+
)
|
|
221
|
+
return {
|
|
222
|
+
...projectUIMessageStream<M>({
|
|
223
|
+
messageId: projection.responseMessageId,
|
|
224
|
+
...(base === undefined ? {} : { base }),
|
|
225
|
+
chunks: ordered.flatMap((event) => event.chunks),
|
|
226
|
+
}),
|
|
227
|
+
throughIndex: ordered.at(-1)?.index ?? 0,
|
|
228
|
+
}
|
|
200
229
|
}
|
|
201
230
|
|
|
202
|
-
export const projectedMessage = <M extends UIMessage>(
|
|
203
|
-
projection: MessageProjection
|
|
204
|
-
|
|
231
|
+
export const projectedMessage = <M extends UIMessage>(options: {
|
|
232
|
+
projection: MessageProjection
|
|
233
|
+
current: M | undefined
|
|
234
|
+
}): M => projectedMessageStream(options).message
|
|
205
235
|
|
|
206
236
|
export const reduceToolActivity = (
|
|
207
237
|
tools: ToolActivity[],
|
|
@@ -211,12 +241,17 @@ export const reduceToolActivity = (
|
|
|
211
241
|
): ToolActivity[] => {
|
|
212
242
|
if (event.type === 'ai.tool.called') {
|
|
213
243
|
const payload = event.payload
|
|
214
|
-
const { providerMetadata, ...called } = payload
|
|
215
244
|
const activity: ToolActivity = {
|
|
216
|
-
|
|
217
|
-
|
|
245
|
+
requestId: payload.requestId,
|
|
246
|
+
messageId: payload.messageId,
|
|
247
|
+
generationId: payload.generationId,
|
|
248
|
+
toolCallId: payload.toolCallId,
|
|
249
|
+
toolName: payload.toolName,
|
|
250
|
+
...(payload.dynamic === undefined ? {} : { dynamic: payload.dynamic }),
|
|
251
|
+
...(payload.providerExecuted === undefined
|
|
218
252
|
? {}
|
|
219
|
-
: {
|
|
253
|
+
: { providerExecuted: payload.providerExecuted }),
|
|
254
|
+
...(payload.title === undefined ? {} : { title: payload.title }),
|
|
220
255
|
status: 'running',
|
|
221
256
|
}
|
|
222
257
|
return [
|
|
@@ -236,22 +271,15 @@ export const reduceToolActivity = (
|
|
|
236
271
|
candidate.toolCallId === payload.toolCallId,
|
|
237
272
|
)
|
|
238
273
|
const toolName = payload.toolName ?? existing?.toolName
|
|
239
|
-
const input = payload.input === undefined ? existing?.input : payload.input
|
|
240
274
|
const dynamic = payload.dynamic ?? existing?.dynamic
|
|
241
275
|
const providerExecuted =
|
|
242
276
|
payload.providerExecuted ?? existing?.providerExecuted
|
|
243
|
-
const toolMetadata = payload.toolMetadata ?? existing?.toolMetadata
|
|
244
|
-
const resultProviderMetadata =
|
|
245
|
-
payload.providerMetadata ?? existing?.resultProviderMetadata
|
|
246
277
|
const activity: ToolActivity = {
|
|
247
278
|
requestId: payload.requestId,
|
|
248
279
|
messageId: payload.messageId,
|
|
249
280
|
generationId: payload.generationId,
|
|
250
281
|
toolCallId: payload.toolCallId,
|
|
251
282
|
...(toolName === undefined ? {} : { toolName }),
|
|
252
|
-
...(input === undefined ? {} : { input }),
|
|
253
|
-
...(payload.rawInput === undefined ? {} : { rawInput: payload.rawInput }),
|
|
254
|
-
...(payload.output === undefined ? {} : { output: payload.output }),
|
|
255
283
|
...(payload.error === undefined ? {} : { error: payload.error }),
|
|
256
284
|
...(payload.preliminary === undefined
|
|
257
285
|
? {}
|
|
@@ -259,11 +287,6 @@ export const reduceToolActivity = (
|
|
|
259
287
|
...(payload.phase === undefined ? {} : { phase: payload.phase }),
|
|
260
288
|
...(dynamic === undefined ? {} : { dynamic }),
|
|
261
289
|
...(providerExecuted === undefined ? {} : { providerExecuted }),
|
|
262
|
-
...(existing?.callProviderMetadata === undefined
|
|
263
|
-
? {}
|
|
264
|
-
: { callProviderMetadata: existing.callProviderMetadata }),
|
|
265
|
-
...(resultProviderMetadata === undefined ? {} : { resultProviderMetadata }),
|
|
266
|
-
...(toolMetadata === undefined ? {} : { toolMetadata }),
|
|
267
290
|
...(existing?.title === undefined ? {} : { title: existing.title }),
|
|
268
291
|
status: payload.denied
|
|
269
292
|
? 'denied'
|
|
@@ -289,14 +312,14 @@ export const advanceProjection = <M extends UIMessage>({
|
|
|
289
312
|
chunks,
|
|
290
313
|
index,
|
|
291
314
|
}: {
|
|
292
|
-
projection: MessageProjection
|
|
315
|
+
projection: MessageProjection
|
|
293
316
|
base: M | undefined
|
|
294
317
|
chunks: UIMessageChunk[]
|
|
295
318
|
index: number
|
|
296
319
|
}): {
|
|
297
320
|
message: M
|
|
298
321
|
batches: ProgressBatches
|
|
299
|
-
cursor: NonNullable<MessageProjection
|
|
322
|
+
cursor: NonNullable<MessageProjection['cursor']>
|
|
300
323
|
} => {
|
|
301
324
|
const ordered = index > (projection.batches.tail.at(-1)?.index ?? -1)
|
|
302
325
|
const batches = ordered
|
|
@@ -323,7 +346,10 @@ export const advanceProjection = <M extends UIMessage>({
|
|
|
323
346
|
cursor: projection.cursor!.stream,
|
|
324
347
|
chunks,
|
|
325
348
|
})
|
|
326
|
-
: projectedMessageStream({
|
|
349
|
+
: projectedMessageStream({
|
|
350
|
+
projection: { ...projection, batches },
|
|
351
|
+
current: base,
|
|
352
|
+
})
|
|
327
353
|
return {
|
|
328
354
|
message: projected.message,
|
|
329
355
|
batches,
|
|
@@ -346,3 +372,301 @@ export const advanceProjection = <M extends UIMessage>({
|
|
|
346
372
|
},
|
|
347
373
|
}
|
|
348
374
|
}
|
|
375
|
+
|
|
376
|
+
export const projectedTools = (
|
|
377
|
+
projection: ActiveGenerationProjection,
|
|
378
|
+
): ToolActivity[] =>
|
|
379
|
+
projection.toolEvents.reduce(
|
|
380
|
+
(tools, event) => reduceToolActivity(tools, event),
|
|
381
|
+
projection.baseTools,
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
export const restoreGenerationBase = <M extends UIMessage>(
|
|
385
|
+
state: AIState<M>,
|
|
386
|
+
generationId: string,
|
|
387
|
+
responseMessageId: string,
|
|
388
|
+
reason: 'interrupted' | 'superseded' | 'failed',
|
|
389
|
+
): AIState<M> => {
|
|
390
|
+
const projection =
|
|
391
|
+
state.activeProjection?.generationId === generationId
|
|
392
|
+
? state.activeProjection
|
|
393
|
+
: null
|
|
394
|
+
const restored = restoreMessageBase({
|
|
395
|
+
current: findMessage(state.messages, responseMessageId),
|
|
396
|
+
base: projection?.base,
|
|
397
|
+
})
|
|
398
|
+
// A superseded attempt's unfinished compaction reruns in its replacement;
|
|
399
|
+
// a completed one stays in effect, and so does its part.
|
|
400
|
+
const base =
|
|
401
|
+
restored !== undefined && reason === 'superseded'
|
|
402
|
+
? withoutRunningCompactionPart(restored, generationId)
|
|
403
|
+
: restored
|
|
404
|
+
return {
|
|
405
|
+
...state,
|
|
406
|
+
messages:
|
|
407
|
+
base === undefined
|
|
408
|
+
? state.messages.filter((message) => message.id !== responseMessageId)
|
|
409
|
+
: upsertMessage(state.messages, base),
|
|
410
|
+
tools:
|
|
411
|
+
projection === null
|
|
412
|
+
? state.tools.filter(
|
|
413
|
+
(activity) => activity.generationId !== generationId,
|
|
414
|
+
)
|
|
415
|
+
: projection.baseTools,
|
|
416
|
+
pendingApprovals: state.pendingApprovals.filter(
|
|
417
|
+
(approval) => approval.generationId !== generationId,
|
|
418
|
+
),
|
|
419
|
+
pendingInputs: state.pendingInputs.filter(
|
|
420
|
+
(input) => input.generationId !== generationId,
|
|
421
|
+
),
|
|
422
|
+
activeGeneration: null,
|
|
423
|
+
activeProjection: null,
|
|
424
|
+
terminalGenerations: {
|
|
425
|
+
...state.terminalGenerations,
|
|
426
|
+
[generationId]: reason,
|
|
427
|
+
},
|
|
428
|
+
compaction:
|
|
429
|
+
projection === null
|
|
430
|
+
? state.compaction?.generationId === generationId
|
|
431
|
+
? null
|
|
432
|
+
: state.compaction
|
|
433
|
+
: (projection.baseCompaction ?? null),
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
export const stopGenerationTools = (
|
|
438
|
+
tools: ToolActivity[],
|
|
439
|
+
generationId: string | undefined,
|
|
440
|
+
responseMessageId: string,
|
|
441
|
+
error: string,
|
|
442
|
+
): ToolActivity[] =>
|
|
443
|
+
tools.map((activity) =>
|
|
444
|
+
activity.status === 'running' &&
|
|
445
|
+
(generationId === undefined
|
|
446
|
+
? activity.messageId === responseMessageId
|
|
447
|
+
: activity.generationId === generationId)
|
|
448
|
+
? { ...activity, status: 'failed', error, preliminary: false }
|
|
449
|
+
: activity,
|
|
450
|
+
)
|
|
451
|
+
|
|
452
|
+
export const interruptGenerationProjection = <M extends UIMessage>(
|
|
453
|
+
state: AIState<M>,
|
|
454
|
+
generationId: string,
|
|
455
|
+
responseMessageId: string,
|
|
456
|
+
cutoff: number,
|
|
457
|
+
): AIState<M> | null => {
|
|
458
|
+
const projection =
|
|
459
|
+
state.activeProjection?.generationId === generationId
|
|
460
|
+
? state.activeProjection
|
|
461
|
+
: null
|
|
462
|
+
if (projection === null) return null
|
|
463
|
+
const retained: ActiveGenerationProjection = {
|
|
464
|
+
...projection,
|
|
465
|
+
batches: progressBatches(
|
|
466
|
+
flattenProgressBatches(projection.batches).filter(
|
|
467
|
+
(batch) => batch.index <= cutoff,
|
|
468
|
+
),
|
|
469
|
+
),
|
|
470
|
+
toolEvents: projection.toolEvents.filter(
|
|
471
|
+
(toolEvent) => toolEvent.index <= cutoff,
|
|
472
|
+
),
|
|
473
|
+
approvalEvents: projection.approvalEvents.filter(
|
|
474
|
+
(approvalEvent) => approvalEvent.index <= cutoff,
|
|
475
|
+
),
|
|
476
|
+
}
|
|
477
|
+
const shouldProject =
|
|
478
|
+
retained.base !== undefined || retained.batches.length > 0
|
|
479
|
+
const restored = restoreGenerationBase(
|
|
480
|
+
state,
|
|
481
|
+
generationId,
|
|
482
|
+
responseMessageId,
|
|
483
|
+
'interrupted',
|
|
484
|
+
)
|
|
485
|
+
return {
|
|
486
|
+
...restored,
|
|
487
|
+
messages: shouldProject
|
|
488
|
+
? upsertMessage(
|
|
489
|
+
state.messages,
|
|
490
|
+
interruptUIMessage(
|
|
491
|
+
projectedMessage({
|
|
492
|
+
projection: retained,
|
|
493
|
+
current: findMessage(state.messages, responseMessageId),
|
|
494
|
+
}),
|
|
495
|
+
),
|
|
496
|
+
)
|
|
497
|
+
: restored.messages,
|
|
498
|
+
tools: stopGenerationTools(
|
|
499
|
+
projectedTools(retained),
|
|
500
|
+
generationId,
|
|
501
|
+
responseMessageId,
|
|
502
|
+
'Tool execution was interrupted.',
|
|
503
|
+
),
|
|
504
|
+
usage:
|
|
505
|
+
projection.completionIndex === undefined ||
|
|
506
|
+
projection.completionIndex <= cutoff
|
|
507
|
+
? restored.usage
|
|
508
|
+
: restored.usage.filter((entry) => entry.generationId !== generationId),
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
export const retainMessageBase = <
|
|
513
|
+
S extends {
|
|
514
|
+
messages: UIMessage[]
|
|
515
|
+
activeProjection: { responseMessageId: string; base?: MessageBase } | null
|
|
516
|
+
},
|
|
517
|
+
>(options: {
|
|
518
|
+
before: S
|
|
519
|
+
after: S
|
|
520
|
+
}): S => {
|
|
521
|
+
const { before, after } = options
|
|
522
|
+
const projection = after.activeProjection
|
|
523
|
+
if (
|
|
524
|
+
before.messages === after.messages ||
|
|
525
|
+
!projection?.base ||
|
|
526
|
+
projection.base !== before.activeProjection?.base
|
|
527
|
+
)
|
|
528
|
+
return after
|
|
529
|
+
const previous = findMessage(before.messages, projection.responseMessageId)
|
|
530
|
+
const current = findMessage(after.messages, projection.responseMessageId)
|
|
531
|
+
if (previous !== undefined && previous === current) return after
|
|
532
|
+
// A response removed or rewritten outside this tracking (for example, by an
|
|
533
|
+
// extension's own transition) cannot be restored, so a later re-created
|
|
534
|
+
// message must not inherit the stale recovery.
|
|
535
|
+
const base =
|
|
536
|
+
previous &&
|
|
537
|
+
current &&
|
|
538
|
+
updateMessageBase({
|
|
539
|
+
base: projection.base,
|
|
540
|
+
before: previous,
|
|
541
|
+
after: current,
|
|
542
|
+
})
|
|
543
|
+
const { base: _stale, ...unrecoverable } = projection
|
|
544
|
+
return {
|
|
545
|
+
...after,
|
|
546
|
+
activeProjection: base ? { ...unrecoverable, base } : unrecoverable,
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
export const isCompactionPart = (part: {
|
|
551
|
+
type: string
|
|
552
|
+
}): part is CompactionPart => part.type === 'data-a2-compaction'
|
|
553
|
+
|
|
554
|
+
const compactionPartOf = (message: UIMessage, generationId: string): number =>
|
|
555
|
+
message.parts.findIndex(
|
|
556
|
+
(part) => isCompactionPart(part) && part.id === generationId,
|
|
557
|
+
)
|
|
558
|
+
|
|
559
|
+
const withoutRunningCompactionPart = <M extends UIMessage>(
|
|
560
|
+
message: M,
|
|
561
|
+
generationId: string,
|
|
562
|
+
): M => {
|
|
563
|
+
const index = compactionPartOf(message, generationId)
|
|
564
|
+
const part = message.parts[index]
|
|
565
|
+
return part !== undefined &&
|
|
566
|
+
isCompactionPart(part) &&
|
|
567
|
+
part.data.status === 'running'
|
|
568
|
+
? { ...message, parts: message.parts.toSpliced(index, 1) }
|
|
569
|
+
: message
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Compaction runs before its model step streams, so the part lands between
|
|
574
|
+
* the response's earlier steps and this one. Counting it in the step's base
|
|
575
|
+
* keeps it through Stop cutoffs, failures, and retries of that step.
|
|
576
|
+
*/
|
|
577
|
+
export const addCompactionPart = <M extends UIMessage>(
|
|
578
|
+
state: AIState<M>,
|
|
579
|
+
payload: CompactionRequestedPayload,
|
|
580
|
+
): AIState<M> => {
|
|
581
|
+
const projection = state.activeProjection
|
|
582
|
+
if (projection?.generationId !== payload.generationId) return state
|
|
583
|
+
const current = findMessage(state.messages, projection.responseMessageId)
|
|
584
|
+
if (
|
|
585
|
+
current === undefined
|
|
586
|
+
? projection.base !== undefined
|
|
587
|
+
: projection.base?.partCount !== current.parts.length
|
|
588
|
+
)
|
|
589
|
+
return state
|
|
590
|
+
const inputTokens = payload.inputTokens ?? payload.inputTokenEstimate
|
|
591
|
+
const part: CompactionPart = {
|
|
592
|
+
type: 'data-a2-compaction',
|
|
593
|
+
id: payload.generationId,
|
|
594
|
+
data: {
|
|
595
|
+
status: 'running',
|
|
596
|
+
...(inputTokens === undefined ? {} : { inputTokens }),
|
|
597
|
+
...(payload.thresholdTokens === undefined
|
|
598
|
+
? {}
|
|
599
|
+
: { thresholdTokens: payload.thresholdTokens }),
|
|
600
|
+
},
|
|
601
|
+
}
|
|
602
|
+
const message = (
|
|
603
|
+
current === undefined
|
|
604
|
+
? { id: projection.responseMessageId, role: 'assistant', parts: [part] }
|
|
605
|
+
: { ...current, parts: [...current.parts, part] }
|
|
606
|
+
) as M
|
|
607
|
+
return {
|
|
608
|
+
...state,
|
|
609
|
+
messages: upsertResponse({
|
|
610
|
+
messages: state.messages,
|
|
611
|
+
message,
|
|
612
|
+
inputId: state.activeGeneration?.messageId ?? message.id,
|
|
613
|
+
}),
|
|
614
|
+
activeProjection: {
|
|
615
|
+
...projection,
|
|
616
|
+
cursor: null,
|
|
617
|
+
base:
|
|
618
|
+
projection.base === undefined
|
|
619
|
+
? { partCount: 1 }
|
|
620
|
+
: { ...projection.base, partCount: projection.base.partCount + 1 },
|
|
621
|
+
},
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
export const settleCompactionPart = <M extends UIMessage>(options: {
|
|
626
|
+
state: AIState<M>
|
|
627
|
+
generationId: string
|
|
628
|
+
data: Partial<CompactionPartData>
|
|
629
|
+
}): AIState<M> => {
|
|
630
|
+
const { state, generationId, data } = options
|
|
631
|
+
const position = state.messages.findLastIndex(
|
|
632
|
+
(message) => compactionPartOf(message, generationId) !== -1,
|
|
633
|
+
)
|
|
634
|
+
if (position === -1) return state
|
|
635
|
+
const message = state.messages[position]!
|
|
636
|
+
const index = compactionPartOf(message, generationId)
|
|
637
|
+
const part = message.parts[index] as unknown as CompactionPart
|
|
638
|
+
return {
|
|
639
|
+
...state,
|
|
640
|
+
messages: state.messages.with(position, {
|
|
641
|
+
...message,
|
|
642
|
+
parts: message.parts.with(index, {
|
|
643
|
+
...part,
|
|
644
|
+
data: { ...part.data, ...data },
|
|
645
|
+
} as unknown as M['parts'][number]),
|
|
646
|
+
}),
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/** A running compaction whose state reverted without completing was abandoned. */
|
|
651
|
+
export const settleAbandonedCompaction = <M extends UIMessage>(
|
|
652
|
+
before: AIState<M>,
|
|
653
|
+
after: AIState<M>,
|
|
654
|
+
): AIState<M> => {
|
|
655
|
+
const running = before.compaction
|
|
656
|
+
if (
|
|
657
|
+
running?.status !== 'running' ||
|
|
658
|
+
after.compaction === running ||
|
|
659
|
+
(after.compaction?.status === 'completed' &&
|
|
660
|
+
after.compaction.generationId === running.generationId)
|
|
661
|
+
)
|
|
662
|
+
return after
|
|
663
|
+
const interrupted =
|
|
664
|
+
after.status === 'closed' ||
|
|
665
|
+
after.pausedGenerationIds?.[running.generationId] === true ||
|
|
666
|
+
after.terminalGenerations?.[running.generationId] === 'interrupted'
|
|
667
|
+
return settleCompactionPart({
|
|
668
|
+
state: after,
|
|
669
|
+
generationId: running.generationId,
|
|
670
|
+
data: { status: interrupted ? 'interrupted' : 'failed' },
|
|
671
|
+
})
|
|
672
|
+
}
|
|
@@ -1,4 +1,30 @@
|
|
|
1
1
|
import type { UIMessageChunk } from 'ai'
|
|
2
|
+
import type { GenerationProgressPayload } from './ai.ts'
|
|
3
|
+
|
|
4
|
+
/** Progress already in a log may name its generation by ids instead of `startIndex`. */
|
|
5
|
+
export type StoredProgressPayload =
|
|
6
|
+
| GenerationProgressPayload
|
|
7
|
+
| {
|
|
8
|
+
requestId: string
|
|
9
|
+
generationId: string
|
|
10
|
+
responseMessageId: string
|
|
11
|
+
chunks: UIMessageChunk[]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const progressOwnedBy = ({
|
|
15
|
+
payload,
|
|
16
|
+
owner,
|
|
17
|
+
startIndex,
|
|
18
|
+
}: {
|
|
19
|
+
payload: StoredProgressPayload
|
|
20
|
+
owner: { requestId: string; generationId: string; responseMessageId: string }
|
|
21
|
+
startIndex: number
|
|
22
|
+
}): boolean =>
|
|
23
|
+
'startIndex' in payload
|
|
24
|
+
? payload.startIndex === startIndex
|
|
25
|
+
: payload.requestId === owner.requestId &&
|
|
26
|
+
payload.generationId === owner.generationId &&
|
|
27
|
+
payload.responseMessageId === owner.responseMessageId
|
|
2
28
|
|
|
3
29
|
export type ProgressBatch = { index: number; chunks: UIMessageChunk[] }
|
|
4
30
|
type BatchBlock = ProgressBatch[] | { left: BatchBlock; right: BatchBlock }
|