experimental-a2 0.16.1 → 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 +352 -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-DgOBltJ_.js → ai-UrWfKeuv.js} +621 -216
- 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 +432 -258
- package/dist/ai-server.js.map +1 -1
- package/dist/{ai-CrEf6p_W.d.ts → ai-vpGtcaCB.d.ts} +114 -100
- 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 +671 -581
- 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 +656 -194
- 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 +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-message-base.ts +209 -0
- package/src/ai-message-projection.ts +262 -64
- 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 -1964
- 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 +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-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/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,8 +1,135 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as
|
|
3
|
-
import { t as contract } from "./contract-CKRg_E4q.js";
|
|
1
|
+
import { a as reducer, o as assertSyncSchema, s as validateSync } from "./reducer-BAXc8JyF.js";
|
|
2
|
+
import { t as contract } from "./contract-BYKASlCV.js";
|
|
4
3
|
import { t as idempotentId } from "./idempotent-id-BRJVeylj.js";
|
|
5
|
-
import {
|
|
4
|
+
import { i as withReducerRuntime } from "./reducer-runtime-DQwz_J59.js";
|
|
5
|
+
import { u as ambientToolScopeStorage } from "./internal-CbVvEwad.js";
|
|
6
|
+
//#region src/equal-json.ts
|
|
7
|
+
const sameValue = (left, right) => {
|
|
8
|
+
if (Object.is(left, right)) return true;
|
|
9
|
+
if (typeof left !== "object" || left === null || typeof right !== "object" || right === null) return false;
|
|
10
|
+
const prototype = Object.getPrototypeOf(left);
|
|
11
|
+
if (prototype !== Object.getPrototypeOf(right) || prototype !== Object.prototype && prototype !== Array.prototype && prototype !== null) return false;
|
|
12
|
+
if (Array.isArray(left) && (!Array.isArray(right) || left.length !== right.length)) return false;
|
|
13
|
+
const keys = Reflect.ownKeys(left);
|
|
14
|
+
return keys.length === Reflect.ownKeys(right).length && keys.every((key) => Object.hasOwn(right, key) && sameValue(Reflect.get(left, key), Reflect.get(right, key)));
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/ai-message-base.ts
|
|
18
|
+
const record = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19
|
+
const assertFields = (fields) => {
|
|
20
|
+
if (fields === void 0) return;
|
|
21
|
+
if (!record(fields)) throw new TypeError("invalid AI message base fields");
|
|
22
|
+
for (const [key, undo] of Object.entries(fields)) if (!record(undo) || Object.keys(undo).length > 1 || !(Object.keys(undo).length === 0 || "value" in undo || undo["remove"] === true || key === "text" && Number.isSafeInteger(undo["length"]) && undo["length"] >= 0)) throw new TypeError("invalid AI message base field");
|
|
23
|
+
};
|
|
24
|
+
/** Checks decoded recovery data; `restoreMessageBase` trusts this shape. */
|
|
25
|
+
function assertMessageBase(value) {
|
|
26
|
+
if (!record(value) || !Number.isSafeInteger(value["partCount"]) || value["partCount"] < 0 || value["partCount"] > 4294967294 || Object.keys(value).some((key) => ![
|
|
27
|
+
"partCount",
|
|
28
|
+
"fields",
|
|
29
|
+
"parts"
|
|
30
|
+
].includes(key)) || value["parts"] !== void 0 && !record(value["parts"])) throw new TypeError("invalid AI message base");
|
|
31
|
+
assertFields(value["fields"]);
|
|
32
|
+
const partCount = value["partCount"];
|
|
33
|
+
for (const [key, undo] of Object.entries(value["parts"] ?? {})) {
|
|
34
|
+
const index = Number(key);
|
|
35
|
+
if (!Number.isSafeInteger(index) || String(index) !== key || index < 0 || index >= partCount || !record(undo) || Object.keys(undo).length !== 1 || !("value" in undo && record(undo["value"]) || "fields" in undo)) throw new TypeError("invalid AI message base part");
|
|
36
|
+
if ("fields" in undo) assertFields(undo["fields"]);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const restoreFields = (current, fields) => {
|
|
40
|
+
if (fields === void 0) return current;
|
|
41
|
+
const restored = { ...current };
|
|
42
|
+
for (const [key, undo] of Object.entries(fields)) if ("remove" in undo) delete restored[key];
|
|
43
|
+
else if ("length" in undo) {
|
|
44
|
+
const text = current[key];
|
|
45
|
+
if (typeof text !== "string" || undo.length > text.length) return void 0;
|
|
46
|
+
restored[key] = text.slice(0, undo.length);
|
|
47
|
+
} else Object.defineProperty(restored, key, {
|
|
48
|
+
value: undo.value,
|
|
49
|
+
enumerable: true,
|
|
50
|
+
writable: true,
|
|
51
|
+
configurable: true
|
|
52
|
+
});
|
|
53
|
+
return restored;
|
|
54
|
+
};
|
|
55
|
+
/** `undefined` when `base` no longer describes `current`, including a removed message. */
|
|
56
|
+
const restoreMessageBase = (options) => {
|
|
57
|
+
const { current, base } = options;
|
|
58
|
+
if (base === void 0 || current === void 0) return void 0;
|
|
59
|
+
const parts = current.parts.slice(0, base.partCount);
|
|
60
|
+
for (const [key, undo] of Object.entries(base.parts ?? {})) {
|
|
61
|
+
const index = Number(key);
|
|
62
|
+
if ("value" in undo) {
|
|
63
|
+
parts[index] = undo.value;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const part = parts[index];
|
|
67
|
+
const restored = part === void 0 ? void 0 : restoreFields(part, undo.fields);
|
|
68
|
+
if (!restored) return void 0;
|
|
69
|
+
parts[index] = restored;
|
|
70
|
+
}
|
|
71
|
+
if (parts.length !== base.partCount || Object.keys(parts).length !== parts.length) return void 0;
|
|
72
|
+
const { parts: _parts, ...fields } = current;
|
|
73
|
+
const restored = restoreFields(fields, base.fields);
|
|
74
|
+
return restored && {
|
|
75
|
+
...restored,
|
|
76
|
+
parts
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
const updateFields = (options) => {
|
|
80
|
+
const { before, after, undo } = options;
|
|
81
|
+
const original = restoreFields(before, undo);
|
|
82
|
+
if (!original) return void 0;
|
|
83
|
+
return Object.fromEntries([.../* @__PURE__ */ new Set([...Object.keys(original), ...Object.keys(after)])].flatMap((key) => {
|
|
84
|
+
if (Object.hasOwn(original, key) === Object.hasOwn(after, key) && sameValue(original[key], after[key])) return [];
|
|
85
|
+
const value = original[key];
|
|
86
|
+
const next = after[key];
|
|
87
|
+
return [[key, !Object.hasOwn(original, key) ? { remove: true } : key === "text" && typeof value === "string" && typeof next === "string" && next.startsWith(value) ? { length: value.length } : value === void 0 ? {} : { value }]];
|
|
88
|
+
}));
|
|
89
|
+
};
|
|
90
|
+
/** `undefined` when `before` no longer matches `base`, so the recovery must be dropped. */
|
|
91
|
+
const updateMessageBase = (options) => {
|
|
92
|
+
const { base, before, after } = options;
|
|
93
|
+
if (before === after) return base;
|
|
94
|
+
const { parts: beforeParts, ...beforeFields } = before;
|
|
95
|
+
const { parts: afterParts, ...afterFields } = after;
|
|
96
|
+
const fields = updateFields({
|
|
97
|
+
before: beforeFields,
|
|
98
|
+
after: afterFields,
|
|
99
|
+
...base.fields && { undo: base.fields }
|
|
100
|
+
});
|
|
101
|
+
if (!fields) return void 0;
|
|
102
|
+
const parts = [];
|
|
103
|
+
for (let index = 0; index < base.partCount; index += 1) {
|
|
104
|
+
const previous = beforeParts[index];
|
|
105
|
+
const current = afterParts[index];
|
|
106
|
+
const undo = base.parts?.[index];
|
|
107
|
+
const original = undo && "value" in undo ? undo.value : previous;
|
|
108
|
+
if (!original) return void 0;
|
|
109
|
+
if (previous === current && undo === void 0) continue;
|
|
110
|
+
const originalFields = original;
|
|
111
|
+
const undoFields = undo && "fields" in undo ? undo.fields : void 0;
|
|
112
|
+
if (!current) {
|
|
113
|
+
const value = restoreFields(originalFields, undoFields);
|
|
114
|
+
if (!value) return void 0;
|
|
115
|
+
parts.push([String(index), { value }]);
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
const changed = updateFields({
|
|
119
|
+
before: originalFields,
|
|
120
|
+
after: current,
|
|
121
|
+
...undoFields && { undo: undoFields }
|
|
122
|
+
});
|
|
123
|
+
if (!changed) return void 0;
|
|
124
|
+
if (Object.keys(changed).length > 0) parts.push([String(index), { fields: changed }]);
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
partCount: base.partCount,
|
|
128
|
+
...Object.keys(fields).length > 0 && { fields },
|
|
129
|
+
...parts.length > 0 && { parts: Object.fromEntries(parts) }
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
//#endregion
|
|
6
133
|
//#region src/parse-partial-json.ts
|
|
7
134
|
/*!
|
|
8
135
|
* Adapted from AI SDK 7.0.58, packages/ai/src/util/fix-json.ts.
|
|
@@ -284,7 +411,13 @@ const cloneMessage = (messageId, base) => base === void 0 ? {
|
|
|
284
411
|
} : {
|
|
285
412
|
...base,
|
|
286
413
|
id: messageId,
|
|
287
|
-
parts: base.parts
|
|
414
|
+
parts: [...base.parts]
|
|
415
|
+
};
|
|
416
|
+
const editPart = ({ parts, part }) => {
|
|
417
|
+
const index = parts.indexOf(part);
|
|
418
|
+
const next = { ...part };
|
|
419
|
+
parts[index] = next;
|
|
420
|
+
return next;
|
|
288
421
|
};
|
|
289
422
|
const currentStepParts = (parts) => {
|
|
290
423
|
let start = parts.length - 1;
|
|
@@ -297,6 +430,10 @@ const findToolPart = (parts, toolCallId) => {
|
|
|
297
430
|
if (current) return current;
|
|
298
431
|
return parts.findLast((part) => isToolPart(part) && part["toolCallId"] === toolCallId);
|
|
299
432
|
};
|
|
433
|
+
const hasToolCall = ({ message, call }) => {
|
|
434
|
+
const part = findToolPart(message.parts, call.toolCallId);
|
|
435
|
+
return part !== void 0 && part["state"] !== "input-streaming" && sameValue(part["input"], call.input) && (part["callProviderMetadata"] !== void 0 || call.providerMetadata === void 0) && (part["toolMetadata"] !== void 0 || call.toolMetadata === void 0) && (call.providerExecuted === void 0 || part["providerExecuted"] === call.providerExecuted) && (call.title === void 0 || part["title"] === call.title);
|
|
436
|
+
};
|
|
300
437
|
const findApprovalPart = (parts, approvalId) => parts.find((part) => {
|
|
301
438
|
const approval = part["approval"];
|
|
302
439
|
return isToolPart(part) && isRecord$3(approval) && approval["id"] === approvalId;
|
|
@@ -313,7 +450,10 @@ const setToolPart = (options) => {
|
|
|
313
450
|
toolCallId: options.toolCallId
|
|
314
451
|
};
|
|
315
452
|
options.parts.push(part);
|
|
316
|
-
}
|
|
453
|
+
} else part = editPart({
|
|
454
|
+
parts: options.parts,
|
|
455
|
+
part
|
|
456
|
+
});
|
|
317
457
|
part["state"] = options.state;
|
|
318
458
|
part["input"] = options.input;
|
|
319
459
|
delete part["output"];
|
|
@@ -371,13 +511,22 @@ function projectUIMessageStream(options) {
|
|
|
371
511
|
activeText.set(chunk.id, part);
|
|
372
512
|
parts.push(part);
|
|
373
513
|
}
|
|
514
|
+
part = editPart({
|
|
515
|
+
parts,
|
|
516
|
+
part
|
|
517
|
+
});
|
|
518
|
+
activeText.set(chunk.id, part);
|
|
374
519
|
part["text"] = `${typeof part["text"] === "string" ? part["text"] : ""}${chunk.delta}`;
|
|
375
520
|
setOptional(part, "providerMetadata", chunk.providerMetadata);
|
|
376
521
|
break;
|
|
377
522
|
}
|
|
378
523
|
case "text-end": {
|
|
379
|
-
const
|
|
380
|
-
if (
|
|
524
|
+
const current = activeText.get(chunk.id);
|
|
525
|
+
if (current) {
|
|
526
|
+
const part = editPart({
|
|
527
|
+
parts,
|
|
528
|
+
part: current
|
|
529
|
+
});
|
|
381
530
|
part["state"] = "done";
|
|
382
531
|
setOptional(part, "providerMetadata", chunk.providerMetadata);
|
|
383
532
|
activeText.delete(chunk.id);
|
|
@@ -406,13 +555,22 @@ function projectUIMessageStream(options) {
|
|
|
406
555
|
activeReasoning.set(chunk.id, part);
|
|
407
556
|
parts.push(part);
|
|
408
557
|
}
|
|
558
|
+
part = editPart({
|
|
559
|
+
parts,
|
|
560
|
+
part
|
|
561
|
+
});
|
|
562
|
+
activeReasoning.set(chunk.id, part);
|
|
409
563
|
part["text"] = `${typeof part["text"] === "string" ? part["text"] : ""}${chunk.delta}`;
|
|
410
564
|
setOptional(part, "providerMetadata", chunk.providerMetadata);
|
|
411
565
|
break;
|
|
412
566
|
}
|
|
413
567
|
case "reasoning-end": {
|
|
414
|
-
const
|
|
415
|
-
if (
|
|
568
|
+
const current = activeReasoning.get(chunk.id);
|
|
569
|
+
if (current) {
|
|
570
|
+
const part = editPart({
|
|
571
|
+
parts,
|
|
572
|
+
part: current
|
|
573
|
+
});
|
|
416
574
|
part["state"] = "done";
|
|
417
575
|
setOptional(part, "providerMetadata", chunk.providerMetadata);
|
|
418
576
|
activeReasoning.delete(chunk.id);
|
|
@@ -494,6 +652,35 @@ function projectUIMessageStream(options) {
|
|
|
494
652
|
});
|
|
495
653
|
break;
|
|
496
654
|
}
|
|
655
|
+
case "a2-tool-called": {
|
|
656
|
+
const call = chunk.call;
|
|
657
|
+
const current = findToolPart(parts, call.toolCallId);
|
|
658
|
+
if (current) {
|
|
659
|
+
const existing = editPart({
|
|
660
|
+
parts,
|
|
661
|
+
part: current
|
|
662
|
+
});
|
|
663
|
+
existing["input"] = call.input;
|
|
664
|
+
if (existing["state"] === "input-streaming") existing["state"] = "input-available";
|
|
665
|
+
if (existing["callProviderMetadata"] === void 0) setOptional(existing, "callProviderMetadata", call.providerMetadata);
|
|
666
|
+
if (existing["toolMetadata"] === void 0) setOptional(existing, "toolMetadata", call.toolMetadata);
|
|
667
|
+
setOptional(existing, "providerExecuted", call.providerExecuted);
|
|
668
|
+
setOptional(existing, "title", call.title);
|
|
669
|
+
} else setToolPart({
|
|
670
|
+
parts,
|
|
671
|
+
toolCallId: call.toolCallId,
|
|
672
|
+
toolName: call.toolName,
|
|
673
|
+
dynamic: call.dynamic === true,
|
|
674
|
+
state: "input-available",
|
|
675
|
+
input: call.input,
|
|
676
|
+
providerExecuted: call.providerExecuted,
|
|
677
|
+
providerMetadata: call.providerMetadata,
|
|
678
|
+
toolMetadata: call.toolMetadata,
|
|
679
|
+
title: call.title
|
|
680
|
+
});
|
|
681
|
+
partialTools.delete(call.toolCallId);
|
|
682
|
+
break;
|
|
683
|
+
}
|
|
497
684
|
case "tool-input-available":
|
|
498
685
|
setToolPart({
|
|
499
686
|
parts,
|
|
@@ -529,8 +716,12 @@ function projectUIMessageStream(options) {
|
|
|
529
716
|
break;
|
|
530
717
|
}
|
|
531
718
|
case "tool-approval-request": {
|
|
532
|
-
const
|
|
533
|
-
if (!
|
|
719
|
+
const current = findToolPart(parts, chunk.toolCallId);
|
|
720
|
+
if (!current) break;
|
|
721
|
+
const part = editPart({
|
|
722
|
+
parts,
|
|
723
|
+
part: current
|
|
724
|
+
});
|
|
534
725
|
part["state"] = "approval-requested";
|
|
535
726
|
part["approval"] = {
|
|
536
727
|
id: chunk.approvalId,
|
|
@@ -540,8 +731,12 @@ function projectUIMessageStream(options) {
|
|
|
540
731
|
break;
|
|
541
732
|
}
|
|
542
733
|
case "tool-approval-response": {
|
|
543
|
-
const
|
|
544
|
-
if (!
|
|
734
|
+
const current = findApprovalPart(parts, chunk.approvalId);
|
|
735
|
+
if (!current) break;
|
|
736
|
+
const part = editPart({
|
|
737
|
+
parts,
|
|
738
|
+
part: current
|
|
739
|
+
});
|
|
545
740
|
const approval = isRecord$3(part["approval"]) ? part["approval"] : {};
|
|
546
741
|
part["state"] = "approval-responded";
|
|
547
742
|
part["approval"] = {
|
|
@@ -595,7 +790,10 @@ function projectUIMessageStream(options) {
|
|
|
595
790
|
}
|
|
596
791
|
case "tool-output-denied": {
|
|
597
792
|
const part = findToolPart(parts, chunk.toolCallId);
|
|
598
|
-
if (part)
|
|
793
|
+
if (part) editPart({
|
|
794
|
+
parts,
|
|
795
|
+
part
|
|
796
|
+
})["state"] = "output-denied";
|
|
599
797
|
break;
|
|
600
798
|
}
|
|
601
799
|
case "start-step":
|
|
@@ -619,7 +817,10 @@ function projectUIMessageStream(options) {
|
|
|
619
817
|
default: {
|
|
620
818
|
if (!chunk.type.startsWith("data-") || chunk.transient) break;
|
|
621
819
|
const existing = chunk.id === void 0 ? void 0 : parts.find((part) => part["type"] === chunk.type && part["id"] === chunk.id);
|
|
622
|
-
if (existing)
|
|
820
|
+
if (existing) editPart({
|
|
821
|
+
parts,
|
|
822
|
+
part: existing
|
|
823
|
+
})["data"] = chunk.data;
|
|
623
824
|
else parts.push({
|
|
624
825
|
type: chunk.type,
|
|
625
826
|
...chunk.id === void 0 ? {} : { id: chunk.id },
|
|
@@ -680,6 +881,7 @@ function interruptUIMessage(message, toolError = "Tool execution was interrupted
|
|
|
680
881
|
}
|
|
681
882
|
//#endregion
|
|
682
883
|
//#region src/ai-progress-batches.ts
|
|
884
|
+
const progressOwnedBy = ({ payload, owner, startIndex }) => "startIndex" in payload ? payload.startIndex === startIndex : payload.requestId === owner.requestId && payload.generationId === owner.generationId && payload.responseMessageId === owner.responseMessageId;
|
|
683
885
|
const PAGE_SIZE = 64;
|
|
684
886
|
const appendProgressBatch = ({ batches, batch }) => {
|
|
685
887
|
if (batches.tail.length < PAGE_SIZE) return {
|
|
@@ -738,22 +940,22 @@ const flattenProgressBatches = (batches) => {
|
|
|
738
940
|
//#endregion
|
|
739
941
|
//#region src/ai-message-projection.ts
|
|
740
942
|
const isRecord$2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
943
|
+
const positionOf = (messages, id) => messages.findLastIndex((message) => message.id === id);
|
|
944
|
+
const findMessage = (messages, id) => messages.findLast((message) => message.id === id);
|
|
741
945
|
const upsertMessage = (messages, message) => {
|
|
742
|
-
const index = messages
|
|
946
|
+
const index = positionOf(messages, message.id);
|
|
743
947
|
if (index === -1) return [...messages, message];
|
|
744
|
-
|
|
745
|
-
next[index] = message;
|
|
746
|
-
return next;
|
|
948
|
+
return messages[index] === message ? messages : messages.with(index, message);
|
|
747
949
|
};
|
|
748
950
|
const upsertResponse = (options) => {
|
|
749
951
|
const { messages, message, inputId } = options;
|
|
750
|
-
if (messages
|
|
751
|
-
const inputIndex = messages
|
|
752
|
-
|
|
952
|
+
if (positionOf(messages, message.id) !== -1) return upsertMessage(messages, message);
|
|
953
|
+
const inputIndex = positionOf(messages, inputId);
|
|
954
|
+
const position = inputIndex === -1 ? messages.length : inputIndex + 1;
|
|
753
955
|
return [
|
|
754
|
-
...messages.slice(0,
|
|
956
|
+
...messages.slice(0, position),
|
|
755
957
|
message,
|
|
756
|
-
...messages.slice(
|
|
958
|
+
...messages.slice(position)
|
|
757
959
|
];
|
|
758
960
|
};
|
|
759
961
|
const answerApproval = (messages, response) => messages.map((message) => {
|
|
@@ -791,6 +993,10 @@ const approvalRespondedChunk = (payload) => ({
|
|
|
791
993
|
approved: payload.approved,
|
|
792
994
|
...payload.reason === void 0 ? {} : { reason: payload.reason }
|
|
793
995
|
});
|
|
996
|
+
const toolCalledChunk = (payload) => ({
|
|
997
|
+
type: "a2-tool-called",
|
|
998
|
+
call: payload
|
|
999
|
+
});
|
|
794
1000
|
const toolResultChunk = (payload) => {
|
|
795
1001
|
if (payload.phase === "input") return {
|
|
796
1002
|
type: "tool-input-error",
|
|
@@ -827,30 +1033,43 @@ const toolResultChunk = (payload) => {
|
|
|
827
1033
|
...payload.toolMetadata === void 0 ? {} : { toolMetadata: payload.toolMetadata }
|
|
828
1034
|
};
|
|
829
1035
|
};
|
|
830
|
-
const projectedMessageStream = (projection) => {
|
|
1036
|
+
const projectedMessageStream = ({ projection, current }) => {
|
|
1037
|
+
const base = restoreMessageBase({
|
|
1038
|
+
current,
|
|
1039
|
+
base: projection.base
|
|
1040
|
+
});
|
|
831
1041
|
const projectionEvents = flattenProgressBatches(projection.batches);
|
|
832
|
-
for (const event of projection.toolEvents)
|
|
1042
|
+
for (const event of projection.toolEvents) projectionEvents.push({
|
|
833
1043
|
index: event.index,
|
|
834
|
-
chunks: [toolResultChunk(event.payload)]
|
|
1044
|
+
chunks: [event.type === "ai.tool.called" ? toolCalledChunk(event.payload) : toolResultChunk(event.payload)]
|
|
835
1045
|
});
|
|
836
1046
|
for (const event of projection.approvalEvents) projectionEvents.push({
|
|
837
1047
|
index: event.index,
|
|
838
1048
|
chunks: [event.type === "ai.approval.requested" ? approvalRequestedChunk(event.payload) : approvalRespondedChunk(event.payload)]
|
|
839
1049
|
});
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
...
|
|
843
|
-
|
|
844
|
-
|
|
1050
|
+
const ordered = projectionEvents.toSorted((left, right) => left.index - right.index);
|
|
1051
|
+
return {
|
|
1052
|
+
...projectUIMessageStream({
|
|
1053
|
+
messageId: projection.responseMessageId,
|
|
1054
|
+
...base === void 0 ? {} : { base },
|
|
1055
|
+
chunks: ordered.flatMap((event) => event.chunks)
|
|
1056
|
+
}),
|
|
1057
|
+
throughIndex: ordered.at(-1)?.index ?? 0
|
|
1058
|
+
};
|
|
845
1059
|
};
|
|
846
|
-
const projectedMessage = (
|
|
1060
|
+
const projectedMessage = (options) => projectedMessageStream(options).message;
|
|
847
1061
|
const reduceToolActivity = (tools, event) => {
|
|
848
1062
|
if (event.type === "ai.tool.called") {
|
|
849
1063
|
const payload = event.payload;
|
|
850
|
-
const { providerMetadata, ...called } = payload;
|
|
851
1064
|
const activity = {
|
|
852
|
-
|
|
853
|
-
|
|
1065
|
+
requestId: payload.requestId,
|
|
1066
|
+
messageId: payload.messageId,
|
|
1067
|
+
generationId: payload.generationId,
|
|
1068
|
+
toolCallId: payload.toolCallId,
|
|
1069
|
+
toolName: payload.toolName,
|
|
1070
|
+
...payload.dynamic === void 0 ? {} : { dynamic: payload.dynamic },
|
|
1071
|
+
...payload.providerExecuted === void 0 ? {} : { providerExecuted: payload.providerExecuted },
|
|
1072
|
+
...payload.title === void 0 ? {} : { title: payload.title },
|
|
854
1073
|
status: "running"
|
|
855
1074
|
};
|
|
856
1075
|
return [...tools.filter((candidate) => candidate.generationId !== payload.generationId || candidate.toolCallId !== payload.toolCallId), activity];
|
|
@@ -858,28 +1077,19 @@ const reduceToolActivity = (tools, event) => {
|
|
|
858
1077
|
const payload = event.payload;
|
|
859
1078
|
const existing = tools.find((candidate) => candidate.generationId === payload.generationId && candidate.toolCallId === payload.toolCallId);
|
|
860
1079
|
const toolName = payload.toolName ?? existing?.toolName;
|
|
861
|
-
const input = payload.input === void 0 ? existing?.input : payload.input;
|
|
862
1080
|
const dynamic = payload.dynamic ?? existing?.dynamic;
|
|
863
1081
|
const providerExecuted = payload.providerExecuted ?? existing?.providerExecuted;
|
|
864
|
-
const toolMetadata = payload.toolMetadata ?? existing?.toolMetadata;
|
|
865
|
-
const resultProviderMetadata = payload.providerMetadata ?? existing?.resultProviderMetadata;
|
|
866
1082
|
const activity = {
|
|
867
1083
|
requestId: payload.requestId,
|
|
868
1084
|
messageId: payload.messageId,
|
|
869
1085
|
generationId: payload.generationId,
|
|
870
1086
|
toolCallId: payload.toolCallId,
|
|
871
1087
|
...toolName === void 0 ? {} : { toolName },
|
|
872
|
-
...input === void 0 ? {} : { input },
|
|
873
|
-
...payload.rawInput === void 0 ? {} : { rawInput: payload.rawInput },
|
|
874
|
-
...payload.output === void 0 ? {} : { output: payload.output },
|
|
875
1088
|
...payload.error === void 0 ? {} : { error: payload.error },
|
|
876
1089
|
...payload.preliminary === void 0 ? {} : { preliminary: payload.preliminary },
|
|
877
1090
|
...payload.phase === void 0 ? {} : { phase: payload.phase },
|
|
878
1091
|
...dynamic === void 0 ? {} : { dynamic },
|
|
879
1092
|
...providerExecuted === void 0 ? {} : { providerExecuted },
|
|
880
|
-
...existing?.callProviderMetadata === void 0 ? {} : { callProviderMetadata: existing.callProviderMetadata },
|
|
881
|
-
...resultProviderMetadata === void 0 ? {} : { resultProviderMetadata },
|
|
882
|
-
...toolMetadata === void 0 ? {} : { toolMetadata },
|
|
883
1093
|
...existing?.title === void 0 ? {} : { title: existing.title },
|
|
884
1094
|
status: payload.denied ? "denied" : payload.error ? "failed" : payload.preliminary ? "running" : "completed"
|
|
885
1095
|
};
|
|
@@ -903,8 +1113,11 @@ const advanceProjection = ({ projection, base, chunks, index }) => {
|
|
|
903
1113
|
cursor: projection.cursor.stream,
|
|
904
1114
|
chunks
|
|
905
1115
|
}) : projectedMessageStream({
|
|
906
|
-
|
|
907
|
-
|
|
1116
|
+
projection: {
|
|
1117
|
+
...projection,
|
|
1118
|
+
batches
|
|
1119
|
+
},
|
|
1120
|
+
current: base
|
|
908
1121
|
});
|
|
909
1122
|
return {
|
|
910
1123
|
message: projected.message,
|
|
@@ -918,9 +1131,14 @@ const advanceProjection = ({ projection, base, chunks, index }) => {
|
|
|
918
1131
|
const projectedTools = (projection) => projection.toolEvents.reduce((tools, event) => reduceToolActivity(tools, event), projection.baseTools);
|
|
919
1132
|
const restoreGenerationBase = (state, generationId, responseMessageId, reason) => {
|
|
920
1133
|
const projection = state.activeProjection?.generationId === generationId ? state.activeProjection : null;
|
|
1134
|
+
const restored = restoreMessageBase({
|
|
1135
|
+
current: findMessage(state.messages, responseMessageId),
|
|
1136
|
+
base: projection?.base
|
|
1137
|
+
});
|
|
1138
|
+
const base = restored !== void 0 && reason === "superseded" ? withoutRunningCompactionPart(restored, generationId) : restored;
|
|
921
1139
|
return {
|
|
922
1140
|
...state,
|
|
923
|
-
messages:
|
|
1141
|
+
messages: base === void 0 ? state.messages.filter((message) => message.id !== responseMessageId) : upsertMessage(state.messages, base),
|
|
924
1142
|
tools: projection === null ? state.tools.filter((activity) => activity.generationId !== generationId) : projection.baseTools,
|
|
925
1143
|
pendingApprovals: state.pendingApprovals.filter((approval) => approval.generationId !== generationId),
|
|
926
1144
|
pendingInputs: state.pendingInputs.filter((input) => input.generationId !== generationId),
|
|
@@ -948,15 +1166,126 @@ const interruptGenerationProjection = (state, generationId, responseMessageId, c
|
|
|
948
1166
|
toolEvents: projection.toolEvents.filter((toolEvent) => toolEvent.index <= cutoff),
|
|
949
1167
|
approvalEvents: projection.approvalEvents.filter((approvalEvent) => approvalEvent.index <= cutoff)
|
|
950
1168
|
};
|
|
951
|
-
const shouldProject = retained.
|
|
1169
|
+
const shouldProject = retained.base !== void 0 || retained.batches.length > 0;
|
|
952
1170
|
const restored = restoreGenerationBase(state, generationId, responseMessageId, "interrupted");
|
|
953
1171
|
return {
|
|
954
1172
|
...restored,
|
|
955
|
-
messages: shouldProject ? upsertMessage(state.messages, interruptUIMessage(projectedMessage(
|
|
1173
|
+
messages: shouldProject ? upsertMessage(state.messages, interruptUIMessage(projectedMessage({
|
|
1174
|
+
projection: retained,
|
|
1175
|
+
current: findMessage(state.messages, responseMessageId)
|
|
1176
|
+
}))) : restored.messages,
|
|
956
1177
|
tools: stopGenerationTools(projectedTools(retained), generationId, responseMessageId, "Tool execution was interrupted."),
|
|
957
1178
|
usage: projection.completionIndex === void 0 || projection.completionIndex <= cutoff ? restored.usage : restored.usage.filter((entry) => entry.generationId !== generationId)
|
|
958
1179
|
};
|
|
959
1180
|
};
|
|
1181
|
+
const retainMessageBase = (options) => {
|
|
1182
|
+
const { before, after } = options;
|
|
1183
|
+
const projection = after.activeProjection;
|
|
1184
|
+
if (before.messages === after.messages || !projection?.base || projection.base !== before.activeProjection?.base) return after;
|
|
1185
|
+
const previous = findMessage(before.messages, projection.responseMessageId);
|
|
1186
|
+
const current = findMessage(after.messages, projection.responseMessageId);
|
|
1187
|
+
if (previous !== void 0 && previous === current) return after;
|
|
1188
|
+
const base = previous && current && updateMessageBase({
|
|
1189
|
+
base: projection.base,
|
|
1190
|
+
before: previous,
|
|
1191
|
+
after: current
|
|
1192
|
+
});
|
|
1193
|
+
const { base: _stale, ...unrecoverable } = projection;
|
|
1194
|
+
return {
|
|
1195
|
+
...after,
|
|
1196
|
+
activeProjection: base ? {
|
|
1197
|
+
...unrecoverable,
|
|
1198
|
+
base
|
|
1199
|
+
} : unrecoverable
|
|
1200
|
+
};
|
|
1201
|
+
};
|
|
1202
|
+
const isCompactionPart = (part) => part.type === "data-a2-compaction";
|
|
1203
|
+
const compactionPartOf = (message, generationId) => message.parts.findIndex((part) => isCompactionPart(part) && part.id === generationId);
|
|
1204
|
+
const withoutRunningCompactionPart = (message, generationId) => {
|
|
1205
|
+
const index = compactionPartOf(message, generationId);
|
|
1206
|
+
const part = message.parts[index];
|
|
1207
|
+
return part !== void 0 && isCompactionPart(part) && part.data.status === "running" ? {
|
|
1208
|
+
...message,
|
|
1209
|
+
parts: message.parts.toSpliced(index, 1)
|
|
1210
|
+
} : message;
|
|
1211
|
+
};
|
|
1212
|
+
/**
|
|
1213
|
+
* Compaction runs before its model step streams, so the part lands between
|
|
1214
|
+
* the response's earlier steps and this one. Counting it in the step's base
|
|
1215
|
+
* keeps it through Stop cutoffs, failures, and retries of that step.
|
|
1216
|
+
*/
|
|
1217
|
+
const addCompactionPart = (state, payload) => {
|
|
1218
|
+
const projection = state.activeProjection;
|
|
1219
|
+
if (projection?.generationId !== payload.generationId) return state;
|
|
1220
|
+
const current = findMessage(state.messages, projection.responseMessageId);
|
|
1221
|
+
if (current === void 0 ? projection.base !== void 0 : projection.base?.partCount !== current.parts.length) return state;
|
|
1222
|
+
const inputTokens = payload.inputTokens ?? payload.inputTokenEstimate;
|
|
1223
|
+
const part = {
|
|
1224
|
+
type: "data-a2-compaction",
|
|
1225
|
+
id: payload.generationId,
|
|
1226
|
+
data: {
|
|
1227
|
+
status: "running",
|
|
1228
|
+
...inputTokens === void 0 ? {} : { inputTokens },
|
|
1229
|
+
...payload.thresholdTokens === void 0 ? {} : { thresholdTokens: payload.thresholdTokens }
|
|
1230
|
+
}
|
|
1231
|
+
};
|
|
1232
|
+
const message = current === void 0 ? {
|
|
1233
|
+
id: projection.responseMessageId,
|
|
1234
|
+
role: "assistant",
|
|
1235
|
+
parts: [part]
|
|
1236
|
+
} : {
|
|
1237
|
+
...current,
|
|
1238
|
+
parts: [...current.parts, part]
|
|
1239
|
+
};
|
|
1240
|
+
return {
|
|
1241
|
+
...state,
|
|
1242
|
+
messages: upsertResponse({
|
|
1243
|
+
messages: state.messages,
|
|
1244
|
+
message,
|
|
1245
|
+
inputId: state.activeGeneration?.messageId ?? message.id
|
|
1246
|
+
}),
|
|
1247
|
+
activeProjection: {
|
|
1248
|
+
...projection,
|
|
1249
|
+
cursor: null,
|
|
1250
|
+
base: projection.base === void 0 ? { partCount: 1 } : {
|
|
1251
|
+
...projection.base,
|
|
1252
|
+
partCount: projection.base.partCount + 1
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
};
|
|
1256
|
+
};
|
|
1257
|
+
const settleCompactionPart = (options) => {
|
|
1258
|
+
const { state, generationId, data } = options;
|
|
1259
|
+
const position = state.messages.findLastIndex((message) => compactionPartOf(message, generationId) !== -1);
|
|
1260
|
+
if (position === -1) return state;
|
|
1261
|
+
const message = state.messages[position];
|
|
1262
|
+
const index = compactionPartOf(message, generationId);
|
|
1263
|
+
const part = message.parts[index];
|
|
1264
|
+
return {
|
|
1265
|
+
...state,
|
|
1266
|
+
messages: state.messages.with(position, {
|
|
1267
|
+
...message,
|
|
1268
|
+
parts: message.parts.with(index, {
|
|
1269
|
+
...part,
|
|
1270
|
+
data: {
|
|
1271
|
+
...part.data,
|
|
1272
|
+
...data
|
|
1273
|
+
}
|
|
1274
|
+
})
|
|
1275
|
+
})
|
|
1276
|
+
};
|
|
1277
|
+
};
|
|
1278
|
+
/** A running compaction whose state reverted without completing was abandoned. */
|
|
1279
|
+
const settleAbandonedCompaction = (before, after) => {
|
|
1280
|
+
const running = before.compaction;
|
|
1281
|
+
if (running?.status !== "running" || after.compaction === running || after.compaction?.status === "completed" && after.compaction.generationId === running.generationId) return after;
|
|
1282
|
+
const interrupted = after.status === "closed" || after.pausedGenerationIds?.[running.generationId] === true || after.terminalGenerations?.[running.generationId] === "interrupted";
|
|
1283
|
+
return settleCompactionPart({
|
|
1284
|
+
state: after,
|
|
1285
|
+
generationId: running.generationId,
|
|
1286
|
+
data: { status: interrupted ? "interrupted" : "failed" }
|
|
1287
|
+
});
|
|
1288
|
+
};
|
|
960
1289
|
//#endregion
|
|
961
1290
|
//#region src/ai-client-state.ts
|
|
962
1291
|
const isQueueCommand = (command) => command.action === "send" || command.action === "edit" || command.action === "move" || command.action === "remove" || command.action === "send-now" || command.action === "steer" || command.action === "pause" || command.action === "resume" || command.action === "stop";
|
|
@@ -1076,8 +1405,9 @@ function projectAIClientState(state) {
|
|
|
1076
1405
|
const stop = pending.find(({ command }) => command.action === "stop" && command.turnId === state.active?.turnId)?.command;
|
|
1077
1406
|
if (stop?.action !== "stop") return displayed;
|
|
1078
1407
|
const projection = state.activeProjection;
|
|
1079
|
-
|
|
1080
|
-
|
|
1408
|
+
const stopped = projection === null ? displayed : interruptGenerationProjection(displayed, projection.generationId, projection.responseMessageId, stop.lastSeenIndex ?? Number.POSITIVE_INFINITY) ?? displayed;
|
|
1409
|
+
return settleAbandonedCompaction(displayed, {
|
|
1410
|
+
...stopped,
|
|
1081
1411
|
active: null,
|
|
1082
1412
|
status: paused ? "paused" : "idle",
|
|
1083
1413
|
starting: false,
|
|
@@ -1089,7 +1419,7 @@ function projectAIClientState(state) {
|
|
|
1089
1419
|
pendingApprovals: [],
|
|
1090
1420
|
pendingInputs: [],
|
|
1091
1421
|
error: null
|
|
1092
|
-
};
|
|
1422
|
+
});
|
|
1093
1423
|
}
|
|
1094
1424
|
//#endregion
|
|
1095
1425
|
//#region src/ai-control-state.ts
|
|
@@ -1222,7 +1552,6 @@ const AI_EVENT_ID_PREFIX = "a2.ai:";
|
|
|
1222
1552
|
const aiEventId = async (...parts) => `${AI_EVENT_ID_PREFIX}${await idempotentId(...parts)}`;
|
|
1223
1553
|
//#endregion
|
|
1224
1554
|
//#region src/ai-stored-state.ts
|
|
1225
|
-
const aiStateReducer = Symbol("a2.ai.stateReducer");
|
|
1226
1555
|
const isRecord$1 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1227
1556
|
const hasKeys = (value, { required, optional = [] }) => isRecord$1(value) && required.every((key) => Object.hasOwn(value, key)) && Object.keys(value).every((key) => required.includes(key) || optional.includes(key));
|
|
1228
1557
|
const reference = (value) => {
|
|
@@ -1243,15 +1572,6 @@ const payloadFields = /* @__PURE__ */ new Set([
|
|
|
1243
1572
|
"data"
|
|
1244
1573
|
]);
|
|
1245
1574
|
const keyFor = (value) => value === void 0 ? "undefined" : JSON.stringify(value);
|
|
1246
|
-
const sameValue = (left, right) => {
|
|
1247
|
-
if (Object.is(left, right)) return true;
|
|
1248
|
-
if (typeof left !== "object" || left === null || typeof right !== "object" || right === null) return false;
|
|
1249
|
-
const prototype = Object.getPrototypeOf(left);
|
|
1250
|
-
if (prototype !== Object.getPrototypeOf(right) || prototype !== Object.prototype && prototype !== Array.prototype && prototype !== null) return false;
|
|
1251
|
-
if (Array.isArray(left) && (!Array.isArray(right) || left.length !== right.length)) return false;
|
|
1252
|
-
const keys = Reflect.ownKeys(left);
|
|
1253
|
-
return keys.length === Reflect.ownKeys(right).length && keys.every((key) => Object.hasOwn(right, key) && sameValue(Reflect.get(left, key), Reflect.get(right, key)));
|
|
1254
|
-
};
|
|
1255
1575
|
const restore = (current, undo) => {
|
|
1256
1576
|
if (undo === void 0) return current;
|
|
1257
1577
|
if (!isRecord$1(undo)) throw new TypeError("invalid AI recovery change");
|
|
@@ -1350,22 +1670,18 @@ const storeState = (state) => {
|
|
|
1350
1670
|
packed.set(value, result);
|
|
1351
1671
|
return result;
|
|
1352
1672
|
};
|
|
1353
|
-
const saveProjection = (projection,
|
|
1354
|
-
const {
|
|
1355
|
-
const current = messages.find((message) => message.id === projection.responseMessageId);
|
|
1356
|
-
const message = baseMessage === void 0 ? void 0 : difference(pack(current), pack(baseMessage));
|
|
1673
|
+
const saveProjection = (projection, tools) => {
|
|
1674
|
+
const { baseTools, ...fields } = projection;
|
|
1357
1675
|
const toolPatch = baseTools === void 0 ? void 0 : difference(pack(tools), pack(baseTools));
|
|
1358
1676
|
return {
|
|
1359
1677
|
fields: pack(fields),
|
|
1360
|
-
hasMessage: baseMessage !== void 0,
|
|
1361
|
-
...message === void 0 ? {} : { message },
|
|
1362
1678
|
...toolPatch === void 0 ? {} : { tools: toolPatch }
|
|
1363
1679
|
};
|
|
1364
1680
|
};
|
|
1365
1681
|
const { activeProjection, ...fields } = state;
|
|
1366
|
-
const projection = activeProjection === null ? null : saveProjection(activeProjection, state.
|
|
1682
|
+
const projection = activeProjection === null ? null : saveProjection(activeProjection, state.tools);
|
|
1367
1683
|
return {
|
|
1368
|
-
version:
|
|
1684
|
+
version: 3,
|
|
1369
1685
|
fields: pack(fields),
|
|
1370
1686
|
projection,
|
|
1371
1687
|
values
|
|
@@ -1388,99 +1704,114 @@ const loadState = (stored) => {
|
|
|
1388
1704
|
};
|
|
1389
1705
|
const fields = stored.fields;
|
|
1390
1706
|
const state = unpack(stored.fields);
|
|
1391
|
-
const loadProjection = (saved,
|
|
1707
|
+
const loadProjection = (saved, tools) => {
|
|
1392
1708
|
if (!hasKeys(saved, {
|
|
1393
|
-
required: ["fields"
|
|
1394
|
-
optional: ["
|
|
1395
|
-
}) ||
|
|
1709
|
+
required: ["fields"],
|
|
1710
|
+
optional: ["tools"]
|
|
1711
|
+
}) || !isRecord$1(saved.fields) || "tools" in saved && saved.tools === void 0) throw new TypeError("invalid AI projection recovery");
|
|
1396
1712
|
const projection = unpack(saved.fields);
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
const current =
|
|
1400
|
-
|
|
1713
|
+
if (projection.base !== void 0) {
|
|
1714
|
+
assertMessageBase(projection.base);
|
|
1715
|
+
const current = state.messages.find((message) => message.id === projection.responseMessageId);
|
|
1716
|
+
if (current !== void 0 && restoreMessageBase({
|
|
1717
|
+
current,
|
|
1718
|
+
base: projection.base
|
|
1719
|
+
}) === void 0) throw new TypeError("AI message base does not match its message");
|
|
1401
1720
|
}
|
|
1402
1721
|
if (tools !== void 0) projection.baseTools = unpack(restore(tools, saved.tools));
|
|
1403
1722
|
else if (saved.tools !== void 0) throw new TypeError("missing AI recovery tools");
|
|
1404
1723
|
return projection;
|
|
1405
1724
|
};
|
|
1406
|
-
state.activeProjection = stored.projection === null ? null : loadProjection(stored.projection, fields["
|
|
1725
|
+
state.activeProjection = stored.projection === null ? null : loadProjection(stored.projection, fields["tools"]);
|
|
1407
1726
|
return state;
|
|
1408
1727
|
};
|
|
1409
|
-
const
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1728
|
+
const withAIStorage = (source) => withReducerRuntime({
|
|
1729
|
+
reducer: source,
|
|
1730
|
+
storage: {
|
|
1731
|
+
encode: (state) => storeState(state),
|
|
1732
|
+
decode(value) {
|
|
1733
|
+
if (!hasKeys(value, { required: [
|
|
1734
|
+
"version",
|
|
1735
|
+
"fields",
|
|
1736
|
+
"projection",
|
|
1737
|
+
"values"
|
|
1738
|
+
] }) || value["version"] !== 3 || !Array.isArray(value["values"]) || !isRecord$1(value["fields"]) || value["projection"] !== null && !isRecord$1(value["projection"])) throw new TypeError("invalid AI stored state");
|
|
1739
|
+
const state = value;
|
|
1740
|
+
if (Object.keys(state.values).length !== state.values.length) throw new TypeError("invalid AI payload table");
|
|
1741
|
+
for (const payload of state.values) if (!hasKeys(payload, {
|
|
1742
|
+
required: [],
|
|
1743
|
+
optional: ["value"]
|
|
1744
|
+
})) throw new TypeError("invalid AI payload table");
|
|
1745
|
+
return loadState(state);
|
|
1416
1746
|
}
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
} },
|
|
1474
|
-
fold(state, event) {
|
|
1475
|
-
const current = view(state);
|
|
1476
|
-
const next = source.fold(current, event);
|
|
1477
|
-
if (next === current) return state;
|
|
1478
|
-
return defer(next);
|
|
1479
|
-
}
|
|
1480
|
-
};
|
|
1747
|
+
}
|
|
1748
|
+
});
|
|
1749
|
+
//#endregion
|
|
1750
|
+
//#region src/ai-app-state.ts
|
|
1751
|
+
const aiStateKeys = {
|
|
1752
|
+
inbox: true,
|
|
1753
|
+
pendingQueueCommands: true,
|
|
1754
|
+
active: true,
|
|
1755
|
+
starting: true,
|
|
1756
|
+
receipt: true,
|
|
1757
|
+
pausedGenerationIds: true,
|
|
1758
|
+
session: true,
|
|
1759
|
+
messages: true,
|
|
1760
|
+
status: true,
|
|
1761
|
+
activeGeneration: true,
|
|
1762
|
+
activeRequestId: true,
|
|
1763
|
+
activeRequestReason: true,
|
|
1764
|
+
activeRequestSourceGenerationId: true,
|
|
1765
|
+
activeResponseMessageId: true,
|
|
1766
|
+
activeProjection: true,
|
|
1767
|
+
responseOwners: true,
|
|
1768
|
+
terminalRequestIds: true,
|
|
1769
|
+
terminalGenerations: true,
|
|
1770
|
+
pendingApprovals: true,
|
|
1771
|
+
pendingInputs: true,
|
|
1772
|
+
tools: true,
|
|
1773
|
+
compaction: true,
|
|
1774
|
+
modelMetadata: true,
|
|
1775
|
+
usage: true,
|
|
1776
|
+
error: true
|
|
1777
|
+
};
|
|
1778
|
+
const isAIStateKey = (key) => Object.hasOwn(aiStateKeys, key);
|
|
1779
|
+
const keep = (state, ai) => {
|
|
1780
|
+
const kept = {};
|
|
1781
|
+
for (const [key, value] of Object.entries(state)) if (isAIStateKey(key) === ai) kept[key] = value;
|
|
1782
|
+
return kept;
|
|
1783
|
+
};
|
|
1784
|
+
/** The application part of a merged state: every key `AIState` does not own. */
|
|
1785
|
+
const appSlice = (state) => keep(state, false);
|
|
1786
|
+
/** A merged state with its application part replaced. */
|
|
1787
|
+
const withAppSlice = (state, app) => ({
|
|
1788
|
+
...keep(state, true),
|
|
1789
|
+
...keep(app, false)
|
|
1790
|
+
});
|
|
1791
|
+
const agentReducers = /* @__PURE__ */ new WeakMap();
|
|
1792
|
+
const registerAgentReducer = (reducer, app) => {
|
|
1793
|
+
agentReducers.set(reducer, app ?? null);
|
|
1794
|
+
};
|
|
1795
|
+
const reducerOf = (contract) => typeof contract.reducer === "object" && contract.reducer !== null ? contract.reducer : void 0;
|
|
1796
|
+
const isAgentContract = (contract) => {
|
|
1797
|
+
const reducer = reducerOf(contract);
|
|
1798
|
+
return reducer !== void 0 && agentReducers.has(reducer);
|
|
1799
|
+
};
|
|
1800
|
+
const appReducerOf = (contract) => {
|
|
1801
|
+
const reducer = reducerOf(contract);
|
|
1802
|
+
return reducer === void 0 ? void 0 : agentReducers.get(reducer) ?? void 0;
|
|
1481
1803
|
};
|
|
1482
1804
|
//#endregion
|
|
1483
1805
|
//#region src/ai.ts
|
|
1806
|
+
const reasoningLevels = [
|
|
1807
|
+
"provider-default",
|
|
1808
|
+
"none",
|
|
1809
|
+
"minimal",
|
|
1810
|
+
"low",
|
|
1811
|
+
"medium",
|
|
1812
|
+
"high",
|
|
1813
|
+
"xhigh"
|
|
1814
|
+
];
|
|
1484
1815
|
const issue = (message) => ({ issues: [{ message }] });
|
|
1485
1816
|
const schema = (label, parse) => ({ "~standard": {
|
|
1486
1817
|
version: 1,
|
|
@@ -1530,7 +1861,7 @@ const messagePayloadSchema = (messageSchema) => schema("ai.message.created", (va
|
|
|
1530
1861
|
} };
|
|
1531
1862
|
});
|
|
1532
1863
|
const progressPayloadSchema = schema("ai.generation.progress", (value) => {
|
|
1533
|
-
if (!isRecord(value) || !isJSONCompatible(value) ||
|
|
1864
|
+
if (!isRecord(value) || !isJSONCompatible(value) || typeof value["startIndex"] !== "number" || !optionalIndexField(value, "startIndex") || !Array.isArray(value["chunks"]) || !value["chunks"].every((chunk) => isRecord(chunk) && typeof chunk["type"] === "string")) return issue("invalid ai.generation.progress payload");
|
|
1534
1865
|
return { value };
|
|
1535
1866
|
});
|
|
1536
1867
|
const completedPayloadSchema = schema("ai.generation.completed", (value) => {
|
|
@@ -1633,7 +1964,7 @@ function createEvents(options) {
|
|
|
1633
1964
|
"ai.message.interrupted": jsonObject("ai.message.interrupted", (value) => stringField(value, "messageId") && (stringField(value, "generationId") && value["requestId"] === void 0 || stringField(value, "requestId") && value["generationId"] === void 0) && optionalStringField(value, "reason") && (value["lastSeenIndex"] === void 0 || typeof value["lastSeenIndex"] === "number" && Number.isInteger(value["lastSeenIndex"]) && value["lastSeenIndex"] >= 0)),
|
|
1634
1965
|
"ai.generation.requested": jsonObject("ai.generation.requested", (value) => stringField(value, "messageId") && stringField(value, "responseMessageId") && optionalStringField(value, "sourceGenerationId") && (value["reason"] !== "tool" || stringField(value, "sourceGenerationId")) && (value["reason"] === "message" || value["reason"] === "tool" || value["reason"] === "input" || value["reason"] === "retry" || value["reason"] === "resume")),
|
|
1635
1966
|
"ai.retry.requested": jsonObject("ai.retry.requested", (value) => stringField(value, "messageId") && stringField(value, "responseMessageId") && stringField(value, "retryId")),
|
|
1636
|
-
"ai.generation.started": jsonObject("ai.generation.started", (value) => stringField(value, "requestId") && stringField(value, "messageId") && stringField(value, "generationId") && stringField(value, "responseMessageId") && typeof value["attempt"] === "number" && Number.isInteger(value["attempt"]) && value["attempt"] > 0 && stringField(value, "model") && optionalIndexField(value, "promptThroughIndex")),
|
|
1967
|
+
"ai.generation.started": jsonObject("ai.generation.started", (value) => stringField(value, "requestId") && stringField(value, "messageId") && stringField(value, "generationId") && stringField(value, "responseMessageId") && typeof value["attempt"] === "number" && Number.isInteger(value["attempt"]) && value["attempt"] > 0 && (value["model"] === void 0 || stringField(value, "model")) && optionalIndexField(value, "promptThroughIndex")),
|
|
1637
1968
|
"ai.generation.progress": progressPayloadSchema,
|
|
1638
1969
|
"ai.generation.completed": completedPayloadSchema,
|
|
1639
1970
|
"ai.generation.failed": jsonObject("ai.generation.failed", (value) => stringField(value, "requestId") && stringField(value, "messageId") && stringField(value, "generationId") && stringField(value, "responseMessageId") && stringField(value, "error") && (value["superseded"] === void 0 || typeof value["superseded"] === "boolean") && (value["stepLimit"] === void 0 || typeof value["stepLimit"] === "boolean")),
|
|
@@ -1675,11 +2006,14 @@ const initialState = () => ({
|
|
|
1675
2006
|
usage: [],
|
|
1676
2007
|
error: null
|
|
1677
2008
|
});
|
|
1678
|
-
const projectMessageChunks = (messages, messageId, chunks) =>
|
|
1679
|
-
messageId
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
}
|
|
2009
|
+
const projectMessageChunks = (messages, messageId, chunks) => {
|
|
2010
|
+
const base = findMessage(messages, messageId);
|
|
2011
|
+
return upsertMessage(messages, projectUIMessage({
|
|
2012
|
+
messageId,
|
|
2013
|
+
...base === void 0 ? {} : { base },
|
|
2014
|
+
chunks
|
|
2015
|
+
}));
|
|
2016
|
+
};
|
|
1683
2017
|
const waitingStatus = (state) => {
|
|
1684
2018
|
if (state.pendingApprovals.length > 0 || state.pendingInputs.length > 0) return "waiting";
|
|
1685
2019
|
return state.activeGeneration !== null || state.tools.some((activity) => activity.status === "running") ? "generating" : "idle";
|
|
@@ -1690,7 +2024,10 @@ const isStaleGeneration = (state, messageId, owner) => {
|
|
|
1690
2024
|
return current !== void 0 && (current.generationId !== owner.generationId || current.requestId !== owner.requestId);
|
|
1691
2025
|
};
|
|
1692
2026
|
const projectedResponse = (options) => {
|
|
1693
|
-
const message = projectedMessage(
|
|
2027
|
+
const message = projectedMessage({
|
|
2028
|
+
projection: options.projection,
|
|
2029
|
+
current: findMessage(options.state.messages, options.projection.responseMessageId)
|
|
2030
|
+
});
|
|
1694
2031
|
return options.state.pausedGenerationIds?.[options.projection.generationId] ? pauseUIMessage({
|
|
1695
2032
|
message,
|
|
1696
2033
|
toolCallIds: new Set(options.state.tools.map((tool) => tool.toolCallId))
|
|
@@ -1703,6 +2040,12 @@ const terminalGenerationReason = (state, generationId, requestId) => {
|
|
|
1703
2040
|
};
|
|
1704
2041
|
/** Pure projection of the built-in AI protocol. Unknown extension events are ignored. */
|
|
1705
2042
|
function reduceAIState(state, event) {
|
|
2043
|
+
return settleAbandonedCompaction(state, retainMessageBase({
|
|
2044
|
+
before: state,
|
|
2045
|
+
after: reduceAIEvent(state, event)
|
|
2046
|
+
}));
|
|
2047
|
+
}
|
|
2048
|
+
function reduceAIEvent(state, event) {
|
|
1706
2049
|
if (state.status === "closed") return state;
|
|
1707
2050
|
switch (event.type) {
|
|
1708
2051
|
case "ai.control.requested": {
|
|
@@ -1893,11 +2236,14 @@ function reduceAIState(state, event) {
|
|
|
1893
2236
|
if (currentOwner?.requestId === payload.requestId && currentOwner.attempt >= payload.attempt) return state;
|
|
1894
2237
|
const activeGeneration = state.activeGeneration;
|
|
1895
2238
|
const baseState = activeGeneration !== null && activeGeneration.requestId === payload.requestId && activeGeneration.responseMessageId === payload.responseMessageId && activeGeneration.attempt < payload.attempt && state.activeProjection?.generationId === activeGeneration.generationId ? restoreGenerationBase(state, activeGeneration.generationId, activeGeneration.responseMessageId, "superseded") : state;
|
|
1896
|
-
const baseMessage = baseState.messages
|
|
2239
|
+
const baseMessage = findMessage(baseState.messages, payload.responseMessageId);
|
|
1897
2240
|
return {
|
|
1898
2241
|
...baseState,
|
|
1899
2242
|
status: "generating",
|
|
1900
|
-
activeGeneration:
|
|
2243
|
+
activeGeneration: {
|
|
2244
|
+
...payload,
|
|
2245
|
+
startIndex: event.index
|
|
2246
|
+
},
|
|
1901
2247
|
activeResponseMessageId: null,
|
|
1902
2248
|
responseOwners: {
|
|
1903
2249
|
...baseState.responseOwners,
|
|
@@ -1911,7 +2257,7 @@ function reduceAIState(state, event) {
|
|
|
1911
2257
|
generationId: payload.generationId,
|
|
1912
2258
|
responseMessageId: payload.responseMessageId,
|
|
1913
2259
|
promptThroughIndex: payload.promptThroughIndex ?? event.index - 1,
|
|
1914
|
-
...baseMessage === void 0 ? {} : { baseMessage },
|
|
2260
|
+
...baseMessage === void 0 ? {} : { base: { partCount: baseMessage.parts.length } },
|
|
1915
2261
|
baseCompaction: baseState.compaction,
|
|
1916
2262
|
batches: progressBatches(),
|
|
1917
2263
|
baseTools: baseState.tools,
|
|
@@ -1923,13 +2269,16 @@ function reduceAIState(state, event) {
|
|
|
1923
2269
|
}
|
|
1924
2270
|
case "ai.generation.progress": {
|
|
1925
2271
|
const payload = event.payload;
|
|
1926
|
-
|
|
1927
|
-
if (terminalGenerationReason(state, payload.generationId, payload.requestId) !== void 0) return state;
|
|
2272
|
+
const generation = state.activeGeneration;
|
|
1928
2273
|
const activeProjection = state.activeProjection;
|
|
1929
|
-
if (
|
|
2274
|
+
if (generation === null || !progressOwnedBy({
|
|
2275
|
+
payload,
|
|
2276
|
+
owner: generation,
|
|
2277
|
+
startIndex: generation.startIndex
|
|
2278
|
+
}) || state.pausedGenerationIds?.[generation.generationId] || terminalGenerationReason(state, generation.generationId, generation.requestId) !== void 0 || activeProjection?.generationId !== generation.generationId) return state;
|
|
1930
2279
|
const progress = advanceProjection({
|
|
1931
2280
|
projection: activeProjection,
|
|
1932
|
-
base: state.messages
|
|
2281
|
+
base: findMessage(state.messages, activeProjection.responseMessageId),
|
|
1933
2282
|
chunks: payload.chunks,
|
|
1934
2283
|
index: event.index
|
|
1935
2284
|
});
|
|
@@ -1938,7 +2287,7 @@ function reduceAIState(state, event) {
|
|
|
1938
2287
|
messages: upsertResponse({
|
|
1939
2288
|
messages: state.messages,
|
|
1940
2289
|
message: progress.message,
|
|
1941
|
-
inputId:
|
|
2290
|
+
inputId: generation.messageId
|
|
1942
2291
|
}),
|
|
1943
2292
|
activeProjection: {
|
|
1944
2293
|
...activeProjection,
|
|
@@ -1976,10 +2325,13 @@ function reduceAIState(state, event) {
|
|
|
1976
2325
|
if ((state.activeGeneration?.generationId !== payload.generationId || state.activeGeneration.requestId !== payload.requestId) && !(payload.stepLimit === true && state.activeRequestReason === "tool" && state.responseOwners[payload.responseMessageId]?.requestId === payload.requestId && state.responseOwners[payload.responseMessageId]?.generationId === payload.generationId && state.activeRequestSourceGenerationId === payload.generationId && state.activeResponseMessageId === payload.responseMessageId)) return state;
|
|
1977
2326
|
if (payload.superseded === true) return restoreGenerationBase(state, payload.generationId, payload.responseMessageId, "superseded");
|
|
1978
2327
|
const projection = state.activeProjection?.generationId === payload.generationId ? state.activeProjection : null;
|
|
1979
|
-
const shouldProject = projection !== null && (projection.
|
|
2328
|
+
const shouldProject = projection !== null && (projection.base !== void 0 || projection.batches.length > 0);
|
|
1980
2329
|
return {
|
|
1981
2330
|
...state,
|
|
1982
|
-
messages: shouldProject ? upsertMessage(state.messages, interruptUIMessage(projectedMessage(
|
|
2331
|
+
messages: shouldProject ? upsertMessage(state.messages, interruptUIMessage(projectedMessage({
|
|
2332
|
+
projection,
|
|
2333
|
+
current: findMessage(state.messages, projection.responseMessageId)
|
|
2334
|
+
}), `Generation failed before tool completion: ${payload.error}`)) : state.messages,
|
|
1983
2335
|
status: "failed",
|
|
1984
2336
|
activeGeneration: null,
|
|
1985
2337
|
activeResponseMessageId: null,
|
|
@@ -2098,6 +2450,7 @@ function reduceAIState(state, event) {
|
|
|
2098
2450
|
if (projection?.generationId !== payload.generationId) {
|
|
2099
2451
|
const next = {
|
|
2100
2452
|
...state,
|
|
2453
|
+
messages: projectMessageChunks(state.messages, payload.messageId, [toolCalledChunk(payload)]),
|
|
2101
2454
|
tools: reduceToolActivity(state.tools, {
|
|
2102
2455
|
type: "ai.tool.called",
|
|
2103
2456
|
payload
|
|
@@ -2110,15 +2463,49 @@ function reduceAIState(state, event) {
|
|
|
2110
2463
|
}
|
|
2111
2464
|
const activeProjection = {
|
|
2112
2465
|
...projection,
|
|
2466
|
+
cursor: null,
|
|
2113
2467
|
toolEvents: [...projection.toolEvents, {
|
|
2114
2468
|
index: event.index,
|
|
2115
2469
|
type: "ai.tool.called",
|
|
2116
2470
|
payload
|
|
2117
2471
|
}]
|
|
2118
2472
|
};
|
|
2473
|
+
const base = findMessage(state.messages, payload.messageId);
|
|
2474
|
+
const paused = state.pausedGenerationIds?.[payload.generationId];
|
|
2475
|
+
const cursor = projection.cursor;
|
|
2476
|
+
const projected = base && cursor && !paused && event.index > cursor.throughIndex ? {
|
|
2477
|
+
...hasToolCall({
|
|
2478
|
+
message: base,
|
|
2479
|
+
call: payload
|
|
2480
|
+
}) ? {
|
|
2481
|
+
message: base,
|
|
2482
|
+
cursor: cursor.stream
|
|
2483
|
+
} : projectUIMessageStream({
|
|
2484
|
+
messageId: payload.messageId,
|
|
2485
|
+
base,
|
|
2486
|
+
cursor: cursor.stream,
|
|
2487
|
+
chunks: [toolCalledChunk(payload)]
|
|
2488
|
+
}),
|
|
2489
|
+
throughIndex: event.index
|
|
2490
|
+
} : projectedMessageStream({
|
|
2491
|
+
projection: activeProjection,
|
|
2492
|
+
current: base
|
|
2493
|
+
});
|
|
2494
|
+
activeProjection.cursor = paused ? null : {
|
|
2495
|
+
throughIndex: projected.throughIndex,
|
|
2496
|
+
stream: projected.cursor
|
|
2497
|
+
};
|
|
2119
2498
|
const next = {
|
|
2120
2499
|
...state,
|
|
2121
2500
|
activeProjection,
|
|
2501
|
+
messages: upsertResponse({
|
|
2502
|
+
messages: state.messages,
|
|
2503
|
+
message: paused ? projectedResponse({
|
|
2504
|
+
state,
|
|
2505
|
+
projection: activeProjection
|
|
2506
|
+
}) : projected.message,
|
|
2507
|
+
inputId: state.activeGeneration?.messageId ?? state.active?.input.id ?? payload.messageId
|
|
2508
|
+
}),
|
|
2122
2509
|
tools: projectedTools(activeProjection)
|
|
2123
2510
|
};
|
|
2124
2511
|
return {
|
|
@@ -2261,30 +2648,41 @@ function reduceAIState(state, event) {
|
|
|
2261
2648
|
case "ai.compaction.requested": {
|
|
2262
2649
|
const payload = event.payload;
|
|
2263
2650
|
if (state.activeGeneration?.generationId !== payload.generationId) return state;
|
|
2264
|
-
return {
|
|
2651
|
+
return addCompactionPart({
|
|
2265
2652
|
...state,
|
|
2266
2653
|
compaction: {
|
|
2267
2654
|
status: "running",
|
|
2268
2655
|
...payload
|
|
2269
2656
|
}
|
|
2270
|
-
};
|
|
2657
|
+
}, payload);
|
|
2271
2658
|
}
|
|
2272
2659
|
case "ai.compaction.completed": {
|
|
2273
2660
|
const payload = event.payload;
|
|
2274
2661
|
if (state.activeGeneration?.generationId !== payload.generationId || state.compaction?.status !== "running" || state.compaction.generationId !== payload.generationId) return state;
|
|
2662
|
+
const { messages: _messages, retainedMessageIds: _retained, ...summary } = payload;
|
|
2275
2663
|
const compaction = {
|
|
2276
2664
|
status: "completed",
|
|
2277
|
-
...
|
|
2665
|
+
...summary,
|
|
2278
2666
|
throughIndex: payload.throughIndex ?? state.activeProjection.promptThroughIndex
|
|
2279
2667
|
};
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2668
|
+
const projection = state.activeProjection;
|
|
2669
|
+
return settleCompactionPart({
|
|
2670
|
+
state: {
|
|
2671
|
+
...state,
|
|
2672
|
+
compaction,
|
|
2673
|
+
activeProjection: projection && {
|
|
2674
|
+
...projection,
|
|
2675
|
+
baseCompaction: compaction,
|
|
2676
|
+
...projection.base === void 0 ? {} : { base: { ...projection.base } }
|
|
2677
|
+
}
|
|
2678
|
+
},
|
|
2679
|
+
generationId: payload.generationId,
|
|
2680
|
+
data: {
|
|
2681
|
+
status: "completed",
|
|
2682
|
+
...summary.summary === void 0 ? {} : { summary: summary.summary },
|
|
2683
|
+
...summary.usage === void 0 ? {} : { usage: summary.usage }
|
|
2286
2684
|
}
|
|
2287
|
-
};
|
|
2685
|
+
});
|
|
2288
2686
|
}
|
|
2289
2687
|
default: return state;
|
|
2290
2688
|
}
|
|
@@ -2295,18 +2693,6 @@ function deriveUIMessages(history) {
|
|
|
2295
2693
|
for (const event of history) state = reduceAIState(state, event);
|
|
2296
2694
|
return state.messages;
|
|
2297
2695
|
}
|
|
2298
|
-
/** Build the standard AI state projection for any contract containing the protocol. */
|
|
2299
|
-
function createReducer(options) {
|
|
2300
|
-
const reducer = options.contract.reducer({
|
|
2301
|
-
name: options.name ?? "a2.ai.state.v22",
|
|
2302
|
-
initialState: initialState(),
|
|
2303
|
-
...options.stateSchema === void 0 ? {} : { stateSchema: options.stateSchema }
|
|
2304
|
-
}).fold(options.fold ?? ((state, event) => reduceAIState(state, event)));
|
|
2305
|
-
return storedAIReducer({
|
|
2306
|
-
...reducer,
|
|
2307
|
-
[clientStateProjection]: projectAIClientState
|
|
2308
|
-
});
|
|
2309
|
-
}
|
|
2310
2696
|
const commandInput = (payload) => [{
|
|
2311
2697
|
type: "ai.control.requested",
|
|
2312
2698
|
payload
|
|
@@ -2407,45 +2793,64 @@ const inputs = {
|
|
|
2407
2793
|
* Read the durable handler context ambient to the current AI tool
|
|
2408
2794
|
* execution. A2 runs each local tool's `execute` inside this scope, so
|
|
2409
2795
|
* plain AI SDK `tool()` definitions reach their `event`, `attempt`,
|
|
2410
|
-
* `session`, and `signal` without an A2-specific wrapper.
|
|
2411
|
-
* contract
|
|
2412
|
-
* the executing
|
|
2796
|
+
* `session`, and `signal` without an A2-specific wrapper. Pass the
|
|
2797
|
+
* agent's contract to type application events; it is verified against
|
|
2798
|
+
* the executing agent.
|
|
2413
2799
|
*/
|
|
2414
|
-
function handlerContext(
|
|
2415
|
-
const contract = "contract" in agentOrContract ? agentOrContract.contract : agentOrContract;
|
|
2800
|
+
function handlerContext(contract) {
|
|
2416
2801
|
const scope = ambientToolScopeStorage()?.getStore();
|
|
2417
|
-
if (scope === void 0) throw new TypeError(
|
|
2418
|
-
if (scope.contract !== void 0 && scope.contract.name !== contract.name) throw new TypeError(`handlerContext('${contract.name}') was called during a tool execution for agent '${scope.contract.name}'`);
|
|
2802
|
+
if (scope === void 0) throw new TypeError("handlerContext() requires an ambient A2 tool execution: call it inside a local tool's execute, or wrap direct tool tests with runWithHandlerContext");
|
|
2803
|
+
if (contract !== void 0 && scope.contract !== void 0 && scope.contract.name !== contract.name) throw new TypeError(`handlerContext('${contract.name}') was called during a tool execution for agent '${scope.contract.name}'`);
|
|
2419
2804
|
return scope.context;
|
|
2420
2805
|
}
|
|
2806
|
+
/** The built-in AI reducer's name, and so its checkpoint identity. */
|
|
2807
|
+
const AI_STATE_REDUCER = "a2.ai.state.v26";
|
|
2421
2808
|
/**
|
|
2422
|
-
*
|
|
2423
|
-
* reducer
|
|
2809
|
+
* The built-in AI protocol plus application events, as a core contract whose
|
|
2810
|
+
* reducer folds `AIState`. Isomorphic: share it when a client needs
|
|
2811
|
+
* application events or extended state; otherwise `agent({ name })` on the
|
|
2812
|
+
* server builds one and clients use the built-in protocol.
|
|
2424
2813
|
*/
|
|
2425
|
-
function
|
|
2814
|
+
function agentContract(options) {
|
|
2426
2815
|
const builtIns = createEvents(options.messageSchema === void 0 ? void 0 : { messageSchema: options.messageSchema });
|
|
2427
2816
|
const extensions = options.events ?? {};
|
|
2428
2817
|
for (const key of Object.keys(extensions)) if (Object.hasOwn(builtIns, key)) throw new TypeError(`agent event '${key}' conflicts with a built-in event`);
|
|
2429
|
-
const
|
|
2818
|
+
const vocabulary = contract({
|
|
2430
2819
|
name: options.name,
|
|
2431
2820
|
events: {
|
|
2432
2821
|
...builtIns,
|
|
2433
2822
|
...extensions
|
|
2434
2823
|
}
|
|
2435
2824
|
});
|
|
2436
|
-
const
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
...
|
|
2444
|
-
|
|
2445
|
-
}
|
|
2446
|
-
}
|
|
2825
|
+
const app = options.reducer;
|
|
2826
|
+
const aiState = initialState();
|
|
2827
|
+
for (const key of Object.keys(app?.initialState ?? {})) if (isAIStateKey(key)) throw new TypeError(`agent state '${key}' conflicts with AIState`);
|
|
2828
|
+
const reducer$1 = reducer({
|
|
2829
|
+
contract: vocabulary,
|
|
2830
|
+
name: app === void 0 ? AI_STATE_REDUCER : `${app.name}+${AI_STATE_REDUCER}`,
|
|
2831
|
+
initialState: {
|
|
2832
|
+
...aiState,
|
|
2833
|
+
...app?.initialState
|
|
2834
|
+
}
|
|
2835
|
+
}).fold((state, event) => {
|
|
2836
|
+
const next = reduceAIState(state, event);
|
|
2837
|
+
if (app === void 0) return next;
|
|
2838
|
+
const before = appSlice(state);
|
|
2839
|
+
const after = app.fold(before, event);
|
|
2840
|
+
return after === before ? next : withAppSlice(next, after);
|
|
2841
|
+
});
|
|
2842
|
+
const shared = contract({
|
|
2843
|
+
name: options.name,
|
|
2844
|
+
events: vocabulary.events,
|
|
2845
|
+
reducer: withAIStorage(withReducerRuntime({
|
|
2846
|
+
reducer: reducer$1,
|
|
2847
|
+
project: projectAIClientState
|
|
2848
|
+
}))
|
|
2849
|
+
});
|
|
2850
|
+
registerAgentReducer(shared.reducer, app);
|
|
2851
|
+
return shared;
|
|
2447
2852
|
}
|
|
2448
2853
|
//#endregion
|
|
2449
|
-
export { interruptUIMessage as C, progressBatches as
|
|
2854
|
+
export { interruptUIMessage as A, reduceToolActivity as C, flattenProgressBatches as D, upsertResponse as E, assertMessageBase as M, restoreMessageBase as N, progressBatches as O, projectedMessage as S, upsertMessage as T, applyControlChanges as _, events as a, findMessage as b, reasoningLevels as c, appSlice as d, isAgentContract as f, initialControlState as g, aiEventId as h, deriveUIMessages as i, pauseUIMessage as j, progressOwnedBy as k, reduceAIState as l, AI_EVENT_ID_PREFIX as m, agentContract as n, handlerContext as o, withAIStorage as p, createEvents as r, inputs as s, AI_STATE_REDUCER as t, appReducerOf as u, controlCommit as v, retainMessageBase as w, isCompactionPart as x, advanceProjection as y };
|
|
2450
2855
|
|
|
2451
|
-
//# sourceMappingURL=ai-
|
|
2856
|
+
//# sourceMappingURL=ai-UrWfKeuv.js.map
|