@astralbeam/sdk 0.16.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -4
- package/dist/{api-DzeMhfHU.js → api-B3UxSTtl.js} +200 -10
- package/dist/api.d.ts +2 -2
- package/dist/api.js +1 -2
- package/dist/auth-lifecycle-B0BXyDr7.js +25 -0
- package/dist/badge-B9WuChHI.js +1 -0
- package/dist/client.d.ts +57 -8
- package/dist/client.js +1 -1
- package/dist/constants-C-Yp0Vhg.js +1 -0
- package/dist/{core-D84VNYWJ.js → core-CLWlvgYl.js} +1534 -129
- package/dist/core.d.ts +2 -2
- package/dist/core.js +1 -2
- package/dist/css-BGIxQoYs.js +1 -0
- package/dist/css-DgaLhXQH.js +1 -0
- package/dist/{debug-qLts7gEt.js → debug-DLDY8CZb.js} +1 -1
- package/dist/diff-woXpYk--.js +1 -0
- package/dist/github-dark-C-LZuMrd.js +1 -0
- package/dist/github-light-EUqPIrTm.js +1 -0
- package/dist/highlighter-Bd_oZUcA.js +152 -0
- package/dist/html-B3xvRgDO.js +1 -0
- package/dist/{index-CM3pzsKR.d.ts → index-DDfmeUeU.d.ts} +209 -86
- package/dist/{index-CH3RVjha.d.ts → index-DFxtXIXy.d.ts} +232 -20
- package/dist/item-a9y_9nk7.js +1 -0
- package/dist/javascript-BzbQS41l.js +1 -0
- package/dist/javascript-CpIGwZ_Y.js +1 -0
- package/dist/json-qhed-kSA.js +1 -0
- package/dist/jsx-Bz0zcwM4.js +1 -0
- package/dist/listings-DzxJtGCD.js +1 -0
- package/dist/markdown-BYOwaDjH.js +1 -0
- package/dist/mcp-servers-ESbOt00F.js +1 -0
- package/dist/python-gzcpVVnB.js +1 -0
- package/dist/react.d.ts +23 -16
- package/dist/react.js +46 -8
- package/dist/server.d.ts +19 -25
- package/dist/server.js +196 -349
- package/dist/shellscript-CLZ0U2zV.js +1 -0
- package/dist/sql-CEbI0hMM.js +1 -0
- package/dist/styles.generated-D4k7izMB.js +80 -0
- package/dist/tsx-udAQXfEw.js +1 -0
- package/dist/typescript-bsJCZSQ-.js +1 -0
- package/dist/validate-BOw-BAyv.js +140 -0
- package/dist/widget-DGmCPqzk.js +24 -0
- package/dist/yaml-rwi0_p6S.js +1 -0
- package/package.json +20 -17
- package/dist/constants-enyqxaJi.js +0 -1
- package/dist/listings-dAoOEUGK.js +0 -1
- package/dist/rolldown-runtime-Bh1tDfsg.js +0 -1
- package/dist/styles.generated-Ucyw8D9G.js +0 -98
- package/dist/type_checks-C-WTHaWs.js +0 -117
- package/dist/widget-h5LX5aq8.js +0 -11
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { A as getCurrentUser, At as personalMcpTestConnection, Bt as astralBeamChatFetch, C as getChatConfig, Ct as personalMcpAuthorizeConnection, Dt as personalMcpDisconnectConnection, Et as personalMcpCreateConnection, Ht as resolveApiUrl, It as updateChatThread, Ot as personalMcpGetCatalog, S as getChatAttachment, Tt as personalMcpCompleteAuthorization, Vt as isAstralBeamApiError, at as getResolveChatToolResultUrl, gt as listChatMessages, kt as personalMcpSetHeaders, ot as getRunChatUrl, v as createChatThread, vt as listChatThreads, w as getChatFile, wt as personalMcpBindBrowser, x as deleteChatThread, zt as uploadChatFile } from "./api-B3UxSTtl.js";
|
|
2
|
+
import { _ as strictDecoder, i as isObject, l as decode, p as JWTInvalid } from "./validate-BOw-BAyv.js";
|
|
3
3
|
//#region \0rolldown/runtime.js
|
|
4
|
-
var
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod, mod.exports), cb = null), mod.exports);
|
|
6
|
+
var __exportAll = (all, no_symbols) => {
|
|
7
|
+
let target = {};
|
|
8
|
+
for (var name in all) __defProp(target, name, {
|
|
9
|
+
get: all[name],
|
|
10
|
+
enumerable: true
|
|
11
|
+
});
|
|
12
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
13
|
+
return target;
|
|
14
|
+
};
|
|
5
15
|
//#endregion
|
|
6
|
-
//#region node_modules/.
|
|
16
|
+
//#region ../node_modules/.bun/jose@6.2.12/node_modules/jose/dist/webapi/util/decode_jwt.js
|
|
7
17
|
function decodeJwt(jwt) {
|
|
8
|
-
if (typeof jwt
|
|
18
|
+
if (typeof jwt != "string") throw new JWTInvalid("JWTs must use Compact JWS serialization, JWT must be a string");
|
|
9
19
|
const { 1: payload, length } = jwt.split(".");
|
|
10
20
|
if (length === 5) throw new JWTInvalid("Only JWTs using Compact JWS serialization can be decoded");
|
|
11
21
|
if (length !== 3) throw new JWTInvalid("Invalid JWT");
|
|
@@ -26,7 +36,7 @@ function decodeJwt(jwt) {
|
|
|
26
36
|
return result;
|
|
27
37
|
}
|
|
28
38
|
//#endregion
|
|
29
|
-
//#region node_modules/.
|
|
39
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@0.39.2+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/response-stream.js
|
|
30
40
|
var UnsupportedResponseStreamError = class extends Error {
|
|
31
41
|
missingFeature;
|
|
32
42
|
constructor(missingFeature) {
|
|
@@ -48,14 +58,14 @@ function createResponseStreamTextDecoder() {
|
|
|
48
58
|
return new globalThis.TextDecoder();
|
|
49
59
|
}
|
|
50
60
|
//#endregion
|
|
51
|
-
//#region node_modules/.
|
|
61
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@0.39.2+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/sse-utils.js
|
|
52
62
|
function parseSseDataLine(line) {
|
|
53
63
|
if (!line.startsWith("data:")) return line;
|
|
54
64
|
const data = line.slice(5);
|
|
55
65
|
return data.startsWith(" ") ? data.slice(1) : data;
|
|
56
66
|
}
|
|
57
67
|
//#endregion
|
|
58
|
-
//#region node_modules/.
|
|
68
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@0.39.2+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/message-date-normalizer.js
|
|
59
69
|
function validDate(value) {
|
|
60
70
|
if (value instanceof Date) return Number.isNaN(value.getTime()) ? void 0 : value;
|
|
61
71
|
if (typeof value !== "string") return void 0;
|
|
@@ -87,7 +97,7 @@ function normalizeMessagesDates(messages) {
|
|
|
87
97
|
return messages.map(normalizeMessageDates);
|
|
88
98
|
}
|
|
89
99
|
//#endregion
|
|
90
|
-
//#region node_modules/.
|
|
100
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/ag-ui-usage.js
|
|
91
101
|
function definedDetails(value) {
|
|
92
102
|
return Object.keys(value).length > 0 ? value : void 0;
|
|
93
103
|
}
|
|
@@ -132,7 +142,7 @@ function fromSpecTokenUsage(usage, leftover) {
|
|
|
132
142
|
};
|
|
133
143
|
}
|
|
134
144
|
//#endregion
|
|
135
|
-
//#region node_modules/.
|
|
145
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/merge-metadata.js
|
|
136
146
|
function isPlainRecord$1(value) {
|
|
137
147
|
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
138
148
|
}
|
|
@@ -172,7 +182,7 @@ function withTanstackMetadata(value, tanstack) {
|
|
|
172
182
|
};
|
|
173
183
|
}
|
|
174
184
|
//#endregion
|
|
175
|
-
//#region node_modules/.
|
|
185
|
+
//#region ../node_modules/.bun/@ag-ui+core@1.0.0+969a6d035afea0f4/node_modules/@ag-ui/core/dist/version-CTNE2I0_.mjs
|
|
176
186
|
/**
|
|
177
187
|
* The discriminator carried by every event.
|
|
178
188
|
*/
|
|
@@ -211,7 +221,7 @@ let EventType = /* @__PURE__ */ function(EventType) {
|
|
|
211
221
|
return EventType;
|
|
212
222
|
}({});
|
|
213
223
|
//#endregion
|
|
214
|
-
//#region node_modules/.
|
|
224
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/reasoning-encrypted-value.js
|
|
215
225
|
/**
|
|
216
226
|
* Id prefix for the reasoning message of a redacted thinking block (Anthropic
|
|
217
227
|
* `redacted_thinking`). AG-UI's `encryptedValue` does not say what kind of
|
|
@@ -223,7 +233,7 @@ function isRedactedThinkingId(id) {
|
|
|
223
233
|
return typeof id === "string" && id.startsWith("redacted_thinking-");
|
|
224
234
|
}
|
|
225
235
|
//#endregion
|
|
226
|
-
//#region node_modules/.
|
|
236
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/interrupt-serialization.js
|
|
227
237
|
var SHA256_K = new Uint32Array([
|
|
228
238
|
1116352408,
|
|
229
239
|
1899447441,
|
|
@@ -398,7 +408,7 @@ function cloneAndDeepFreezeJson(value) {
|
|
|
398
408
|
return clone;
|
|
399
409
|
}
|
|
400
410
|
//#endregion
|
|
401
|
-
//#region node_modules/.
|
|
411
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/interrupts.js
|
|
402
412
|
function canonicalizeInterruptResolutions(resolutions) {
|
|
403
413
|
const frozen = cloneAndDeepFreezeJson([...resolutions].sort((left, right) => left.interruptId.localeCompare(right.interruptId)));
|
|
404
414
|
const canonicalResolutions = canonicalInterruptJson(frozen);
|
|
@@ -409,7 +419,7 @@ function canonicalizeInterruptResolutions(resolutions) {
|
|
|
409
419
|
});
|
|
410
420
|
}
|
|
411
421
|
//#endregion
|
|
412
|
-
//#region node_modules/.
|
|
422
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/activities/chat/tools/schema-converter.js
|
|
413
423
|
/**
|
|
414
424
|
* Build a JSONSchema object from any plain key/value source. The `JSONSchema`
|
|
415
425
|
* interface's `[key: string]: any` index signature makes every property
|
|
@@ -677,7 +687,7 @@ async function validateWithStandardSchema(schema, data) {
|
|
|
677
687
|
};
|
|
678
688
|
}
|
|
679
689
|
//#endregion
|
|
680
|
-
//#region node_modules/.
|
|
690
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/activities/chat/tools/approval-schema.js
|
|
681
691
|
var jsonSchemaKeywords = /* @__PURE__ */ new Set([
|
|
682
692
|
"$schema",
|
|
683
693
|
"$id",
|
|
@@ -753,13 +763,15 @@ function normalizeApprovalSchema(approvalSchema, inputSchema) {
|
|
|
753
763
|
const normalizedInput = inputSchema === void 0 ? null : schemaToWire(inputSchema);
|
|
754
764
|
let approve = null;
|
|
755
765
|
let reject = null;
|
|
756
|
-
if (approvalSchema !== void 0)
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
766
|
+
if (approvalSchema !== void 0) {
|
|
767
|
+
if (isStandardSchema(approvalSchema) || isRawJsonSchema(approvalSchema)) {
|
|
768
|
+
approve = schemaToWire(approvalSchema);
|
|
769
|
+
reject = approve;
|
|
770
|
+
} else if (isApprovalBranchMap(approvalSchema)) {
|
|
771
|
+
approve = approvalSchema.approve === void 0 ? null : schemaToWire(approvalSchema.approve);
|
|
772
|
+
reject = approvalSchema.reject === void 0 ? null : schemaToWire(approvalSchema.reject);
|
|
773
|
+
} else throw new TypeError("approvalSchema must be a SchemaInput or a nonempty map containing approve or reject.");
|
|
774
|
+
}
|
|
763
775
|
const responseSchema = { oneOf: [decisionEnvelope({
|
|
764
776
|
approved: true,
|
|
765
777
|
payload: approve,
|
|
@@ -789,7 +801,7 @@ function hashSchemaInput(schema) {
|
|
|
789
801
|
return digestInterruptJson(canonicalInterruptJson(schemaToWire(schema).jsonSchema ?? { standardValidator: "unserialized" }));
|
|
790
802
|
}
|
|
791
803
|
//#endregion
|
|
792
|
-
//#region node_modules/.
|
|
804
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/interrupt-resume.js
|
|
793
805
|
/**
|
|
794
806
|
* The `Interrupt.metadata` key under which this package's resume binding
|
|
795
807
|
* travels.
|
|
@@ -910,7 +922,7 @@ function readInterruptBinding(descriptor) {
|
|
|
910
922
|
};
|
|
911
923
|
}
|
|
912
924
|
//#endregion
|
|
913
|
-
//#region node_modules/.
|
|
925
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/interrupt-definition.js
|
|
914
926
|
var INTERRUPT_PAYLOAD_METADATA_KEY = "tanstack:interruptPayload";
|
|
915
927
|
function schemaJson(schema, name) {
|
|
916
928
|
if (!isStandardJSONSchema(schema)) throw new TypeError(`${name} must be a Standard Schema with a JSON Schema converter.`);
|
|
@@ -935,7 +947,7 @@ function hashInterruptDefinitionSchema(schema) {
|
|
|
935
947
|
return digestInterruptJson(schemaJson(schema, "Interrupt schema").canonicalJson);
|
|
936
948
|
}
|
|
937
949
|
//#endregion
|
|
938
|
-
//#region node_modules/.
|
|
950
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/generic-interrupt-continuation.js
|
|
939
951
|
/**
|
|
940
952
|
* `ResumeEntry.metadata` key for a first-party generic request.
|
|
941
953
|
*
|
|
@@ -974,7 +986,7 @@ function genericInterruptContinuationFromDescriptor(interrupt) {
|
|
|
974
986
|
};
|
|
975
987
|
}
|
|
976
988
|
//#endregion
|
|
977
|
-
//#region node_modules/.
|
|
989
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/provider-executed.js
|
|
978
990
|
/**
|
|
979
991
|
* Narrow a tool call's opaque `metadata` to the provider-executed convention.
|
|
980
992
|
* Returns the typed metadata when the call is provider-executed, else `null`.
|
|
@@ -1004,7 +1016,7 @@ function isAssistantSegmentOf(id, parentId) {
|
|
|
1004
1016
|
return id?.startsWith(`${parentId}-segment-`) === true;
|
|
1005
1017
|
}
|
|
1006
1018
|
//#endregion
|
|
1007
|
-
//#region node_modules/.
|
|
1019
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/tool-result.js
|
|
1008
1020
|
var CONTENT_PART_TYPES = /* @__PURE__ */ new Set([
|
|
1009
1021
|
"text",
|
|
1010
1022
|
"image",
|
|
@@ -1065,7 +1077,7 @@ function normalizeToolResult(result) {
|
|
|
1065
1077
|
return JSON.stringify(result);
|
|
1066
1078
|
}
|
|
1067
1079
|
//#endregion
|
|
1068
|
-
//#region node_modules/.
|
|
1080
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/subagent-wire.js
|
|
1069
1081
|
function isRecord$2(value) {
|
|
1070
1082
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1071
1083
|
}
|
|
@@ -1169,7 +1181,7 @@ function splitSubagentWire(messages) {
|
|
|
1169
1181
|
};
|
|
1170
1182
|
}
|
|
1171
1183
|
//#endregion
|
|
1172
|
-
//#region node_modules/.
|
|
1184
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/activities/chat/messages.js
|
|
1173
1185
|
function isRecord$1(value) {
|
|
1174
1186
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1175
1187
|
}
|
|
@@ -1362,6 +1374,7 @@ function assistantMetadata(uiMessage) {
|
|
|
1362
1374
|
*/
|
|
1363
1375
|
function uiMessageToModelMessages(uiMessage) {
|
|
1364
1376
|
if (uiMessage.role === "system") return [];
|
|
1377
|
+
if (uiMessage.role === "activity") return [];
|
|
1365
1378
|
if (uiMessage.role !== "assistant") return [buildUserOrToolMessage(uiMessage)];
|
|
1366
1379
|
return buildAssistantMessages(uiMessage);
|
|
1367
1380
|
}
|
|
@@ -1491,6 +1504,7 @@ function buildAssistantMessages(uiMessage) {
|
|
|
1491
1504
|
}
|
|
1492
1505
|
break;
|
|
1493
1506
|
case "ui-resource": break;
|
|
1507
|
+
case "activity": break;
|
|
1494
1508
|
case "subagent": {
|
|
1495
1509
|
const block = part.subagent.parentToolCallId === void 0 ? subagentHistoryText(part) : "";
|
|
1496
1510
|
if (block !== "") {
|
|
@@ -1707,6 +1721,15 @@ function aguiSnapshotMessageToUIMessage(message) {
|
|
|
1707
1721
|
}] : []
|
|
1708
1722
|
});
|
|
1709
1723
|
}
|
|
1724
|
+
case "activity": return applySnapshotMetadata(message, {
|
|
1725
|
+
id,
|
|
1726
|
+
role: "activity",
|
|
1727
|
+
parts: [{
|
|
1728
|
+
type: "activity",
|
|
1729
|
+
activityType: message.activityType,
|
|
1730
|
+
content: structuredClone(message.content)
|
|
1731
|
+
}]
|
|
1732
|
+
});
|
|
1710
1733
|
default: return applySnapshotMetadata(message, {
|
|
1711
1734
|
id,
|
|
1712
1735
|
role: "assistant",
|
|
@@ -1752,15 +1775,23 @@ function applySnapshotMetadata(source, ui) {
|
|
|
1752
1775
|
}
|
|
1753
1776
|
function snapshotStructuredOutput(value) {
|
|
1754
1777
|
if (value == null || value.status !== "streaming" && value.status !== "complete" && value.status !== "error" || typeof value.raw !== "string") return;
|
|
1755
|
-
|
|
1778
|
+
const base = {
|
|
1756
1779
|
type: "structured-output",
|
|
1757
|
-
status: value.status,
|
|
1758
1780
|
raw: value.raw,
|
|
1759
1781
|
...value.partial !== void 0 ? { partial: value.partial } : {},
|
|
1760
|
-
...value.data !== void 0 ? { data: value.data } : {},
|
|
1761
1782
|
...value.reasoning ? { reasoning: value.reasoning } : {},
|
|
1762
1783
|
...value.errorMessage !== void 0 ? { errorMessage: value.errorMessage } : {}
|
|
1763
1784
|
};
|
|
1785
|
+
if (value.status !== "complete") return {
|
|
1786
|
+
...base,
|
|
1787
|
+
status: value.status
|
|
1788
|
+
};
|
|
1789
|
+
if (value.data === void 0) return void 0;
|
|
1790
|
+
return {
|
|
1791
|
+
...base,
|
|
1792
|
+
status: "complete",
|
|
1793
|
+
data: value.data
|
|
1794
|
+
};
|
|
1764
1795
|
}
|
|
1765
1796
|
/**
|
|
1766
1797
|
* Convert AG-UI user message content into `UIMessage` parts.
|
|
@@ -1818,7 +1849,7 @@ function generateMessageId() {
|
|
|
1818
1849
|
return `msg-${Date.now()}-${Math.random().toString(36).substring(7)}`;
|
|
1819
1850
|
}
|
|
1820
1851
|
//#endregion
|
|
1821
|
-
//#region node_modules/.
|
|
1852
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/ag-ui-wire.js
|
|
1822
1853
|
function isRecord(value) {
|
|
1823
1854
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1824
1855
|
}
|
|
@@ -1849,15 +1880,35 @@ function rebuiltToolMetadata(metadata, createdAt, id, content, anchorOwnsUiResou
|
|
|
1849
1880
|
* on assistant messages are additionally emitted as fan-out
|
|
1850
1881
|
* `{role:'tool',...}` and `{role:'reasoning',...}` entries for strict AG-UI
|
|
1851
1882
|
* server consumers. Set `includeSnapshotStructuredOutput` to retain complete
|
|
1852
|
-
* structured-output metadata for UI snapshots.
|
|
1883
|
+
* structured-output metadata for UI snapshots. Set `includeActivity` to emit
|
|
1884
|
+
* AG-UI `ActivityMessage` rows (MESSAGES_SNAPSHOT only — default omit so
|
|
1885
|
+
* RunAgentInput never carries activity).
|
|
1853
1886
|
*/
|
|
1854
1887
|
function uiMessagesToWire(messages, options) {
|
|
1855
1888
|
const wire = [];
|
|
1856
1889
|
const usedWireIds = new Set(messages.flatMap((message) => "id" in message && message.id && message.role !== "tool" ? [message.id] : []));
|
|
1857
1890
|
const includeSnapshotStructuredOutput = options?.includeSnapshotStructuredOutput ?? false;
|
|
1891
|
+
const includeActivity = options?.includeActivity ?? false;
|
|
1858
1892
|
const assistantIds = /* @__PURE__ */ new Set();
|
|
1859
1893
|
for (const msg of messages) if (msg.role === "assistant" && msg.id !== void 0) assistantIds.add(msg.id);
|
|
1860
1894
|
for (const msg of messages) {
|
|
1895
|
+
if (msg.role === "activity") {
|
|
1896
|
+
if (includeActivity && "parts" in msg) {
|
|
1897
|
+
const part = msg.parts.find((p) => p.type === "activity");
|
|
1898
|
+
if (part) {
|
|
1899
|
+
const activity = {
|
|
1900
|
+
id: msg.id,
|
|
1901
|
+
role: "activity",
|
|
1902
|
+
activityType: part.activityType,
|
|
1903
|
+
content: structuredClone(part.content),
|
|
1904
|
+
...msg.metadata != null && { metadata: msg.metadata },
|
|
1905
|
+
...part.subagentRunId !== void 0 && { subagentRunId: part.subagentRunId }
|
|
1906
|
+
};
|
|
1907
|
+
wire.push(activity);
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
continue;
|
|
1911
|
+
}
|
|
1861
1912
|
if (!("parts" in msg) && msg.role === "tool" && msg.toolCallId) {
|
|
1862
1913
|
const id = uniqueToolWireId(toolWireId(msg.id, msg.toolCallId, assistantIds), usedWireIds);
|
|
1863
1914
|
const metadata = rebuiltToolMetadata(msg.metadata, msg.createdAt, msg.id, msg.content);
|
|
@@ -1888,14 +1939,15 @@ function uiMessagesToWire(messages, options) {
|
|
|
1888
1939
|
parts: []
|
|
1889
1940
|
};
|
|
1890
1941
|
const segments = [current];
|
|
1891
|
-
for (const part of parts) if (part.type === "thinking")
|
|
1892
|
-
current
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1942
|
+
for (const part of parts) if (part.type === "thinking") {
|
|
1943
|
+
if (current.parts.some((p) => p.type === "tool-call" && isProviderExecutedToolCall(p))) {
|
|
1944
|
+
current = {
|
|
1945
|
+
thinking: [part],
|
|
1946
|
+
parts: []
|
|
1947
|
+
};
|
|
1948
|
+
segments.push(current);
|
|
1949
|
+
} else current.thinking.push(part);
|
|
1950
|
+
} else current.parts.push(part);
|
|
1899
1951
|
segments.forEach((segment, index) => {
|
|
1900
1952
|
for (const part of segment.thinking) {
|
|
1901
1953
|
const reasoning = {
|
|
@@ -2132,7 +2184,7 @@ function hashContent(s) {
|
|
|
2132
2184
|
return Math.abs(h).toString(36);
|
|
2133
2185
|
}
|
|
2134
2186
|
//#endregion
|
|
2135
|
-
//#region node_modules/.
|
|
2187
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/restore-inbound-chunk.js
|
|
2136
2188
|
/**
|
|
2137
2189
|
* Rebuild TanStack `TokenUsage` (`promptTokens`) from spec `usage[]` plus
|
|
2138
2190
|
* leftover fields in `metadata.tanstack.usage`. Restore in-process aliases
|
|
@@ -2169,7 +2221,7 @@ function restoreInboundChunk(chunk) {
|
|
|
2169
2221
|
return next;
|
|
2170
2222
|
}
|
|
2171
2223
|
//#endregion
|
|
2172
|
-
//#region node_modules/.
|
|
2224
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/activities/chat/tools/tool-definition.js
|
|
2173
2225
|
/**
|
|
2174
2226
|
* Create an isomorphic tool definition that can be used directly or instantiated for server/client
|
|
2175
2227
|
*
|
|
@@ -2267,7 +2319,7 @@ function toolDefinition(config) {
|
|
|
2267
2319
|
};
|
|
2268
2320
|
}
|
|
2269
2321
|
//#endregion
|
|
2270
|
-
//#region node_modules/.
|
|
2322
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/chunk-ids.js
|
|
2271
2323
|
function stringField(value) {
|
|
2272
2324
|
return typeof value === "string" && value !== "" ? value : void 0;
|
|
2273
2325
|
}
|
|
@@ -2280,7 +2332,7 @@ function getChunkRunId(chunk) {
|
|
|
2280
2332
|
return stringField(tanstackMetadata(chunk)?.runId);
|
|
2281
2333
|
}
|
|
2282
2334
|
//#endregion
|
|
2283
|
-
//#region node_modules/.
|
|
2335
|
+
//#region ../node_modules/.bun/partial-json@0.1.7/node_modules/partial-json/dist/options.js
|
|
2284
2336
|
var require_options = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
2285
2337
|
/**
|
|
2286
2338
|
* Sometimes you don't allow every type to be partially parsed.
|
|
@@ -2370,9 +2422,9 @@ var require_options = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
2370
2422
|
exports.default = exports.Allow;
|
|
2371
2423
|
}));
|
|
2372
2424
|
//#endregion
|
|
2373
|
-
//#region node_modules/.
|
|
2374
|
-
var import_dist = (/* @__PURE__ */ __commonJSMin(((exports) => {
|
|
2375
|
-
var __createBinding =
|
|
2425
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/activities/chat/stream/json-parser.js
|
|
2426
|
+
var import_dist = (/* @__PURE__ */ __commonJSMin(((exports, module, this$1) => {
|
|
2427
|
+
var __createBinding = this$1 && this$1.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
2376
2428
|
if (k2 === void 0) k2 = k;
|
|
2377
2429
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
2378
2430
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) desc = {
|
|
@@ -2386,8 +2438,8 @@ var import_dist = (/* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
2386
2438
|
if (k2 === void 0) k2 = k;
|
|
2387
2439
|
o[k2] = m[k];
|
|
2388
2440
|
}));
|
|
2389
|
-
var __exportStar =
|
|
2390
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports
|
|
2441
|
+
var __exportStar = this$1 && this$1.__exportStar || function(m, exports) {
|
|
2442
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
2391
2443
|
};
|
|
2392
2444
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2393
2445
|
exports.Allow = exports.MalformedJSON = exports.PartialJSON = exports.parseJSON = exports.parse = void 0;
|
|
@@ -2592,7 +2644,7 @@ function parsePartialJSON(jsonString) {
|
|
|
2592
2644
|
return defaultJSONParser.parse(jsonString);
|
|
2593
2645
|
}
|
|
2594
2646
|
//#endregion
|
|
2595
|
-
//#region node_modules/.
|
|
2647
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/activities/chat/stream/strategies.js
|
|
2596
2648
|
/**
|
|
2597
2649
|
* Immediate Strategy - emit on every chunk (default behavior)
|
|
2598
2650
|
*/
|
|
@@ -2602,7 +2654,7 @@ var ImmediateStrategy = class {
|
|
|
2602
2654
|
}
|
|
2603
2655
|
};
|
|
2604
2656
|
//#endregion
|
|
2605
|
-
//#region node_modules/.
|
|
2657
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/errors.js
|
|
2606
2658
|
/**
|
|
2607
2659
|
* Convert an AG-UI RUN_ERROR event to the Error shape exposed to consumers.
|
|
2608
2660
|
* Preserves the provider code and sanitized raw event when available, while
|
|
@@ -2616,7 +2668,732 @@ function runErrorEventToError(chunk) {
|
|
|
2616
2668
|
return error;
|
|
2617
2669
|
}
|
|
2618
2670
|
//#endregion
|
|
2619
|
-
//#region node_modules/.
|
|
2671
|
+
//#region ../node_modules/.bun/fast-json-patch@3.1.1/node_modules/fast-json-patch/module/helpers.mjs
|
|
2672
|
+
/*!
|
|
2673
|
+
* https://github.com/Starcounter-Jack/JSON-Patch
|
|
2674
|
+
* (c) 2017-2022 Joachim Wester
|
|
2675
|
+
* MIT licensed
|
|
2676
|
+
*/
|
|
2677
|
+
var __extends = (function() {
|
|
2678
|
+
var extendStatics = function(d, b) {
|
|
2679
|
+
extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d, b) {
|
|
2680
|
+
d.__proto__ = b;
|
|
2681
|
+
} || function(d, b) {
|
|
2682
|
+
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
|
2683
|
+
};
|
|
2684
|
+
return extendStatics(d, b);
|
|
2685
|
+
};
|
|
2686
|
+
return function(d, b) {
|
|
2687
|
+
extendStatics(d, b);
|
|
2688
|
+
function __() {
|
|
2689
|
+
this.constructor = d;
|
|
2690
|
+
}
|
|
2691
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
2692
|
+
};
|
|
2693
|
+
})();
|
|
2694
|
+
var _hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
2695
|
+
function hasOwnProperty(obj, key) {
|
|
2696
|
+
return _hasOwnProperty.call(obj, key);
|
|
2697
|
+
}
|
|
2698
|
+
function _objectKeys(obj) {
|
|
2699
|
+
if (Array.isArray(obj)) {
|
|
2700
|
+
var keys_1 = new Array(obj.length);
|
|
2701
|
+
for (var k = 0; k < keys_1.length; k++) keys_1[k] = "" + k;
|
|
2702
|
+
return keys_1;
|
|
2703
|
+
}
|
|
2704
|
+
if (Object.keys) return Object.keys(obj);
|
|
2705
|
+
var keys = [];
|
|
2706
|
+
for (var i in obj) if (hasOwnProperty(obj, i)) keys.push(i);
|
|
2707
|
+
return keys;
|
|
2708
|
+
}
|
|
2709
|
+
/**
|
|
2710
|
+
* Deeply clone the object.
|
|
2711
|
+
* https://jsperf.com/deep-copy-vs-json-stringify-json-parse/25 (recursiveDeepCopy)
|
|
2712
|
+
* @param {any} obj value to clone
|
|
2713
|
+
* @return {any} cloned obj
|
|
2714
|
+
*/
|
|
2715
|
+
function _deepClone(obj) {
|
|
2716
|
+
switch (typeof obj) {
|
|
2717
|
+
case "object": return JSON.parse(JSON.stringify(obj));
|
|
2718
|
+
case "undefined": return null;
|
|
2719
|
+
default: return obj;
|
|
2720
|
+
}
|
|
2721
|
+
}
|
|
2722
|
+
function isInteger(str) {
|
|
2723
|
+
var i = 0;
|
|
2724
|
+
var len = str.length;
|
|
2725
|
+
var charCode;
|
|
2726
|
+
while (i < len) {
|
|
2727
|
+
charCode = str.charCodeAt(i);
|
|
2728
|
+
if (charCode >= 48 && charCode <= 57) {
|
|
2729
|
+
i++;
|
|
2730
|
+
continue;
|
|
2731
|
+
}
|
|
2732
|
+
return false;
|
|
2733
|
+
}
|
|
2734
|
+
return true;
|
|
2735
|
+
}
|
|
2736
|
+
/**
|
|
2737
|
+
* Escapes a json pointer path
|
|
2738
|
+
* @param path The raw pointer
|
|
2739
|
+
* @return the Escaped path
|
|
2740
|
+
*/
|
|
2741
|
+
function escapePathComponent(path) {
|
|
2742
|
+
if (path.indexOf("/") === -1 && path.indexOf("~") === -1) return path;
|
|
2743
|
+
return path.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
2744
|
+
}
|
|
2745
|
+
/**
|
|
2746
|
+
* Unescapes a json pointer path
|
|
2747
|
+
* @param path The escaped pointer
|
|
2748
|
+
* @return The unescaped path
|
|
2749
|
+
*/
|
|
2750
|
+
function unescapePathComponent(path) {
|
|
2751
|
+
return path.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
2752
|
+
}
|
|
2753
|
+
/**
|
|
2754
|
+
* Recursively checks whether an object has any undefined values inside.
|
|
2755
|
+
*/
|
|
2756
|
+
function hasUndefined(obj) {
|
|
2757
|
+
if (obj === void 0) return true;
|
|
2758
|
+
if (obj) {
|
|
2759
|
+
if (Array.isArray(obj)) {
|
|
2760
|
+
for (var i_1 = 0, len = obj.length; i_1 < len; i_1++) if (hasUndefined(obj[i_1])) return true;
|
|
2761
|
+
} else if (typeof obj === "object") {
|
|
2762
|
+
var objKeys = _objectKeys(obj);
|
|
2763
|
+
var objKeysLength = objKeys.length;
|
|
2764
|
+
for (var i = 0; i < objKeysLength; i++) if (hasUndefined(obj[objKeys[i]])) return true;
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2767
|
+
return false;
|
|
2768
|
+
}
|
|
2769
|
+
function patchErrorMessageFormatter(message, args) {
|
|
2770
|
+
var messageParts = [message];
|
|
2771
|
+
for (var key in args) {
|
|
2772
|
+
var value = typeof args[key] === "object" ? JSON.stringify(args[key], null, 2) : args[key];
|
|
2773
|
+
if (typeof value !== "undefined") messageParts.push(key + ": " + value);
|
|
2774
|
+
}
|
|
2775
|
+
return messageParts.join("\n");
|
|
2776
|
+
}
|
|
2777
|
+
var PatchError = function(_super) {
|
|
2778
|
+
__extends(PatchError, _super);
|
|
2779
|
+
function PatchError(message, name, index, operation, tree) {
|
|
2780
|
+
var _newTarget = this.constructor;
|
|
2781
|
+
var _this = _super.call(this, patchErrorMessageFormatter(message, {
|
|
2782
|
+
name,
|
|
2783
|
+
index,
|
|
2784
|
+
operation,
|
|
2785
|
+
tree
|
|
2786
|
+
})) || this;
|
|
2787
|
+
_this.name = name;
|
|
2788
|
+
_this.index = index;
|
|
2789
|
+
_this.operation = operation;
|
|
2790
|
+
_this.tree = tree;
|
|
2791
|
+
Object.setPrototypeOf(_this, _newTarget.prototype);
|
|
2792
|
+
_this.message = patchErrorMessageFormatter(message, {
|
|
2793
|
+
name,
|
|
2794
|
+
index,
|
|
2795
|
+
operation,
|
|
2796
|
+
tree
|
|
2797
|
+
});
|
|
2798
|
+
return _this;
|
|
2799
|
+
}
|
|
2800
|
+
return PatchError;
|
|
2801
|
+
}(Error);
|
|
2802
|
+
//#endregion
|
|
2803
|
+
//#region ../node_modules/.bun/fast-json-patch@3.1.1/node_modules/fast-json-patch/module/core.mjs
|
|
2804
|
+
var core_exports = /* @__PURE__ */ __exportAll({
|
|
2805
|
+
JsonPatchError: () => JsonPatchError,
|
|
2806
|
+
_areEquals: () => _areEquals,
|
|
2807
|
+
applyOperation: () => applyOperation,
|
|
2808
|
+
applyPatch: () => applyPatch,
|
|
2809
|
+
applyReducer: () => applyReducer,
|
|
2810
|
+
deepClone: () => deepClone,
|
|
2811
|
+
getValueByPointer: () => getValueByPointer,
|
|
2812
|
+
validate: () => validate,
|
|
2813
|
+
validator: () => validator
|
|
2814
|
+
});
|
|
2815
|
+
var JsonPatchError = PatchError;
|
|
2816
|
+
var deepClone = _deepClone;
|
|
2817
|
+
var objOps = {
|
|
2818
|
+
add: function(obj, key, document) {
|
|
2819
|
+
obj[key] = this.value;
|
|
2820
|
+
return { newDocument: document };
|
|
2821
|
+
},
|
|
2822
|
+
remove: function(obj, key, document) {
|
|
2823
|
+
var removed = obj[key];
|
|
2824
|
+
delete obj[key];
|
|
2825
|
+
return {
|
|
2826
|
+
newDocument: document,
|
|
2827
|
+
removed
|
|
2828
|
+
};
|
|
2829
|
+
},
|
|
2830
|
+
replace: function(obj, key, document) {
|
|
2831
|
+
var removed = obj[key];
|
|
2832
|
+
obj[key] = this.value;
|
|
2833
|
+
return {
|
|
2834
|
+
newDocument: document,
|
|
2835
|
+
removed
|
|
2836
|
+
};
|
|
2837
|
+
},
|
|
2838
|
+
move: function(obj, key, document) {
|
|
2839
|
+
var removed = getValueByPointer(document, this.path);
|
|
2840
|
+
if (removed) removed = _deepClone(removed);
|
|
2841
|
+
var originalValue = applyOperation(document, {
|
|
2842
|
+
op: "remove",
|
|
2843
|
+
path: this.from
|
|
2844
|
+
}).removed;
|
|
2845
|
+
applyOperation(document, {
|
|
2846
|
+
op: "add",
|
|
2847
|
+
path: this.path,
|
|
2848
|
+
value: originalValue
|
|
2849
|
+
});
|
|
2850
|
+
return {
|
|
2851
|
+
newDocument: document,
|
|
2852
|
+
removed
|
|
2853
|
+
};
|
|
2854
|
+
},
|
|
2855
|
+
copy: function(obj, key, document) {
|
|
2856
|
+
var valueToCopy = getValueByPointer(document, this.from);
|
|
2857
|
+
applyOperation(document, {
|
|
2858
|
+
op: "add",
|
|
2859
|
+
path: this.path,
|
|
2860
|
+
value: _deepClone(valueToCopy)
|
|
2861
|
+
});
|
|
2862
|
+
return { newDocument: document };
|
|
2863
|
+
},
|
|
2864
|
+
test: function(obj, key, document) {
|
|
2865
|
+
return {
|
|
2866
|
+
newDocument: document,
|
|
2867
|
+
test: _areEquals(obj[key], this.value)
|
|
2868
|
+
};
|
|
2869
|
+
},
|
|
2870
|
+
_get: function(obj, key, document) {
|
|
2871
|
+
this.value = obj[key];
|
|
2872
|
+
return { newDocument: document };
|
|
2873
|
+
}
|
|
2874
|
+
};
|
|
2875
|
+
var arrOps = {
|
|
2876
|
+
add: function(arr, i, document) {
|
|
2877
|
+
if (isInteger(i)) arr.splice(i, 0, this.value);
|
|
2878
|
+
else arr[i] = this.value;
|
|
2879
|
+
return {
|
|
2880
|
+
newDocument: document,
|
|
2881
|
+
index: i
|
|
2882
|
+
};
|
|
2883
|
+
},
|
|
2884
|
+
remove: function(arr, i, document) {
|
|
2885
|
+
return {
|
|
2886
|
+
newDocument: document,
|
|
2887
|
+
removed: arr.splice(i, 1)[0]
|
|
2888
|
+
};
|
|
2889
|
+
},
|
|
2890
|
+
replace: function(arr, i, document) {
|
|
2891
|
+
var removed = arr[i];
|
|
2892
|
+
arr[i] = this.value;
|
|
2893
|
+
return {
|
|
2894
|
+
newDocument: document,
|
|
2895
|
+
removed
|
|
2896
|
+
};
|
|
2897
|
+
},
|
|
2898
|
+
move: objOps.move,
|
|
2899
|
+
copy: objOps.copy,
|
|
2900
|
+
test: objOps.test,
|
|
2901
|
+
_get: objOps._get
|
|
2902
|
+
};
|
|
2903
|
+
/**
|
|
2904
|
+
* Retrieves a value from a JSON document by a JSON pointer.
|
|
2905
|
+
* Returns the value.
|
|
2906
|
+
*
|
|
2907
|
+
* @param document The document to get the value from
|
|
2908
|
+
* @param pointer an escaped JSON pointer
|
|
2909
|
+
* @return The retrieved value
|
|
2910
|
+
*/
|
|
2911
|
+
function getValueByPointer(document, pointer) {
|
|
2912
|
+
if (pointer == "") return document;
|
|
2913
|
+
var getOriginalDestination = {
|
|
2914
|
+
op: "_get",
|
|
2915
|
+
path: pointer
|
|
2916
|
+
};
|
|
2917
|
+
applyOperation(document, getOriginalDestination);
|
|
2918
|
+
return getOriginalDestination.value;
|
|
2919
|
+
}
|
|
2920
|
+
/**
|
|
2921
|
+
* Apply a single JSON Patch Operation on a JSON document.
|
|
2922
|
+
* Returns the {newDocument, result} of the operation.
|
|
2923
|
+
* It modifies the `document` and `operation` objects - it gets the values by reference.
|
|
2924
|
+
* If you would like to avoid touching your values, clone them:
|
|
2925
|
+
* `jsonpatch.applyOperation(document, jsonpatch._deepClone(operation))`.
|
|
2926
|
+
*
|
|
2927
|
+
* @param document The document to patch
|
|
2928
|
+
* @param operation The operation to apply
|
|
2929
|
+
* @param validateOperation `false` is without validation, `true` to use default jsonpatch's validation, or you can pass a `validateOperation` callback to be used for validation.
|
|
2930
|
+
* @param mutateDocument Whether to mutate the original document or clone it before applying
|
|
2931
|
+
* @param banPrototypeModifications Whether to ban modifications to `__proto__`, defaults to `true`.
|
|
2932
|
+
* @return `{newDocument, result}` after the operation
|
|
2933
|
+
*/
|
|
2934
|
+
function applyOperation(document, operation, validateOperation, mutateDocument, banPrototypeModifications, index) {
|
|
2935
|
+
if (validateOperation === void 0) validateOperation = false;
|
|
2936
|
+
if (mutateDocument === void 0) mutateDocument = true;
|
|
2937
|
+
if (banPrototypeModifications === void 0) banPrototypeModifications = true;
|
|
2938
|
+
if (index === void 0) index = 0;
|
|
2939
|
+
if (validateOperation) {
|
|
2940
|
+
if (typeof validateOperation == "function") validateOperation(operation, 0, document, operation.path);
|
|
2941
|
+
else validator(operation, 0);
|
|
2942
|
+
}
|
|
2943
|
+
if (operation.path === "") {
|
|
2944
|
+
var returnValue = { newDocument: document };
|
|
2945
|
+
if (operation.op === "add") {
|
|
2946
|
+
returnValue.newDocument = operation.value;
|
|
2947
|
+
return returnValue;
|
|
2948
|
+
} else if (operation.op === "replace") {
|
|
2949
|
+
returnValue.newDocument = operation.value;
|
|
2950
|
+
returnValue.removed = document;
|
|
2951
|
+
return returnValue;
|
|
2952
|
+
} else if (operation.op === "move" || operation.op === "copy") {
|
|
2953
|
+
returnValue.newDocument = getValueByPointer(document, operation.from);
|
|
2954
|
+
if (operation.op === "move") returnValue.removed = document;
|
|
2955
|
+
return returnValue;
|
|
2956
|
+
} else if (operation.op === "test") {
|
|
2957
|
+
returnValue.test = _areEquals(document, operation.value);
|
|
2958
|
+
if (returnValue.test === false) throw new JsonPatchError("Test operation failed", "TEST_OPERATION_FAILED", index, operation, document);
|
|
2959
|
+
returnValue.newDocument = document;
|
|
2960
|
+
return returnValue;
|
|
2961
|
+
} else if (operation.op === "remove") {
|
|
2962
|
+
returnValue.removed = document;
|
|
2963
|
+
returnValue.newDocument = null;
|
|
2964
|
+
return returnValue;
|
|
2965
|
+
} else if (operation.op === "_get") {
|
|
2966
|
+
operation.value = document;
|
|
2967
|
+
return returnValue;
|
|
2968
|
+
} else if (validateOperation) throw new JsonPatchError("Operation `op` property is not one of operations defined in RFC-6902", "OPERATION_OP_INVALID", index, operation, document);
|
|
2969
|
+
else return returnValue;
|
|
2970
|
+
} else {
|
|
2971
|
+
if (!mutateDocument) document = _deepClone(document);
|
|
2972
|
+
var keys = (operation.path || "").split("/");
|
|
2973
|
+
var obj = document;
|
|
2974
|
+
var t = 1;
|
|
2975
|
+
var len = keys.length;
|
|
2976
|
+
var existingPathFragment = void 0;
|
|
2977
|
+
var key = void 0;
|
|
2978
|
+
var validateFunction = void 0;
|
|
2979
|
+
if (typeof validateOperation == "function") validateFunction = validateOperation;
|
|
2980
|
+
else validateFunction = validator;
|
|
2981
|
+
while (true) {
|
|
2982
|
+
key = keys[t];
|
|
2983
|
+
if (key && key.indexOf("~") != -1) key = unescapePathComponent(key);
|
|
2984
|
+
if (banPrototypeModifications && (key == "__proto__" || key == "prototype" && t > 0 && keys[t - 1] == "constructor")) throw new TypeError("JSON-Patch: modifying `__proto__` or `constructor/prototype` prop is banned for security reasons, if this was on purpose, please set `banPrototypeModifications` flag false and pass it to this function. More info in fast-json-patch README");
|
|
2985
|
+
if (validateOperation) {
|
|
2986
|
+
if (existingPathFragment === void 0) {
|
|
2987
|
+
if (obj[key] === void 0) existingPathFragment = keys.slice(0, t).join("/");
|
|
2988
|
+
else if (t == len - 1) existingPathFragment = operation.path;
|
|
2989
|
+
if (existingPathFragment !== void 0) validateFunction(operation, 0, document, existingPathFragment);
|
|
2990
|
+
}
|
|
2991
|
+
}
|
|
2992
|
+
t++;
|
|
2993
|
+
if (Array.isArray(obj)) {
|
|
2994
|
+
if (key === "-") key = obj.length;
|
|
2995
|
+
else if (validateOperation && !isInteger(key)) throw new JsonPatchError("Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index", "OPERATION_PATH_ILLEGAL_ARRAY_INDEX", index, operation, document);
|
|
2996
|
+
else if (isInteger(key)) key = ~~key;
|
|
2997
|
+
if (t >= len) {
|
|
2998
|
+
if (validateOperation && operation.op === "add" && key > obj.length) throw new JsonPatchError("The specified index MUST NOT be greater than the number of elements in the array", "OPERATION_VALUE_OUT_OF_BOUNDS", index, operation, document);
|
|
2999
|
+
var returnValue = arrOps[operation.op].call(operation, obj, key, document);
|
|
3000
|
+
if (returnValue.test === false) throw new JsonPatchError("Test operation failed", "TEST_OPERATION_FAILED", index, operation, document);
|
|
3001
|
+
return returnValue;
|
|
3002
|
+
}
|
|
3003
|
+
} else if (t >= len) {
|
|
3004
|
+
var returnValue = objOps[operation.op].call(operation, obj, key, document);
|
|
3005
|
+
if (returnValue.test === false) throw new JsonPatchError("Test operation failed", "TEST_OPERATION_FAILED", index, operation, document);
|
|
3006
|
+
return returnValue;
|
|
3007
|
+
}
|
|
3008
|
+
obj = obj[key];
|
|
3009
|
+
if (validateOperation && t < len && (!obj || typeof obj !== "object")) throw new JsonPatchError("Cannot perform operation at the desired path", "OPERATION_PATH_UNRESOLVABLE", index, operation, document);
|
|
3010
|
+
}
|
|
3011
|
+
}
|
|
3012
|
+
}
|
|
3013
|
+
/**
|
|
3014
|
+
* Apply a full JSON Patch array on a JSON document.
|
|
3015
|
+
* Returns the {newDocument, result} of the patch.
|
|
3016
|
+
* It modifies the `document` object and `patch` - it gets the values by reference.
|
|
3017
|
+
* If you would like to avoid touching your values, clone them:
|
|
3018
|
+
* `jsonpatch.applyPatch(document, jsonpatch._deepClone(patch))`.
|
|
3019
|
+
*
|
|
3020
|
+
* @param document The document to patch
|
|
3021
|
+
* @param patch The patch to apply
|
|
3022
|
+
* @param validateOperation `false` is without validation, `true` to use default jsonpatch's validation, or you can pass a `validateOperation` callback to be used for validation.
|
|
3023
|
+
* @param mutateDocument Whether to mutate the original document or clone it before applying
|
|
3024
|
+
* @param banPrototypeModifications Whether to ban modifications to `__proto__`, defaults to `true`.
|
|
3025
|
+
* @return An array of `{newDocument, result}` after the patch
|
|
3026
|
+
*/
|
|
3027
|
+
function applyPatch(document, patch, validateOperation, mutateDocument, banPrototypeModifications) {
|
|
3028
|
+
if (mutateDocument === void 0) mutateDocument = true;
|
|
3029
|
+
if (banPrototypeModifications === void 0) banPrototypeModifications = true;
|
|
3030
|
+
if (validateOperation) {
|
|
3031
|
+
if (!Array.isArray(patch)) throw new JsonPatchError("Patch sequence must be an array", "SEQUENCE_NOT_AN_ARRAY");
|
|
3032
|
+
}
|
|
3033
|
+
if (!mutateDocument) document = _deepClone(document);
|
|
3034
|
+
var results = new Array(patch.length);
|
|
3035
|
+
for (var i = 0, length_1 = patch.length; i < length_1; i++) {
|
|
3036
|
+
results[i] = applyOperation(document, patch[i], validateOperation, true, banPrototypeModifications, i);
|
|
3037
|
+
document = results[i].newDocument;
|
|
3038
|
+
}
|
|
3039
|
+
results.newDocument = document;
|
|
3040
|
+
return results;
|
|
3041
|
+
}
|
|
3042
|
+
/**
|
|
3043
|
+
* Apply a single JSON Patch Operation on a JSON document.
|
|
3044
|
+
* Returns the updated document.
|
|
3045
|
+
* Suitable as a reducer.
|
|
3046
|
+
*
|
|
3047
|
+
* @param document The document to patch
|
|
3048
|
+
* @param operation The operation to apply
|
|
3049
|
+
* @return The updated document
|
|
3050
|
+
*/
|
|
3051
|
+
function applyReducer(document, operation, index) {
|
|
3052
|
+
var operationResult = applyOperation(document, operation);
|
|
3053
|
+
if (operationResult.test === false) throw new JsonPatchError("Test operation failed", "TEST_OPERATION_FAILED", index, operation, document);
|
|
3054
|
+
return operationResult.newDocument;
|
|
3055
|
+
}
|
|
3056
|
+
/**
|
|
3057
|
+
* Validates a single operation. Called from `jsonpatch.validate`. Throws `JsonPatchError` in case of an error.
|
|
3058
|
+
* @param {object} operation - operation object (patch)
|
|
3059
|
+
* @param {number} index - index of operation in the sequence
|
|
3060
|
+
* @param {object} [document] - object where the operation is supposed to be applied
|
|
3061
|
+
* @param {string} [existingPathFragment] - comes along with `document`
|
|
3062
|
+
*/
|
|
3063
|
+
function validator(operation, index, document, existingPathFragment) {
|
|
3064
|
+
if (typeof operation !== "object" || operation === null || Array.isArray(operation)) throw new JsonPatchError("Operation is not an object", "OPERATION_NOT_AN_OBJECT", index, operation, document);
|
|
3065
|
+
else if (!objOps[operation.op]) throw new JsonPatchError("Operation `op` property is not one of operations defined in RFC-6902", "OPERATION_OP_INVALID", index, operation, document);
|
|
3066
|
+
else if (typeof operation.path !== "string") throw new JsonPatchError("Operation `path` property is not a string", "OPERATION_PATH_INVALID", index, operation, document);
|
|
3067
|
+
else if (operation.path.indexOf("/") !== 0 && operation.path.length > 0) throw new JsonPatchError("Operation `path` property must start with \"/\"", "OPERATION_PATH_INVALID", index, operation, document);
|
|
3068
|
+
else if ((operation.op === "move" || operation.op === "copy") && typeof operation.from !== "string") throw new JsonPatchError("Operation `from` property is not present (applicable in `move` and `copy` operations)", "OPERATION_FROM_REQUIRED", index, operation, document);
|
|
3069
|
+
else if ((operation.op === "add" || operation.op === "replace" || operation.op === "test") && operation.value === void 0) throw new JsonPatchError("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)", "OPERATION_VALUE_REQUIRED", index, operation, document);
|
|
3070
|
+
else if ((operation.op === "add" || operation.op === "replace" || operation.op === "test") && hasUndefined(operation.value)) throw new JsonPatchError("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)", "OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED", index, operation, document);
|
|
3071
|
+
else if (document) {
|
|
3072
|
+
if (operation.op == "add") {
|
|
3073
|
+
var pathLen = operation.path.split("/").length;
|
|
3074
|
+
var existingPathLen = existingPathFragment.split("/").length;
|
|
3075
|
+
if (pathLen !== existingPathLen + 1 && pathLen !== existingPathLen) throw new JsonPatchError("Cannot perform an `add` operation at the desired path", "OPERATION_PATH_CANNOT_ADD", index, operation, document);
|
|
3076
|
+
} else if (operation.op === "replace" || operation.op === "remove" || operation.op === "_get") {
|
|
3077
|
+
if (operation.path !== existingPathFragment) throw new JsonPatchError("Cannot perform the operation at a path that does not exist", "OPERATION_PATH_UNRESOLVABLE", index, operation, document);
|
|
3078
|
+
} else if (operation.op === "move" || operation.op === "copy") {
|
|
3079
|
+
var error = validate([{
|
|
3080
|
+
op: "_get",
|
|
3081
|
+
path: operation.from,
|
|
3082
|
+
value: void 0
|
|
3083
|
+
}], document);
|
|
3084
|
+
if (error && error.name === "OPERATION_PATH_UNRESOLVABLE") throw new JsonPatchError("Cannot perform the operation from a path that does not exist", "OPERATION_FROM_UNRESOLVABLE", index, operation, document);
|
|
3085
|
+
}
|
|
3086
|
+
}
|
|
3087
|
+
}
|
|
3088
|
+
/**
|
|
3089
|
+
* Validates a sequence of operations. If `document` parameter is provided, the sequence is additionally validated against the object document.
|
|
3090
|
+
* If error is encountered, returns a JsonPatchError object
|
|
3091
|
+
* @param sequence
|
|
3092
|
+
* @param document
|
|
3093
|
+
* @returns {JsonPatchError|undefined}
|
|
3094
|
+
*/
|
|
3095
|
+
function validate(sequence, document, externalValidator) {
|
|
3096
|
+
try {
|
|
3097
|
+
if (!Array.isArray(sequence)) throw new JsonPatchError("Patch sequence must be an array", "SEQUENCE_NOT_AN_ARRAY");
|
|
3098
|
+
if (document) applyPatch(_deepClone(document), _deepClone(sequence), externalValidator || true);
|
|
3099
|
+
else {
|
|
3100
|
+
externalValidator = externalValidator || validator;
|
|
3101
|
+
for (var i = 0; i < sequence.length; i++) externalValidator(sequence[i], i, document, void 0);
|
|
3102
|
+
}
|
|
3103
|
+
} catch (e) {
|
|
3104
|
+
if (e instanceof JsonPatchError) return e;
|
|
3105
|
+
else throw e;
|
|
3106
|
+
}
|
|
3107
|
+
}
|
|
3108
|
+
function _areEquals(a, b) {
|
|
3109
|
+
if (a === b) return true;
|
|
3110
|
+
if (a && b && typeof a == "object" && typeof b == "object") {
|
|
3111
|
+
var arrA = Array.isArray(a), arrB = Array.isArray(b), i, length, key;
|
|
3112
|
+
if (arrA && arrB) {
|
|
3113
|
+
length = a.length;
|
|
3114
|
+
if (length != b.length) return false;
|
|
3115
|
+
for (i = length; i-- !== 0;) if (!_areEquals(a[i], b[i])) return false;
|
|
3116
|
+
return true;
|
|
3117
|
+
}
|
|
3118
|
+
if (arrA != arrB) return false;
|
|
3119
|
+
var keys = Object.keys(a);
|
|
3120
|
+
length = keys.length;
|
|
3121
|
+
if (length !== Object.keys(b).length) return false;
|
|
3122
|
+
for (i = length; i-- !== 0;) if (!b.hasOwnProperty(keys[i])) return false;
|
|
3123
|
+
for (i = length; i-- !== 0;) {
|
|
3124
|
+
key = keys[i];
|
|
3125
|
+
if (!_areEquals(a[key], b[key])) return false;
|
|
3126
|
+
}
|
|
3127
|
+
return true;
|
|
3128
|
+
}
|
|
3129
|
+
return a !== a && b !== b;
|
|
3130
|
+
}
|
|
3131
|
+
//#endregion
|
|
3132
|
+
//#region ../node_modules/.bun/fast-json-patch@3.1.1/node_modules/fast-json-patch/module/duplex.mjs
|
|
3133
|
+
/*!
|
|
3134
|
+
* https://github.com/Starcounter-Jack/JSON-Patch
|
|
3135
|
+
* (c) 2017-2021 Joachim Wester
|
|
3136
|
+
* MIT license
|
|
3137
|
+
*/
|
|
3138
|
+
var duplex_exports = /* @__PURE__ */ __exportAll({
|
|
3139
|
+
compare: () => compare,
|
|
3140
|
+
generate: () => generate,
|
|
3141
|
+
observe: () => observe,
|
|
3142
|
+
unobserve: () => unobserve
|
|
3143
|
+
});
|
|
3144
|
+
var beforeDict = /* @__PURE__ */ new WeakMap();
|
|
3145
|
+
var Mirror = function() {
|
|
3146
|
+
function Mirror(obj) {
|
|
3147
|
+
this.observers = /* @__PURE__ */ new Map();
|
|
3148
|
+
this.obj = obj;
|
|
3149
|
+
}
|
|
3150
|
+
return Mirror;
|
|
3151
|
+
}();
|
|
3152
|
+
var ObserverInfo = function() {
|
|
3153
|
+
function ObserverInfo(callback, observer) {
|
|
3154
|
+
this.callback = callback;
|
|
3155
|
+
this.observer = observer;
|
|
3156
|
+
}
|
|
3157
|
+
return ObserverInfo;
|
|
3158
|
+
}();
|
|
3159
|
+
function getMirror(obj) {
|
|
3160
|
+
return beforeDict.get(obj);
|
|
3161
|
+
}
|
|
3162
|
+
function getObserverFromMirror(mirror, callback) {
|
|
3163
|
+
return mirror.observers.get(callback);
|
|
3164
|
+
}
|
|
3165
|
+
function removeObserverFromMirror(mirror, observer) {
|
|
3166
|
+
mirror.observers.delete(observer.callback);
|
|
3167
|
+
}
|
|
3168
|
+
/**
|
|
3169
|
+
* Detach an observer from an object
|
|
3170
|
+
*/
|
|
3171
|
+
function unobserve(root, observer) {
|
|
3172
|
+
observer.unobserve();
|
|
3173
|
+
}
|
|
3174
|
+
/**
|
|
3175
|
+
* Observes changes made to an object, which can then be retrieved using generate
|
|
3176
|
+
*/
|
|
3177
|
+
function observe(obj, callback) {
|
|
3178
|
+
var patches = [];
|
|
3179
|
+
var observer;
|
|
3180
|
+
var mirror = getMirror(obj);
|
|
3181
|
+
if (!mirror) {
|
|
3182
|
+
mirror = new Mirror(obj);
|
|
3183
|
+
beforeDict.set(obj, mirror);
|
|
3184
|
+
} else {
|
|
3185
|
+
var observerInfo = getObserverFromMirror(mirror, callback);
|
|
3186
|
+
observer = observerInfo && observerInfo.observer;
|
|
3187
|
+
}
|
|
3188
|
+
if (observer) return observer;
|
|
3189
|
+
observer = {};
|
|
3190
|
+
mirror.value = _deepClone(obj);
|
|
3191
|
+
if (callback) {
|
|
3192
|
+
observer.callback = callback;
|
|
3193
|
+
observer.next = null;
|
|
3194
|
+
var dirtyCheck = function() {
|
|
3195
|
+
generate(observer);
|
|
3196
|
+
};
|
|
3197
|
+
var fastCheck = function() {
|
|
3198
|
+
clearTimeout(observer.next);
|
|
3199
|
+
observer.next = setTimeout(dirtyCheck);
|
|
3200
|
+
};
|
|
3201
|
+
if (typeof window !== "undefined") {
|
|
3202
|
+
window.addEventListener("mouseup", fastCheck);
|
|
3203
|
+
window.addEventListener("keyup", fastCheck);
|
|
3204
|
+
window.addEventListener("mousedown", fastCheck);
|
|
3205
|
+
window.addEventListener("keydown", fastCheck);
|
|
3206
|
+
window.addEventListener("change", fastCheck);
|
|
3207
|
+
}
|
|
3208
|
+
}
|
|
3209
|
+
observer.patches = patches;
|
|
3210
|
+
observer.object = obj;
|
|
3211
|
+
observer.unobserve = function() {
|
|
3212
|
+
generate(observer);
|
|
3213
|
+
clearTimeout(observer.next);
|
|
3214
|
+
removeObserverFromMirror(mirror, observer);
|
|
3215
|
+
if (typeof window !== "undefined") {
|
|
3216
|
+
window.removeEventListener("mouseup", fastCheck);
|
|
3217
|
+
window.removeEventListener("keyup", fastCheck);
|
|
3218
|
+
window.removeEventListener("mousedown", fastCheck);
|
|
3219
|
+
window.removeEventListener("keydown", fastCheck);
|
|
3220
|
+
window.removeEventListener("change", fastCheck);
|
|
3221
|
+
}
|
|
3222
|
+
};
|
|
3223
|
+
mirror.observers.set(callback, new ObserverInfo(callback, observer));
|
|
3224
|
+
return observer;
|
|
3225
|
+
}
|
|
3226
|
+
/**
|
|
3227
|
+
* Generate an array of patches from an observer
|
|
3228
|
+
*/
|
|
3229
|
+
function generate(observer, invertible) {
|
|
3230
|
+
if (invertible === void 0) invertible = false;
|
|
3231
|
+
var mirror = beforeDict.get(observer.object);
|
|
3232
|
+
_generate(mirror.value, observer.object, observer.patches, "", invertible);
|
|
3233
|
+
if (observer.patches.length) applyPatch(mirror.value, observer.patches);
|
|
3234
|
+
var temp = observer.patches;
|
|
3235
|
+
if (temp.length > 0) {
|
|
3236
|
+
observer.patches = [];
|
|
3237
|
+
if (observer.callback) observer.callback(temp);
|
|
3238
|
+
}
|
|
3239
|
+
return temp;
|
|
3240
|
+
}
|
|
3241
|
+
function _generate(mirror, obj, patches, path, invertible) {
|
|
3242
|
+
if (obj === mirror) return;
|
|
3243
|
+
if (typeof obj.toJSON === "function") obj = obj.toJSON();
|
|
3244
|
+
var newKeys = _objectKeys(obj);
|
|
3245
|
+
var oldKeys = _objectKeys(mirror);
|
|
3246
|
+
var deleted = false;
|
|
3247
|
+
for (var t = oldKeys.length - 1; t >= 0; t--) {
|
|
3248
|
+
var key = oldKeys[t];
|
|
3249
|
+
var oldVal = mirror[key];
|
|
3250
|
+
if (hasOwnProperty(obj, key) && !(obj[key] === void 0 && oldVal !== void 0 && Array.isArray(obj) === false)) {
|
|
3251
|
+
var newVal = obj[key];
|
|
3252
|
+
if (typeof oldVal == "object" && oldVal != null && typeof newVal == "object" && newVal != null && Array.isArray(oldVal) === Array.isArray(newVal)) _generate(oldVal, newVal, patches, path + "/" + escapePathComponent(key), invertible);
|
|
3253
|
+
else if (oldVal !== newVal) {
|
|
3254
|
+
if (invertible) patches.push({
|
|
3255
|
+
op: "test",
|
|
3256
|
+
path: path + "/" + escapePathComponent(key),
|
|
3257
|
+
value: _deepClone(oldVal)
|
|
3258
|
+
});
|
|
3259
|
+
patches.push({
|
|
3260
|
+
op: "replace",
|
|
3261
|
+
path: path + "/" + escapePathComponent(key),
|
|
3262
|
+
value: _deepClone(newVal)
|
|
3263
|
+
});
|
|
3264
|
+
}
|
|
3265
|
+
} else if (Array.isArray(mirror) === Array.isArray(obj)) {
|
|
3266
|
+
if (invertible) patches.push({
|
|
3267
|
+
op: "test",
|
|
3268
|
+
path: path + "/" + escapePathComponent(key),
|
|
3269
|
+
value: _deepClone(oldVal)
|
|
3270
|
+
});
|
|
3271
|
+
patches.push({
|
|
3272
|
+
op: "remove",
|
|
3273
|
+
path: path + "/" + escapePathComponent(key)
|
|
3274
|
+
});
|
|
3275
|
+
deleted = true;
|
|
3276
|
+
} else {
|
|
3277
|
+
if (invertible) patches.push({
|
|
3278
|
+
op: "test",
|
|
3279
|
+
path,
|
|
3280
|
+
value: mirror
|
|
3281
|
+
});
|
|
3282
|
+
patches.push({
|
|
3283
|
+
op: "replace",
|
|
3284
|
+
path,
|
|
3285
|
+
value: obj
|
|
3286
|
+
});
|
|
3287
|
+
}
|
|
3288
|
+
}
|
|
3289
|
+
if (!deleted && newKeys.length == oldKeys.length) return;
|
|
3290
|
+
for (var t = 0; t < newKeys.length; t++) {
|
|
3291
|
+
var key = newKeys[t];
|
|
3292
|
+
if (!hasOwnProperty(mirror, key) && obj[key] !== void 0) patches.push({
|
|
3293
|
+
op: "add",
|
|
3294
|
+
path: path + "/" + escapePathComponent(key),
|
|
3295
|
+
value: _deepClone(obj[key])
|
|
3296
|
+
});
|
|
3297
|
+
}
|
|
3298
|
+
}
|
|
3299
|
+
/**
|
|
3300
|
+
* Create an array of patches from the differences in two objects
|
|
3301
|
+
*/
|
|
3302
|
+
function compare(tree1, tree2, invertible) {
|
|
3303
|
+
if (invertible === void 0) invertible = false;
|
|
3304
|
+
var patches = [];
|
|
3305
|
+
_generate(tree1, tree2, patches, "", invertible);
|
|
3306
|
+
return patches;
|
|
3307
|
+
}
|
|
3308
|
+
//#endregion
|
|
3309
|
+
//#region ../node_modules/.bun/fast-json-patch@3.1.1/node_modules/fast-json-patch/index.mjs
|
|
3310
|
+
/**
|
|
3311
|
+
* Default export for backwards compat
|
|
3312
|
+
*/
|
|
3313
|
+
var fast_json_patch_default = Object.assign({}, core_exports, duplex_exports, {
|
|
3314
|
+
JsonPatchError: PatchError,
|
|
3315
|
+
deepClone: _deepClone,
|
|
3316
|
+
escapePathComponent,
|
|
3317
|
+
unescapePathComponent
|
|
3318
|
+
});
|
|
3319
|
+
//#endregion
|
|
3320
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/activities/chat/activity-records.js
|
|
3321
|
+
function isActivityPart(part) {
|
|
3322
|
+
return part.type === "activity";
|
|
3323
|
+
}
|
|
3324
|
+
function isActivityContent(value) {
|
|
3325
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
3326
|
+
}
|
|
3327
|
+
function applyActivitySnapshotToUIMessages(messages, chunk) {
|
|
3328
|
+
const { messageId, activityType, content } = chunk;
|
|
3329
|
+
const replace = chunk.replace ?? true;
|
|
3330
|
+
const existingIndex = messages.findIndex((m) => m.id === messageId);
|
|
3331
|
+
const existing = existingIndex >= 0 ? messages[existingIndex] : void 0;
|
|
3332
|
+
if (existing && existing.role !== "activity") {
|
|
3333
|
+
console.warn(`ACTIVITY_SNAPSHOT: Message '${messageId}' is not an activity message`);
|
|
3334
|
+
return messages;
|
|
3335
|
+
}
|
|
3336
|
+
if (existing && !replace) return messages;
|
|
3337
|
+
const metadata = mergeMetadata(existing?.role === "activity" ? existing.metadata : void 0, chunk.metadata);
|
|
3338
|
+
const next = {
|
|
3339
|
+
id: messageId,
|
|
3340
|
+
role: "activity",
|
|
3341
|
+
parts: [{
|
|
3342
|
+
type: "activity",
|
|
3343
|
+
activityType,
|
|
3344
|
+
content: structuredClone(content ?? {})
|
|
3345
|
+
}],
|
|
3346
|
+
...metadata != null ? { metadata } : {},
|
|
3347
|
+
...existing?.role === "activity" && existing.createdAt != null ? { createdAt: existing.createdAt } : {},
|
|
3348
|
+
...existing?.role === "activity" && existing.name != null ? { name: existing.name } : {}
|
|
3349
|
+
};
|
|
3350
|
+
if (existingIndex === -1) return [...messages, next];
|
|
3351
|
+
return messages.map((msg, index) => index === existingIndex ? next : msg);
|
|
3352
|
+
}
|
|
3353
|
+
function applyActivityDeltaToUIMessages(messages, chunk) {
|
|
3354
|
+
const { messageId, activityType, patch } = chunk;
|
|
3355
|
+
const existingIndex = messages.findIndex((m) => m.id === messageId);
|
|
3356
|
+
if (existingIndex === -1) {
|
|
3357
|
+
console.warn(`ACTIVITY_DELTA: No activity message '${messageId}'`);
|
|
3358
|
+
return messages;
|
|
3359
|
+
}
|
|
3360
|
+
const existing = messages[existingIndex];
|
|
3361
|
+
if (existing == null || existing.role !== "activity") {
|
|
3362
|
+
console.warn(`ACTIVITY_DELTA: Message '${messageId}' is not an activity message`);
|
|
3363
|
+
return messages;
|
|
3364
|
+
}
|
|
3365
|
+
const activityPart = existing.parts.find(isActivityPart);
|
|
3366
|
+
if (activityPart && activityPart.activityType !== activityType) {
|
|
3367
|
+
console.warn(`ACTIVITY_DELTA: activityType '${activityType}' does not match '${activityPart.activityType}' for '${messageId}'`);
|
|
3368
|
+
return messages;
|
|
3369
|
+
}
|
|
3370
|
+
const baseContent = structuredClone(activityPart?.content ?? {});
|
|
3371
|
+
try {
|
|
3372
|
+
const result = fast_json_patch_default.applyPatch(baseContent, patch ?? [], true, false);
|
|
3373
|
+
if (!isActivityContent(result.newDocument)) {
|
|
3374
|
+
console.warn(`ACTIVITY_DELTA: patched content for '${messageId}' is not an object`);
|
|
3375
|
+
return messages;
|
|
3376
|
+
}
|
|
3377
|
+
const nextPart = {
|
|
3378
|
+
type: "activity",
|
|
3379
|
+
activityType,
|
|
3380
|
+
content: structuredClone(result.newDocument)
|
|
3381
|
+
};
|
|
3382
|
+
const parts = activityPart ? existing.parts.map((part) => part.type === "activity" ? nextPart : part) : [nextPart];
|
|
3383
|
+
const metadata = mergeMetadata(existing.metadata, chunk.metadata);
|
|
3384
|
+
return messages.map((msg, index) => index === existingIndex ? {
|
|
3385
|
+
...msg,
|
|
3386
|
+
parts,
|
|
3387
|
+
...metadata != null ? { metadata } : {}
|
|
3388
|
+
} : msg);
|
|
3389
|
+
} catch (error) {
|
|
3390
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3391
|
+
console.warn(`Failed to apply activity patch for '${messageId}': ${errorMessage}`);
|
|
3392
|
+
return messages;
|
|
3393
|
+
}
|
|
3394
|
+
}
|
|
3395
|
+
//#endregion
|
|
3396
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/activities/chat/stream/message-updaters.js
|
|
2620
3397
|
/**
|
|
2621
3398
|
* Message Updaters (Internal)
|
|
2622
3399
|
*
|
|
@@ -2918,7 +3695,7 @@ function updateThinkingPart(messages, messageId, stepId, content, signature) {
|
|
|
2918
3695
|
});
|
|
2919
3696
|
}
|
|
2920
3697
|
//#endregion
|
|
2921
|
-
//#region node_modules/.
|
|
3698
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/activities/chat/stream/processor.js
|
|
2922
3699
|
/**
|
|
2923
3700
|
* Unified Stream Processor
|
|
2924
3701
|
*
|
|
@@ -2939,6 +3716,28 @@ function updateThinkingPart(messages, messageId, stepId, content, signature) {
|
|
|
2939
3716
|
* adapter contract, single-shot flows, and expected UIMessage output.
|
|
2940
3717
|
*/
|
|
2941
3718
|
var STRUCTURED_OUTPUT_UPDATE_BATCH_SIZE = 12;
|
|
3719
|
+
/**
|
|
3720
|
+
* Events that leave this processor's open *_CHUNK stream open.
|
|
3721
|
+
* RAW, activity events, and REASONING_ENCRYPTED_VALUE match the AG-UI client.
|
|
3722
|
+
* Subagent lifecycle events stay here too: the child processor owns that
|
|
3723
|
+
* lane, and SUBAGENT_FINISHED or SUBAGENT_ERROR finalizes the child.
|
|
3724
|
+
*/
|
|
3725
|
+
var CHUNK_PASS_THROUGH = /* @__PURE__ */ new Set([
|
|
3726
|
+
"RAW",
|
|
3727
|
+
"ACTIVITY_SNAPSHOT",
|
|
3728
|
+
"ACTIVITY_DELTA",
|
|
3729
|
+
"REASONING_ENCRYPTED_VALUE",
|
|
3730
|
+
"SUBAGENT_STARTED",
|
|
3731
|
+
"SUBAGENT_FINISHED",
|
|
3732
|
+
"SUBAGENT_ERROR"
|
|
3733
|
+
]);
|
|
3734
|
+
/** A run-level event closes every open shorthand lane, including children. */
|
|
3735
|
+
var RUN_LEVEL_CLOSES_LANES = /* @__PURE__ */ new Set([
|
|
3736
|
+
"RUN_STARTED",
|
|
3737
|
+
"RUN_FINISHED",
|
|
3738
|
+
"RUN_ERROR",
|
|
3739
|
+
"MESSAGES_SNAPSHOT"
|
|
3740
|
+
]);
|
|
2942
3741
|
function interruptBatchHasGeneric(interrupts) {
|
|
2943
3742
|
return interrupts.some((interrupt) => {
|
|
2944
3743
|
const metadata = interrupt.metadata;
|
|
@@ -2964,6 +3763,19 @@ function serializeToolInput(input) {
|
|
|
2964
3763
|
}
|
|
2965
3764
|
}
|
|
2966
3765
|
/**
|
|
3766
|
+
* The input of a tool call from its raw arguments: `{}` for an empty string,
|
|
3767
|
+
* `undefined` when the arguments are not complete JSON (for example cut off)
|
|
3768
|
+
* or are `null`.
|
|
3769
|
+
*/
|
|
3770
|
+
function parseToolArguments(args) {
|
|
3771
|
+
if (args.trim() === "") return {};
|
|
3772
|
+
try {
|
|
3773
|
+
return JSON.parse(args) ?? void 0;
|
|
3774
|
+
} catch {
|
|
3775
|
+
return;
|
|
3776
|
+
}
|
|
3777
|
+
}
|
|
3778
|
+
/**
|
|
2967
3779
|
* StreamProcessor - State machine for processing AI response streams
|
|
2968
3780
|
*
|
|
2969
3781
|
* Manages the full UIMessage[] conversation and emits events on changes.
|
|
@@ -2990,9 +3802,12 @@ var StreamProcessor = class StreamProcessor {
|
|
|
2990
3802
|
toolCallToMessage = /* @__PURE__ */ new Map();
|
|
2991
3803
|
pendingManualMessageId = null;
|
|
2992
3804
|
pendingThinkingStepId = null;
|
|
3805
|
+
openChunk = null;
|
|
2993
3806
|
structuredMessageIds = /* @__PURE__ */ new Set();
|
|
2994
3807
|
structuredOutputUpdateBatches = /* @__PURE__ */ new Map();
|
|
2995
3808
|
activeRuns = /* @__PURE__ */ new Set();
|
|
3809
|
+
runToolCallIds = [];
|
|
3810
|
+
toolCallsSentToClient = /* @__PURE__ */ new Set();
|
|
2996
3811
|
childProcessors = /* @__PURE__ */ new Map();
|
|
2997
3812
|
childToolCalls = /* @__PURE__ */ new Map();
|
|
2998
3813
|
finishReason = null;
|
|
@@ -3199,6 +4014,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3199
4014
|
this.structuredMessageIds.clear();
|
|
3200
4015
|
this.structuredOutputUpdateBatches.clear();
|
|
3201
4016
|
this.pendingManualMessageId = null;
|
|
4017
|
+
this.openChunk = null;
|
|
3202
4018
|
this.childProcessors.clear();
|
|
3203
4019
|
this.childToolCalls.clear();
|
|
3204
4020
|
this.emitMessagesChange();
|
|
@@ -3219,7 +4035,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3219
4035
|
*
|
|
3220
4036
|
* Central dispatch for all AG-UI events. Each event type maps to a specific
|
|
3221
4037
|
* handler. Events not listed in the switch are intentionally ignored
|
|
3222
|
-
* (
|
|
4038
|
+
* (STATE_SNAPSHOT, STATE_DELTA).
|
|
3223
4039
|
*
|
|
3224
4040
|
* @see docs/chat-architecture.md#adapter-contract — Expected event types and ordering
|
|
3225
4041
|
*/
|
|
@@ -3230,6 +4046,10 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3230
4046
|
index: this.recording.chunks.length
|
|
3231
4047
|
});
|
|
3232
4048
|
if (this.routeToChild(chunk)) return;
|
|
4049
|
+
for (const event of this.expandChunk(chunk)) this.dispatchChunk(event);
|
|
4050
|
+
}
|
|
4051
|
+
/** Send one event, after expandChunk(), to its handler. */
|
|
4052
|
+
dispatchChunk(chunk) {
|
|
3233
4053
|
switch (chunk.type) {
|
|
3234
4054
|
case "SUBAGENT_STARTED":
|
|
3235
4055
|
this.handleSubagentStartedEvent(chunk);
|
|
@@ -3289,7 +4109,178 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3289
4109
|
case "TOOL_CALL_RESULT":
|
|
3290
4110
|
this.handleToolCallResultEvent(chunk);
|
|
3291
4111
|
break;
|
|
3292
|
-
case "STEP_STARTED":
|
|
4112
|
+
case "STEP_STARTED":
|
|
4113
|
+
this.handleStepStartedEvent(chunk);
|
|
4114
|
+
break;
|
|
4115
|
+
case "ACTIVITY_SNAPSHOT":
|
|
4116
|
+
this.handleActivitySnapshotEvent(chunk);
|
|
4117
|
+
break;
|
|
4118
|
+
case "ACTIVITY_DELTA": this.handleActivityDeltaEvent(chunk);
|
|
4119
|
+
}
|
|
4120
|
+
}
|
|
4121
|
+
/**
|
|
4122
|
+
* AG-UI lets a producer send one TEXT_MESSAGE_CHUNK, TOOL_CALL_CHUNK or
|
|
4123
|
+
* REASONING_MESSAGE_CHUNK in place of the START / CONTENT (ARGS) / END
|
|
4124
|
+
* events. A chunk with a new id opens a stream. A chunk with the same id or
|
|
4125
|
+
* no id continues it. Any other event closes it, except the ones in
|
|
4126
|
+
* CHUNK_PASS_THROUGH. Expand the shorthand into the START / CONTENT (ARGS)
|
|
4127
|
+
* / END events, so both forms build the same message.
|
|
4128
|
+
*/
|
|
4129
|
+
expandChunk(chunk) {
|
|
4130
|
+
const open = this.openChunk;
|
|
4131
|
+
const timestamp = chunk.timestamp;
|
|
4132
|
+
switch (chunk.type) {
|
|
4133
|
+
case "TEXT_MESSAGE_CHUNK": {
|
|
4134
|
+
const id = this.chunkStreamId("TEXT_MESSAGE", chunk.messageId, chunk.type);
|
|
4135
|
+
if (id === void 0) return this.closeChunk();
|
|
4136
|
+
const events = [];
|
|
4137
|
+
if (open?.family !== "TEXT_MESSAGE" || open.id !== id) {
|
|
4138
|
+
events.push(...this.closeChunk(), {
|
|
4139
|
+
type: EventType.TEXT_MESSAGE_START,
|
|
4140
|
+
messageId: id,
|
|
4141
|
+
role: chunk.role ?? "assistant",
|
|
4142
|
+
...chunk.name !== void 0 ? { name: chunk.name } : {},
|
|
4143
|
+
timestamp
|
|
4144
|
+
});
|
|
4145
|
+
this.openChunk = {
|
|
4146
|
+
family: "TEXT_MESSAGE",
|
|
4147
|
+
id
|
|
4148
|
+
};
|
|
4149
|
+
}
|
|
4150
|
+
if (chunk.delta !== void 0 || chunk.metadata !== void 0) events.push({
|
|
4151
|
+
type: EventType.TEXT_MESSAGE_CONTENT,
|
|
4152
|
+
messageId: id,
|
|
4153
|
+
delta: chunk.delta ?? "",
|
|
4154
|
+
metadata: chunk.metadata,
|
|
4155
|
+
timestamp
|
|
4156
|
+
});
|
|
4157
|
+
return events;
|
|
4158
|
+
}
|
|
4159
|
+
case "TOOL_CALL_CHUNK": {
|
|
4160
|
+
const id = this.chunkStreamId("TOOL_CALL", chunk.toolCallId, chunk.type);
|
|
4161
|
+
if (id === void 0) return this.closeChunk();
|
|
4162
|
+
const events = [];
|
|
4163
|
+
if (open?.family !== "TOOL_CALL" || open.id !== id) {
|
|
4164
|
+
if (chunk.toolCallName === void 0) {
|
|
4165
|
+
console.warn(`[StreamProcessor] Dropped TOOL_CALL_CHUNK ${id}: the first chunk of a tool call needs a toolCallName`);
|
|
4166
|
+
return this.closeChunk();
|
|
4167
|
+
}
|
|
4168
|
+
events.push(...this.closeChunk(), {
|
|
4169
|
+
type: EventType.TOOL_CALL_START,
|
|
4170
|
+
toolCallId: id,
|
|
4171
|
+
toolCallName: chunk.toolCallName,
|
|
4172
|
+
parentMessageId: chunk.parentMessageId,
|
|
4173
|
+
metadata: chunk.metadata,
|
|
4174
|
+
timestamp
|
|
4175
|
+
});
|
|
4176
|
+
this.openChunk = {
|
|
4177
|
+
family: "TOOL_CALL",
|
|
4178
|
+
id
|
|
4179
|
+
};
|
|
4180
|
+
}
|
|
4181
|
+
if (chunk.delta !== void 0 || chunk.metadata !== void 0) events.push({
|
|
4182
|
+
type: EventType.TOOL_CALL_ARGS,
|
|
4183
|
+
toolCallId: id,
|
|
4184
|
+
delta: chunk.delta ?? "",
|
|
4185
|
+
...chunk.metadata !== void 0 ? { metadata: chunk.metadata } : {},
|
|
4186
|
+
timestamp
|
|
4187
|
+
});
|
|
4188
|
+
return events;
|
|
4189
|
+
}
|
|
4190
|
+
case "REASONING_MESSAGE_CHUNK": {
|
|
4191
|
+
const id = this.chunkStreamId("REASONING_MESSAGE", chunk.messageId, chunk.type);
|
|
4192
|
+
if (id === void 0) return this.closeChunk();
|
|
4193
|
+
const events = [];
|
|
4194
|
+
if (open?.family !== "REASONING_MESSAGE" || open.id !== id) {
|
|
4195
|
+
events.push(...this.closeChunk(), {
|
|
4196
|
+
type: EventType.REASONING_MESSAGE_START,
|
|
4197
|
+
messageId: id,
|
|
4198
|
+
role: "reasoning",
|
|
4199
|
+
timestamp
|
|
4200
|
+
});
|
|
4201
|
+
this.openChunk = {
|
|
4202
|
+
family: "REASONING_MESSAGE",
|
|
4203
|
+
id
|
|
4204
|
+
};
|
|
4205
|
+
}
|
|
4206
|
+
if (chunk.delta !== void 0 || chunk.metadata !== void 0) events.push({
|
|
4207
|
+
type: EventType.REASONING_MESSAGE_CONTENT,
|
|
4208
|
+
messageId: id,
|
|
4209
|
+
delta: chunk.delta ?? "",
|
|
4210
|
+
...chunk.metadata !== void 0 ? { metadata: chunk.metadata } : {},
|
|
4211
|
+
timestamp
|
|
4212
|
+
});
|
|
4213
|
+
return events;
|
|
4214
|
+
}
|
|
4215
|
+
default: {
|
|
4216
|
+
const events = open && !CHUNK_PASS_THROUGH.has(chunk.type) ? this.closeChunk() : [];
|
|
4217
|
+
if (RUN_LEVEL_CLOSES_LANES.has(chunk.type)) this.closeChildChunkLanes();
|
|
4218
|
+
return [...events, chunk];
|
|
4219
|
+
}
|
|
4220
|
+
}
|
|
4221
|
+
}
|
|
4222
|
+
/** Synthesize *_END on every nested shorthand lane and apply those events there. */
|
|
4223
|
+
closeChildChunkLanes() {
|
|
4224
|
+
for (const child of this.childProcessors.values()) {
|
|
4225
|
+
for (const event of child.closeChunk()) child.dispatchChunk(event);
|
|
4226
|
+
child.closeChildChunkLanes();
|
|
4227
|
+
}
|
|
4228
|
+
}
|
|
4229
|
+
/**
|
|
4230
|
+
* The child an untagged chunk with no id continues: the only child whose
|
|
4231
|
+
* subtree has an open chunk stream of its kind, when this processor has
|
|
4232
|
+
* none. The AG-UI client resolves a chunk that tags only its opener the
|
|
4233
|
+
* same way.
|
|
4234
|
+
*/
|
|
4235
|
+
childContinuing(chunk) {
|
|
4236
|
+
let family;
|
|
4237
|
+
if (chunk.type === "TEXT_MESSAGE_CHUNK" && chunk.messageId === void 0) family = "TEXT_MESSAGE";
|
|
4238
|
+
else if (chunk.type === "REASONING_MESSAGE_CHUNK" && chunk.messageId === void 0) family = "REASONING_MESSAGE";
|
|
4239
|
+
else if (chunk.type === "TOOL_CALL_CHUNK" && chunk.toolCallId === void 0) family = "TOOL_CALL";
|
|
4240
|
+
else return;
|
|
4241
|
+
if (this.openChunkCount(family) !== 1) return void 0;
|
|
4242
|
+
for (const [id, child] of this.childProcessors) if (child.openChunkCount(family) === 1) return id;
|
|
4243
|
+
}
|
|
4244
|
+
/**
|
|
4245
|
+
* How many open chunk streams of a kind this processor and all its nested
|
|
4246
|
+
* children hold.
|
|
4247
|
+
*/
|
|
4248
|
+
openChunkCount(family) {
|
|
4249
|
+
let count = this.openChunk?.family === family ? 1 : 0;
|
|
4250
|
+
for (const child of this.childProcessors.values()) count += child.openChunkCount(family);
|
|
4251
|
+
return count;
|
|
4252
|
+
}
|
|
4253
|
+
/**
|
|
4254
|
+
* The id a chunk opens or continues. A chunk with no id continues. If it
|
|
4255
|
+
* continues nothing, the caller drops it and closes the open stream, so a
|
|
4256
|
+
* later chunk with no id cannot continue that stream either.
|
|
4257
|
+
*/
|
|
4258
|
+
chunkStreamId(family, id, type) {
|
|
4259
|
+
if (id !== void 0) return id;
|
|
4260
|
+
if (this.openChunk?.family === family) return this.openChunk.id;
|
|
4261
|
+
console.warn(`[StreamProcessor] Dropped ${type}: it has no id and continues nothing`);
|
|
4262
|
+
}
|
|
4263
|
+
closeChunk() {
|
|
4264
|
+
const open = this.openChunk;
|
|
4265
|
+
if (!open) return [];
|
|
4266
|
+
this.openChunk = null;
|
|
4267
|
+
const timestamp = Date.now();
|
|
4268
|
+
switch (open.family) {
|
|
4269
|
+
case "TEXT_MESSAGE": return [{
|
|
4270
|
+
type: EventType.TEXT_MESSAGE_END,
|
|
4271
|
+
messageId: open.id,
|
|
4272
|
+
timestamp
|
|
4273
|
+
}];
|
|
4274
|
+
case "TOOL_CALL": return [{
|
|
4275
|
+
type: EventType.TOOL_CALL_END,
|
|
4276
|
+
toolCallId: open.id,
|
|
4277
|
+
timestamp
|
|
4278
|
+
}];
|
|
4279
|
+
case "REASONING_MESSAGE": return [{
|
|
4280
|
+
type: EventType.REASONING_MESSAGE_END,
|
|
4281
|
+
messageId: open.id,
|
|
4282
|
+
timestamp
|
|
4283
|
+
}];
|
|
3293
4284
|
}
|
|
3294
4285
|
}
|
|
3295
4286
|
/**
|
|
@@ -3366,7 +4357,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3366
4357
|
* MESSAGES_SNAPSHOT) but whose transient state was cleared. In that case we
|
|
3367
4358
|
* hydrate state from the existing message rather than creating a duplicate.
|
|
3368
4359
|
*/
|
|
3369
|
-
ensureAssistantMessage(preferredId) {
|
|
4360
|
+
ensureAssistantMessage(preferredId, fallbackToActive = true) {
|
|
3370
4361
|
if (preferredId) {
|
|
3371
4362
|
const state = this.getMessageState(preferredId);
|
|
3372
4363
|
if (state) {
|
|
@@ -3377,7 +4368,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3377
4368
|
};
|
|
3378
4369
|
}
|
|
3379
4370
|
}
|
|
3380
|
-
const activeId = this.getActiveAssistantMessageId();
|
|
4371
|
+
const activeId = fallbackToActive ? this.getActiveAssistantMessageId() : null;
|
|
3381
4372
|
if (activeId) {
|
|
3382
4373
|
const state = this.getMessageState(activeId);
|
|
3383
4374
|
if (state) {
|
|
@@ -3390,7 +4381,8 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3390
4381
|
}
|
|
3391
4382
|
if (preferredId) {
|
|
3392
4383
|
const existingMsg = this.messages.find((m) => m.id === preferredId);
|
|
3393
|
-
if (existingMsg)
|
|
4384
|
+
if (existingMsg?.role === "activity") preferredId = void 0;
|
|
4385
|
+
else if (existingMsg) {
|
|
3394
4386
|
const state = this.createMessageState(preferredId, existingMsg.role);
|
|
3395
4387
|
this.activeMessageIds.add(preferredId);
|
|
3396
4388
|
const lastPart = existingMsg.parts.length > 0 ? existingMsg.parts[existingMsg.parts.length - 1] : null;
|
|
@@ -3415,7 +4407,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3415
4407
|
this.messages = [...this.messages, assistantMessage];
|
|
3416
4408
|
const state = this.createMessageState(id, "assistant");
|
|
3417
4409
|
this.activeMessageIds.add(id);
|
|
3418
|
-
this.pendingManualMessageId = id;
|
|
4410
|
+
if (!preferredId) this.pendingManualMessageId = id;
|
|
3419
4411
|
this.events.onStreamStart?.();
|
|
3420
4412
|
this.emitMessagesChange();
|
|
3421
4413
|
return {
|
|
@@ -3585,7 +4577,9 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3585
4577
|
/**
|
|
3586
4578
|
* Send a child's chunk to that child's processor, so the card keeps text,
|
|
3587
4579
|
* reasoning, tool calls, results, and nested children. A tool event without
|
|
3588
|
-
* `subagentRunId` follows its `TOOL_CALL_START`.
|
|
4580
|
+
* `subagentRunId` follows its `TOOL_CALL_START` or `TOOL_CALL_CHUNK`. An
|
|
4581
|
+
* untagged chunk with no id follows a child's open chunk stream (see
|
|
4582
|
+
* childContinuing()).
|
|
3589
4583
|
*/
|
|
3590
4584
|
routeToChild(chunk) {
|
|
3591
4585
|
let id;
|
|
@@ -3595,6 +4589,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3595
4589
|
id = chunk.subagentRunId;
|
|
3596
4590
|
} else if ("subagentRunId" in chunk && chunk.subagentRunId) id = chunk.subagentRunId;
|
|
3597
4591
|
else if ("toolCallId" in chunk && typeof chunk.toolCallId === "string") id = this.childToolCalls.get(chunk.toolCallId);
|
|
4592
|
+
else id = this.childContinuing(chunk);
|
|
3598
4593
|
if (id === void 0) return false;
|
|
3599
4594
|
const owner = this.childOwning(id);
|
|
3600
4595
|
if (owner === void 0) {
|
|
@@ -3603,34 +4598,45 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3603
4598
|
return true;
|
|
3604
4599
|
}
|
|
3605
4600
|
if (this.findSubagentPart(owner)?.part.subagent.status === "error") return true;
|
|
3606
|
-
if (chunk.type === "TOOL_CALL_START") this.childToolCalls.set(chunk.toolCallId, owner);
|
|
4601
|
+
if ((chunk.type === "TOOL_CALL_START" || chunk.type === "TOOL_CALL_CHUNK") && chunk.toolCallId !== void 0) this.childToolCalls.set(chunk.toolCallId, owner);
|
|
3607
4602
|
this.updateChild(owner, (child) => child.processChunk(chunk));
|
|
3608
4603
|
return true;
|
|
3609
4604
|
}
|
|
4605
|
+
renameMessage(fromId, toId) {
|
|
4606
|
+
this.messages = this.messages.map((msg) => msg.id === fromId ? {
|
|
4607
|
+
...msg,
|
|
4608
|
+
id: toId
|
|
4609
|
+
} : msg);
|
|
4610
|
+
const existingState = this.messageStates.get(fromId);
|
|
4611
|
+
if (existingState) {
|
|
4612
|
+
existingState.id = toId;
|
|
4613
|
+
this.messageStates.delete(fromId);
|
|
4614
|
+
this.messageStates.set(toId, existingState);
|
|
4615
|
+
}
|
|
4616
|
+
this.activeMessageIds.delete(fromId);
|
|
4617
|
+
this.activeMessageIds.add(toId);
|
|
4618
|
+
for (const [toolCallId, mappedMessageId] of this.toolCallToMessage) if (mappedMessageId === fromId) this.toolCallToMessage.set(toolCallId, toId);
|
|
4619
|
+
if (this.structuredMessageIds.delete(fromId)) this.structuredMessageIds.add(toId);
|
|
4620
|
+
const batch = this.structuredOutputUpdateBatches.get(fromId);
|
|
4621
|
+
if (batch) {
|
|
4622
|
+
this.structuredOutputUpdateBatches.delete(fromId);
|
|
4623
|
+
this.structuredOutputUpdateBatches.set(toId, batch);
|
|
4624
|
+
}
|
|
4625
|
+
}
|
|
3610
4626
|
/**
|
|
3611
4627
|
* Handle TEXT_MESSAGE_START event
|
|
3612
4628
|
*/
|
|
3613
4629
|
handleTextMessageStartEvent(chunk) {
|
|
3614
4630
|
const { messageId, role } = chunk;
|
|
4631
|
+
if (this.messages.some((m) => m.id === messageId && m.role === "activity")) {
|
|
4632
|
+
console.warn(`TEXT_MESSAGE_START: Dropped text for '${messageId}', the id of an activity message`);
|
|
4633
|
+
return;
|
|
4634
|
+
}
|
|
3615
4635
|
const uiRole = role === "user" || role === "system" ? role : "assistant";
|
|
3616
4636
|
if (this.pendingManualMessageId) {
|
|
3617
4637
|
const pendingId = this.pendingManualMessageId;
|
|
3618
4638
|
this.pendingManualMessageId = null;
|
|
3619
|
-
if (pendingId !== messageId)
|
|
3620
|
-
this.messages = this.messages.map((msg) => msg.id === pendingId ? {
|
|
3621
|
-
...msg,
|
|
3622
|
-
id: messageId
|
|
3623
|
-
} : msg);
|
|
3624
|
-
const existingState = this.messageStates.get(pendingId);
|
|
3625
|
-
if (existingState) {
|
|
3626
|
-
existingState.id = messageId;
|
|
3627
|
-
this.messageStates.delete(pendingId);
|
|
3628
|
-
this.messageStates.set(messageId, existingState);
|
|
3629
|
-
}
|
|
3630
|
-
this.activeMessageIds.delete(pendingId);
|
|
3631
|
-
this.activeMessageIds.add(messageId);
|
|
3632
|
-
for (const [toolCallId, mappedMessageId] of this.toolCallToMessage) if (mappedMessageId === pendingId) this.toolCallToMessage.set(toolCallId, messageId);
|
|
3633
|
-
}
|
|
4639
|
+
if (pendingId !== messageId) this.renameMessage(pendingId, messageId);
|
|
3634
4640
|
let pendingState = this.messageStates.get(messageId);
|
|
3635
4641
|
if (!pendingState) {
|
|
3636
4642
|
pendingState = this.createMessageState(messageId, uiRole);
|
|
@@ -3641,6 +4647,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3641
4647
|
pendingState.lastEmittedText = "";
|
|
3642
4648
|
pendingState.hasToolCallsSinceTextStart = false;
|
|
3643
4649
|
}
|
|
4650
|
+
this.applySenderName(messageId, chunk.name);
|
|
3644
4651
|
this.mergeMessageMetadata(messageId, chunk.metadata);
|
|
3645
4652
|
this.emitMessagesChange();
|
|
3646
4653
|
return;
|
|
@@ -3655,6 +4662,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3655
4662
|
existingState.lastEmittedText = "";
|
|
3656
4663
|
existingState.hasToolCallsSinceTextStart = false;
|
|
3657
4664
|
}
|
|
4665
|
+
this.applySenderName(messageId, chunk.name);
|
|
3658
4666
|
this.mergeMessageMetadata(messageId, chunk.metadata);
|
|
3659
4667
|
return;
|
|
3660
4668
|
}
|
|
@@ -3667,10 +4675,18 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3667
4675
|
this.messages = [...this.messages, newMessage];
|
|
3668
4676
|
this.createMessageState(messageId, uiRole);
|
|
3669
4677
|
this.activeMessageIds.add(messageId);
|
|
4678
|
+
this.applySenderName(messageId, chunk.name);
|
|
3670
4679
|
this.mergeMessageMetadata(messageId, chunk.metadata);
|
|
3671
4680
|
this.events.onStreamStart?.();
|
|
3672
4681
|
this.emitMessagesChange();
|
|
3673
4682
|
}
|
|
4683
|
+
applySenderName(messageId, name) {
|
|
4684
|
+
if (name === void 0) return;
|
|
4685
|
+
this.messages = this.messages.map((msg) => msg.id === messageId ? {
|
|
4686
|
+
...msg,
|
|
4687
|
+
name
|
|
4688
|
+
} : msg);
|
|
4689
|
+
}
|
|
3674
4690
|
/**
|
|
3675
4691
|
* Handle TEXT_MESSAGE_END event
|
|
3676
4692
|
*/
|
|
@@ -3700,10 +4716,31 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3700
4716
|
metadata: prev.metadata
|
|
3701
4717
|
};
|
|
3702
4718
|
});
|
|
3703
|
-
this.messages = this.attachSnapshotSubagents(reconciled, top, groups, prevMessages);
|
|
4719
|
+
this.messages = this.mergeOmittedActivity(prevMessages, this.attachSnapshotSubagents(reconciled, top, groups, prevMessages));
|
|
3704
4720
|
this.emitMessagesChange();
|
|
3705
4721
|
}
|
|
3706
4722
|
/**
|
|
4723
|
+
* Snapshot is authoritative for user/assistant/system. Activity omitted
|
|
4724
|
+
* from the snapshot (TanStack chat() still builds snapshots from
|
|
4725
|
+
* ModelMessage[]) stays in the transcript so persist/reconnect cannot
|
|
4726
|
+
* wipe it. Snapshot activity rows win when the id is present.
|
|
4727
|
+
*
|
|
4728
|
+
* Keep every snapshot row, including two assistants that share an id
|
|
4729
|
+
* (agent-loop retry reuses `currentMessageId`). A Map keyed by id would
|
|
4730
|
+
* drop the earlier error tool-call (#1192).
|
|
4731
|
+
*/
|
|
4732
|
+
mergeOmittedActivity(prevMessages, snapshot) {
|
|
4733
|
+
const snapshotIds = new Set(snapshot.map((msg) => msg.id));
|
|
4734
|
+
const omitted = prevMessages.filter((msg) => msg.role === "activity" && !snapshotIds.has(msg.id));
|
|
4735
|
+
if (omitted.length === 0) return snapshot;
|
|
4736
|
+
const out = [...snapshot];
|
|
4737
|
+
for (const activity of omitted) {
|
|
4738
|
+
const prevIndex = prevMessages.findIndex((msg) => msg.id === activity.id);
|
|
4739
|
+
out.splice(Math.min(Math.max(prevIndex, 0), out.length), 0, activity);
|
|
4740
|
+
}
|
|
4741
|
+
return out;
|
|
4742
|
+
}
|
|
4743
|
+
/**
|
|
3707
4744
|
* Put subagent cards back on a snapshot. Child wire messages (tagged with
|
|
3708
4745
|
* `subagentRunId`) become a card on the nearest assistant message before
|
|
3709
4746
|
* them, or a new assistant message when there is none. A card that the
|
|
@@ -3923,6 +4960,10 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3923
4960
|
* @see docs/chat-architecture.md#uimessage-part-ordering-invariants — Replace vs. push logic
|
|
3924
4961
|
*/
|
|
3925
4962
|
handleTextMessageContentEvent(chunk) {
|
|
4963
|
+
if (this.messages.some((m) => m.id === chunk.messageId && m.role === "activity")) {
|
|
4964
|
+
console.warn(`TEXT_MESSAGE_CONTENT: Dropped text for '${chunk.messageId}', the id of an activity message`);
|
|
4965
|
+
return;
|
|
4966
|
+
}
|
|
3926
4967
|
const { messageId, state } = this.ensureAssistantMessage(chunk.messageId);
|
|
3927
4968
|
this.mergeMessageMetadata(messageId, chunk.metadata);
|
|
3928
4969
|
if (this.structuredMessageIds.has(messageId)) {
|
|
@@ -3966,8 +5007,25 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3966
5007
|
* @see docs/chat-architecture.md#adapter-contract — Ordering requirements
|
|
3967
5008
|
*/
|
|
3968
5009
|
handleToolCallStartEvent(chunk) {
|
|
5010
|
+
const pendingId = this.pendingManualMessageId;
|
|
5011
|
+
const parentId = chunk.parentMessageId;
|
|
5012
|
+
if (pendingId && parentId && parentId !== pendingId) {
|
|
5013
|
+
const parent = this.messages.find((m) => m.id === parentId);
|
|
5014
|
+
const placeholder = this.messages.find((m) => m.id === pendingId);
|
|
5015
|
+
if (!parent) {
|
|
5016
|
+
this.pendingManualMessageId = null;
|
|
5017
|
+
this.renameMessage(pendingId, parentId);
|
|
5018
|
+
} else if (parent.role === "assistant" && placeholder) {
|
|
5019
|
+
this.pendingManualMessageId = null;
|
|
5020
|
+
this.messages = this.messages.filter((m) => m.id !== pendingId).map((m) => m.id === parentId ? {
|
|
5021
|
+
...m,
|
|
5022
|
+
parts: [...m.parts, ...placeholder.parts]
|
|
5023
|
+
} : m);
|
|
5024
|
+
this.renameMessage(pendingId, parentId);
|
|
5025
|
+
}
|
|
5026
|
+
}
|
|
3969
5027
|
const targetMessageId = chunk.parentMessageId ?? this.getActiveAssistantMessageId();
|
|
3970
|
-
const { messageId, state } = this.ensureAssistantMessage(targetMessageId ?? void 0);
|
|
5028
|
+
const { messageId, state } = this.ensureAssistantMessage(targetMessageId ?? void 0, chunk.parentMessageId === void 0);
|
|
3971
5029
|
state.hasToolCallsSinceTextStart = true;
|
|
3972
5030
|
const toolCallId = chunk.toolCallId;
|
|
3973
5031
|
if (!state.toolCalls.get(toolCallId)) {
|
|
@@ -3985,6 +5043,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3985
5043
|
};
|
|
3986
5044
|
state.toolCalls.set(toolCallId, newToolCall);
|
|
3987
5045
|
state.toolCallOrder.push(toolCallId);
|
|
5046
|
+
this.runToolCallIds.push(toolCallId);
|
|
3988
5047
|
this.toolCallToMessage.set(toolCallId, messageId);
|
|
3989
5048
|
this.messages = updateToolCallPart(this.messages, messageId, {
|
|
3990
5049
|
id: chunk.toolCallId,
|
|
@@ -4018,6 +5077,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4018
5077
|
const existingToolCall = state.toolCalls.get(toolCallId);
|
|
4019
5078
|
if (!existingToolCall) return;
|
|
4020
5079
|
const wasAwaitingInput = existingToolCall.state === "awaiting-input";
|
|
5080
|
+
if (chunk.metadata !== void 0) existingToolCall.metadata = mergeMetadata(existingToolCall.metadata, chunk.metadata);
|
|
4021
5081
|
existingToolCall.arguments += chunk.delta || "";
|
|
4022
5082
|
if (wasAwaitingInput && chunk.delta) existingToolCall.state = "input-streaming";
|
|
4023
5083
|
existingToolCall.parsedArguments = this.jsonParser.parse(existingToolCall.arguments);
|
|
@@ -4025,7 +5085,8 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4025
5085
|
id: existingToolCall.id,
|
|
4026
5086
|
name: existingToolCall.name,
|
|
4027
5087
|
arguments: existingToolCall.arguments,
|
|
4028
|
-
state: existingToolCall.state
|
|
5088
|
+
state: existingToolCall.state,
|
|
5089
|
+
...existingToolCall.metadata !== void 0 && { metadata: existingToolCall.metadata }
|
|
4029
5090
|
});
|
|
4030
5091
|
this.emitMessagesChange();
|
|
4031
5092
|
this.events.onToolCallStateChange?.(messageId, existingToolCall.id, existingToolCall.state, existingToolCall.arguments);
|
|
@@ -4102,6 +5163,10 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4102
5163
|
* runs are still active before finalizing.
|
|
4103
5164
|
*/
|
|
4104
5165
|
handleRunStartedEvent(chunk) {
|
|
5166
|
+
if (this.activeRuns.size === 0) {
|
|
5167
|
+
this.runToolCallIds = [];
|
|
5168
|
+
this.toolCallsSentToClient.clear();
|
|
5169
|
+
}
|
|
4105
5170
|
this.activeRuns.add(chunk.runId);
|
|
4106
5171
|
}
|
|
4107
5172
|
/**
|
|
@@ -4122,11 +5187,39 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4122
5187
|
if (this.activeRuns.size === 0) {
|
|
4123
5188
|
this.completeAllToolCalls();
|
|
4124
5189
|
if (this.finishReason === "tool_calls" && chunk.outcome?.type !== "interrupt") return;
|
|
5190
|
+
if (!chunk.outcome || chunk.outcome.type === "success") this.handlePendingToolCalls(chunk.outcome?.pendingToolCallIds);
|
|
4125
5191
|
this.isDone = true;
|
|
4126
5192
|
this.finalizeStream();
|
|
4127
5193
|
}
|
|
4128
5194
|
}
|
|
4129
5195
|
/**
|
|
5196
|
+
* AG-UI ends a run that calls a frontend tool with a success outcome and
|
|
5197
|
+
* leaves the call unanswered. The pending calls are the ones named in
|
|
5198
|
+
* `pendingToolCallIds` that this run started, or else every call this run
|
|
5199
|
+
* started that has no result. Fire onToolCall once for each, so the client
|
|
5200
|
+
* runs it and continues.
|
|
5201
|
+
*/
|
|
5202
|
+
handlePendingToolCalls(pendingToolCallIds) {
|
|
5203
|
+
const ids = pendingToolCallIds?.length ? pendingToolCallIds.filter((id) => this.runToolCallIds.includes(id)) : this.runToolCallIds;
|
|
5204
|
+
const parts = this.messages.flatMap((msg) => msg.parts ?? []);
|
|
5205
|
+
for (const toolCallId of ids) {
|
|
5206
|
+
if (this.toolCallsSentToClient.has(toolCallId)) continue;
|
|
5207
|
+
const part = parts.find((p) => p.type === "tool-call" && p.id === toolCallId);
|
|
5208
|
+
if (!part || isProviderExecutedToolCall(part) || part.output !== void 0 || parts.some((p) => p.type === "tool-result" && p.toolCallId === toolCallId) || this.isToolCallPartTerminal(toolCallId) || this.isToolCallPartAwaitingUserAction(toolCallId)) continue;
|
|
5209
|
+
const input = part.input ?? parseToolArguments(part.arguments);
|
|
5210
|
+
if (input === void 0) {
|
|
5211
|
+
console.warn(`[StreamProcessor] Did not run tool call ${toolCallId}: the arguments of ${part.name} are not complete JSON`);
|
|
5212
|
+
continue;
|
|
5213
|
+
}
|
|
5214
|
+
this.toolCallsSentToClient.add(toolCallId);
|
|
5215
|
+
this.events.onToolCall?.({
|
|
5216
|
+
toolCallId,
|
|
5217
|
+
toolName: part.name,
|
|
5218
|
+
input
|
|
5219
|
+
});
|
|
5220
|
+
}
|
|
5221
|
+
}
|
|
5222
|
+
/**
|
|
4130
5223
|
* Apply interrupt state to tool-call parts, then fire the client events.
|
|
4131
5224
|
* A child's interrupt updates the child's card. `emit` is false there, so
|
|
4132
5225
|
* the events fire once, from the top processor.
|
|
@@ -4168,6 +5261,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4168
5261
|
}
|
|
4169
5262
|
if (kind === "client_tool" || interrupt.reason === "client_tool_input") {
|
|
4170
5263
|
if (hasGeneric || !emit) continue;
|
|
5264
|
+
this.toolCallsSentToClient.add(toolCallId);
|
|
4171
5265
|
this.events.onToolCall?.({
|
|
4172
5266
|
toolCallId,
|
|
4173
5267
|
toolName,
|
|
@@ -4228,6 +5322,24 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4228
5322
|
this.pendingThinkingStepId = stepId;
|
|
4229
5323
|
}
|
|
4230
5324
|
/**
|
|
5325
|
+
* Handle ACTIVITY_SNAPSHOT. Creates or replaces a frontend-only activity
|
|
5326
|
+
* message. Does not create MessageStreamState (that path feeds
|
|
5327
|
+
* ProcessorResult.content).
|
|
5328
|
+
*/
|
|
5329
|
+
handleActivitySnapshotEvent(chunk) {
|
|
5330
|
+
this.messages = applyActivitySnapshotToUIMessages(this.messages, chunk);
|
|
5331
|
+
this.emitMessagesChange();
|
|
5332
|
+
}
|
|
5333
|
+
/**
|
|
5334
|
+
* Handle ACTIVITY_DELTA. Applies RFC 6902 patches to an existing activity
|
|
5335
|
+
* `content`. Missing or non-activity ids are no-ops. Patch failure leaves
|
|
5336
|
+
* the previous content in place.
|
|
5337
|
+
*/
|
|
5338
|
+
handleActivityDeltaEvent(chunk) {
|
|
5339
|
+
this.messages = applyActivityDeltaToUIMessages(this.messages, chunk);
|
|
5340
|
+
this.emitMessagesChange();
|
|
5341
|
+
}
|
|
5342
|
+
/**
|
|
4231
5343
|
* Handle STEP_FINISHED event.
|
|
4232
5344
|
*
|
|
4233
5345
|
* Thinking *content* comes from REASONING_MESSAGE_CONTENT, not STEP_FINISHED.
|
|
@@ -4256,6 +5368,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4256
5368
|
*/
|
|
4257
5369
|
handleReasoningMessageContentEvent(chunk) {
|
|
4258
5370
|
const { messageId, state } = this.ensureAssistantMessage(this.getActiveAssistantMessageId() ?? void 0);
|
|
5371
|
+
this.mergeMessageMetadata(messageId, chunk.metadata);
|
|
4259
5372
|
state.hasSeenReasoningEvents = true;
|
|
4260
5373
|
const delta = chunk.delta || "";
|
|
4261
5374
|
this.consumePendingThinkingStep(state);
|
|
@@ -4368,6 +5481,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4368
5481
|
}
|
|
4369
5482
|
if (chunk.name === "tool-input-available" && chunk.value) {
|
|
4370
5483
|
const { toolCallId, toolName, input } = chunk.value;
|
|
5484
|
+
this.toolCallsSentToClient.add(toolCallId);
|
|
4371
5485
|
this.events.onToolCall?.({
|
|
4372
5486
|
toolCallId,
|
|
4373
5487
|
toolName,
|
|
@@ -4546,6 +5660,8 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4546
5660
|
*/
|
|
4547
5661
|
finalizeStream() {
|
|
4548
5662
|
this.isDone = true;
|
|
5663
|
+
for (const event of this.closeChunk()) this.dispatchChunk(event);
|
|
5664
|
+
this.closeChildChunkLanes();
|
|
4549
5665
|
let lastAssistantMessage;
|
|
4550
5666
|
for (const messageId of this.activeMessageIds) {
|
|
4551
5667
|
const state = this.getMessageState(messageId);
|
|
@@ -4663,6 +5779,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4663
5779
|
this.structuredOutputUpdateBatches.clear();
|
|
4664
5780
|
this.pendingManualMessageId = null;
|
|
4665
5781
|
this.pendingThinkingStepId = null;
|
|
5782
|
+
this.openChunk = null;
|
|
4666
5783
|
this.finishReason = null;
|
|
4667
5784
|
this.hasError = false;
|
|
4668
5785
|
this.isDone = false;
|
|
@@ -4702,14 +5819,14 @@ function createReplayStream(recording) {
|
|
|
4702
5819
|
} };
|
|
4703
5820
|
}
|
|
4704
5821
|
//#endregion
|
|
4705
|
-
//#region node_modules/.
|
|
5822
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/byok/providers.js
|
|
4706
5823
|
/** `[a-z][a-z0-9-]{0,63}` — lowercase, no underscores, max 64 chars. */
|
|
4707
5824
|
var BYOK_PROVIDER_ID_PATTERN = /^[a-z][a-z0-9-]{0,63}$/;
|
|
4708
5825
|
function isProviderId(value) {
|
|
4709
5826
|
return typeof value === "string" && BYOK_PROVIDER_ID_PATTERN.test(value);
|
|
4710
5827
|
}
|
|
4711
5828
|
//#endregion
|
|
4712
|
-
//#region node_modules/.
|
|
5829
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/byok/missing.js
|
|
4713
5830
|
function isByokMissingBody(value) {
|
|
4714
5831
|
if (typeof value !== "object" || value === null) return false;
|
|
4715
5832
|
if (!("error" in value)) return false;
|
|
@@ -4722,7 +5839,7 @@ function isByokMissingBody(value) {
|
|
|
4722
5839
|
return true;
|
|
4723
5840
|
}
|
|
4724
5841
|
//#endregion
|
|
4725
|
-
//#region node_modules/.
|
|
5842
|
+
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/byok/errors.js
|
|
4726
5843
|
var ByokMissingError = class extends Error {
|
|
4727
5844
|
provider;
|
|
4728
5845
|
constructor(provider) {
|
|
@@ -4748,7 +5865,7 @@ var ByokUnresolvedProviderError = class extends Error {
|
|
|
4748
5865
|
}
|
|
4749
5866
|
};
|
|
4750
5867
|
//#endregion
|
|
4751
|
-
//#region node_modules/.
|
|
5868
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@0.39.2+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/connection-adapters.js
|
|
4752
5869
|
/**
|
|
4753
5870
|
* Associates connect-wrapped chunks with the run they were produced under.
|
|
4754
5871
|
* Content events (TEXT_MESSAGE_CONTENT, TOOL_CALL_*, …) carry no `runId` of
|
|
@@ -4941,6 +6058,9 @@ async function* readStreamLines(reader, abortSignal) {
|
|
|
4941
6058
|
buffer += decoder.decode();
|
|
4942
6059
|
if (buffer.trim() && !abortSignal?.aborted) throw new StreamTruncatedError();
|
|
4943
6060
|
} finally {
|
|
6061
|
+
try {
|
|
6062
|
+
reader.cancel().catch(() => {});
|
|
6063
|
+
} catch {}
|
|
4944
6064
|
reader.releaseLock();
|
|
4945
6065
|
}
|
|
4946
6066
|
}
|
|
@@ -5443,7 +6563,7 @@ async function* abortableIterable(iterable, signal) {
|
|
|
5443
6563
|
}
|
|
5444
6564
|
}
|
|
5445
6565
|
//#endregion
|
|
5446
|
-
//#region node_modules/.
|
|
6566
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@0.39.2+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/interrupt-manager.js
|
|
5447
6567
|
function isClientOwnedInterrupt(item) {
|
|
5448
6568
|
return item.resumable;
|
|
5449
6569
|
}
|
|
@@ -6385,7 +7505,7 @@ var InterruptManager = class {
|
|
|
6385
7505
|
}
|
|
6386
7506
|
};
|
|
6387
7507
|
//#endregion
|
|
6388
|
-
//#region node_modules/.
|
|
7508
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@0.39.2+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/byok/client.js
|
|
6389
7509
|
var registeredProviderIds = /* @__PURE__ */ new WeakMap();
|
|
6390
7510
|
/**
|
|
6391
7511
|
* Provider to stamp when the caller did not pass a slug.
|
|
@@ -6398,7 +7518,7 @@ function byokFallbackProviderId(byok) {
|
|
|
6398
7518
|
if (registered.length === 1) return registered[0];
|
|
6399
7519
|
}
|
|
6400
7520
|
//#endregion
|
|
6401
|
-
//#region node_modules/.
|
|
7521
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@0.39.2+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/byok/resolve.js
|
|
6402
7522
|
function resolveByokProviderId(byokProvider, ...candidates) {
|
|
6403
7523
|
const fromFn = byokProvider?.();
|
|
6404
7524
|
if (isProviderId(fromFn)) return fromFn;
|
|
@@ -6414,7 +7534,7 @@ async function prepareResolvedByokHeaders(byok, provider) {
|
|
|
6414
7534
|
return byok.headers(provider);
|
|
6415
7535
|
}
|
|
6416
7536
|
//#endregion
|
|
6417
|
-
//#region node_modules/.
|
|
7537
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@0.39.2+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/events.js
|
|
6418
7538
|
/**
|
|
6419
7539
|
* Abstract base class for ChatClient event emission
|
|
6420
7540
|
*/
|
|
@@ -6588,7 +7708,7 @@ var ChatClientEventEmitter = class {
|
|
|
6588
7708
|
}
|
|
6589
7709
|
};
|
|
6590
7710
|
//#endregion
|
|
6591
|
-
//#region node_modules/.
|
|
7711
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@0.39.2+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/devtools-noop.js
|
|
6592
7712
|
var NoOpChatClientEventEmitter = class extends ChatClientEventEmitter {
|
|
6593
7713
|
emitEvent() {}
|
|
6594
7714
|
};
|
|
@@ -6633,7 +7753,7 @@ var NoOpChatDevtoolsBridge = class {
|
|
|
6633
7753
|
};
|
|
6634
7754
|
var createNoOpChatDevtoolsBridge = (options) => new NoOpChatDevtoolsBridge(options);
|
|
6635
7755
|
//#endregion
|
|
6636
|
-
//#region node_modules/.
|
|
7756
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@0.39.2+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/client-persistor.js
|
|
6637
7757
|
/** Normalize a raw `getItem` result (legacy bare array or combined record). */
|
|
6638
7758
|
function normalizePersistedState(raw) {
|
|
6639
7759
|
if (Array.isArray(raw)) return { messages: raw };
|
|
@@ -6732,12 +7852,13 @@ var ChatPersistor = class {
|
|
|
6732
7852
|
}
|
|
6733
7853
|
/**
|
|
6734
7854
|
* Apply state from an async `getItem` once it resolves, unless the message
|
|
6735
|
-
* list has already changed since hydration began.
|
|
7855
|
+
* list has already changed since hydration began. Returns a promise that
|
|
7856
|
+
* settles (never rejects) when it is done, or `undefined` for sync state.
|
|
6736
7857
|
*/
|
|
6737
7858
|
hydrateAsync(persistedState) {
|
|
6738
7859
|
if (!(persistedState instanceof Promise)) return;
|
|
6739
7860
|
const hydrationGeneration = this.messagesGeneration;
|
|
6740
|
-
persistedState.then((state) => {
|
|
7861
|
+
return persistedState.then((state) => {
|
|
6741
7862
|
if (!state || this.messagesGeneration !== hydrationGeneration) return;
|
|
6742
7863
|
this.lastResume = state.resume ?? null;
|
|
6743
7864
|
this.lastMessages = state.messages;
|
|
@@ -6893,11 +8014,11 @@ var ChatPersistor = class {
|
|
|
6893
8014
|
isRunlessChunkFromIgnoredRun(chunk) {
|
|
6894
8015
|
if (getChunkRunId$1(chunk) || !this.currentRunlessRunId) return false;
|
|
6895
8016
|
if (!this.ignoredActiveRunIds.has(this.currentRunlessRunId) && !this.clearedRunIds.has(this.currentRunlessRunId)) return false;
|
|
6896
|
-
return chunk.type === "TEXT_MESSAGE_START" || chunk.type === "TEXT_MESSAGE_CONTENT" || chunk.type === "TOOL_CALL_START" || chunk.type === "TOOL_CALL_ARGS" || chunk.type === "TOOL_CALL_END" || chunk.type === "TOOL_CALL_RESULT" || chunk.type === "MESSAGES_SNAPSHOT" || chunk.type === "RUN_ERROR";
|
|
8017
|
+
return chunk.type === "TEXT_MESSAGE_START" || chunk.type === "TEXT_MESSAGE_CONTENT" || chunk.type === "TEXT_MESSAGE_CHUNK" || chunk.type === "TOOL_CALL_START" || chunk.type === "TOOL_CALL_ARGS" || chunk.type === "TOOL_CALL_END" || chunk.type === "TOOL_CALL_RESULT" || chunk.type === "TOOL_CALL_CHUNK" || chunk.type === "MESSAGES_SNAPSHOT" || chunk.type === "RUN_ERROR";
|
|
6897
8018
|
}
|
|
6898
8019
|
};
|
|
6899
8020
|
//#endregion
|
|
6900
|
-
//#region node_modules/.
|
|
8021
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@0.39.2+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/cleared-stream-tracker.js
|
|
6901
8022
|
function getChunkToolCallId(chunk) {
|
|
6902
8023
|
return "toolCallId" in chunk && typeof chunk.toolCallId === "string" ? chunk.toolCallId : void 0;
|
|
6903
8024
|
}
|
|
@@ -6986,11 +8107,11 @@ var ClearedStreamTracker = class {
|
|
|
6986
8107
|
isRunlessChunkFromIgnoredRun(chunk) {
|
|
6987
8108
|
if (getChunkRunId$1(chunk) || !this.currentRunlessRunId) return false;
|
|
6988
8109
|
if (!this.ignoredActiveRunIds.has(this.currentRunlessRunId) && !this.clearedRunIds.has(this.currentRunlessRunId)) return false;
|
|
6989
|
-
return chunk.type === "TEXT_MESSAGE_START" || chunk.type === "TEXT_MESSAGE_CONTENT" || chunk.type === "TOOL_CALL_START" || chunk.type === "TOOL_CALL_ARGS" || chunk.type === "TOOL_CALL_END" || chunk.type === "TOOL_CALL_RESULT" || chunk.type === "MESSAGES_SNAPSHOT" || chunk.type === "RUN_ERROR";
|
|
8110
|
+
return chunk.type === "TEXT_MESSAGE_START" || chunk.type === "TEXT_MESSAGE_CONTENT" || chunk.type === "TEXT_MESSAGE_CHUNK" || chunk.type === "TOOL_CALL_START" || chunk.type === "TOOL_CALL_ARGS" || chunk.type === "TOOL_CALL_END" || chunk.type === "TOOL_CALL_RESULT" || chunk.type === "TOOL_CALL_CHUNK" || chunk.type === "MESSAGES_SNAPSHOT" || chunk.type === "RUN_ERROR";
|
|
6990
8111
|
}
|
|
6991
8112
|
};
|
|
6992
8113
|
//#endregion
|
|
6993
|
-
//#region node_modules/.
|
|
8114
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@0.39.2+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/chat-client.js
|
|
6994
8115
|
var STREAM_PROCESSING_BUDGET_MS = 8;
|
|
6995
8116
|
function yieldToHost() {
|
|
6996
8117
|
const { scheduler } = globalThis;
|
|
@@ -7126,8 +8247,11 @@ var REJOIN_CONNECT_DEADLINE_MS = 2e3;
|
|
|
7126
8247
|
var REJOIN_REBUILD_TRIGGERS = /* @__PURE__ */ new Set([
|
|
7127
8248
|
"TEXT_MESSAGE_START",
|
|
7128
8249
|
"TEXT_MESSAGE_CONTENT",
|
|
8250
|
+
"TEXT_MESSAGE_CHUNK",
|
|
7129
8251
|
"REASONING_MESSAGE_CONTENT",
|
|
8252
|
+
"REASONING_MESSAGE_CHUNK",
|
|
7130
8253
|
"TOOL_CALL_START",
|
|
8254
|
+
"TOOL_CALL_CHUNK",
|
|
7131
8255
|
"MESSAGES_SNAPSHOT",
|
|
7132
8256
|
"SUBAGENT_STARTED"
|
|
7133
8257
|
]);
|
|
@@ -7231,6 +8355,7 @@ var ChatClient = class {
|
|
|
7231
8355
|
currentMessageId = null;
|
|
7232
8356
|
postStreamActions = [];
|
|
7233
8357
|
pendingToolExecutions = /* @__PURE__ */ new Map();
|
|
8358
|
+
handingOverPendingToolCalls = false;
|
|
7234
8359
|
activeClientTools = null;
|
|
7235
8360
|
activeContext = void 0;
|
|
7236
8361
|
continuationPending = false;
|
|
@@ -7256,6 +8381,12 @@ var ChatClient = class {
|
|
|
7256
8381
|
hydrationError;
|
|
7257
8382
|
/** Whether a view is currently watching. See `attach` / `detach`. */
|
|
7258
8383
|
tailing = false;
|
|
8384
|
+
/** `historyGeneration` of the mount hydration GET still in flight, if any. */
|
|
8385
|
+
hydrationInFlight;
|
|
8386
|
+
/** An async storage adapter is still reading the persisted transcript. */
|
|
8387
|
+
storeHydrating = false;
|
|
8388
|
+
/** See {@link getIsHydrating}. */
|
|
8389
|
+
isHydrating = false;
|
|
7259
8390
|
/** Constructor inputs `attach()` needs on every re-attach, not just the first. */
|
|
7260
8391
|
rejoinRunId;
|
|
7261
8392
|
cachesMessages;
|
|
@@ -7310,6 +8441,7 @@ var ChatClient = class {
|
|
|
7310
8441
|
onSubscriptionChange: options.onSubscriptionChange || (() => {}),
|
|
7311
8442
|
onConnectionStatusChange: options.onConnectionStatusChange || (() => {}),
|
|
7312
8443
|
onSessionGeneratingChange: options.onSessionGeneratingChange || (() => {}),
|
|
8444
|
+
onHydratingChange: options.onHydratingChange || (() => {}),
|
|
7313
8445
|
onQueueChange: options.onQueueChange || (() => {}),
|
|
7314
8446
|
onResumeStateChange: options.onResumeStateChange || (() => {}),
|
|
7315
8447
|
onRunIdChange: options.onRunIdChange || (() => {}),
|
|
@@ -7391,6 +8523,10 @@ var ChatClient = class {
|
|
|
7391
8523
|
onToolCall: (args) => {
|
|
7392
8524
|
const clientTool = (this.activeClientTools ?? this.clientToolsRef.current).get(args.toolName);
|
|
7393
8525
|
const executeFunc = clientTool?.execute;
|
|
8526
|
+
if (this.handingOverPendingToolCalls && clientTool?.needsApproval === true) {
|
|
8527
|
+
console.warn(`[ChatClient] Did not run tool call ${args.toolCallId}: ${args.toolName} needs approval, and the server did not ask for it`);
|
|
8528
|
+
return;
|
|
8529
|
+
}
|
|
7394
8530
|
if (executeFunc) {
|
|
7395
8531
|
const continuationGeneration = this.continuationGeneration;
|
|
7396
8532
|
const runEventContext = this.devtoolsBridge.getCurrentRunEventContext();
|
|
@@ -7437,9 +8573,17 @@ var ChatClient = class {
|
|
|
7437
8573
|
}
|
|
7438
8574
|
});
|
|
7439
8575
|
this.syncSubagentHandles();
|
|
7440
|
-
this.persistor?.hydrateAsync(persistedState);
|
|
8576
|
+
const storeHydration = this.persistor?.hydrateAsync(persistedState);
|
|
8577
|
+
if (storeHydration) {
|
|
8578
|
+
this.storeHydrating = true;
|
|
8579
|
+
storeHydration.finally(() => {
|
|
8580
|
+
this.storeHydrating = false;
|
|
8581
|
+
this.syncIsHydrating();
|
|
8582
|
+
});
|
|
8583
|
+
}
|
|
7441
8584
|
this.rejoinRunId = rejoinRunId;
|
|
7442
8585
|
this.cachesMessages = cachesMessages;
|
|
8586
|
+
this.isHydrating = this.storeHydrating || !cachesMessages && !!this.connection.hydrate;
|
|
7443
8587
|
}
|
|
7444
8588
|
/**
|
|
7445
8589
|
* START TAILING: re-attach to an in-flight run so its chunks arrive here.
|
|
@@ -7542,21 +8686,30 @@ var ChatClient = class {
|
|
|
7542
8686
|
*/
|
|
7543
8687
|
hydrateFromServer() {
|
|
7544
8688
|
const hydrate = this.connection.hydrate;
|
|
7545
|
-
if (!hydrate)
|
|
7546
|
-
|
|
7547
|
-
|
|
8689
|
+
if (!hydrate || this.isLoading || this.abortController || this.disposed) {
|
|
8690
|
+
this.syncIsHydrating();
|
|
8691
|
+
return;
|
|
8692
|
+
}
|
|
8693
|
+
if (this.hydrationInFlight === this.historyGeneration) return;
|
|
7548
8694
|
const pageSize = this.historyPageSize;
|
|
7549
8695
|
const hydrateOptions = pageSize === void 0 ? void 0 : { limit: pageSize };
|
|
7550
8696
|
(async () => {
|
|
7551
8697
|
let result;
|
|
7552
8698
|
const generation = this.historyGeneration;
|
|
8699
|
+
this.hydrationInFlight = generation;
|
|
8700
|
+
this.syncIsHydrating();
|
|
8701
|
+
const isCurrent = () => this.hydrationInFlight === generation && generation === this.historyGeneration;
|
|
8702
|
+
let current;
|
|
7553
8703
|
try {
|
|
7554
8704
|
result = await hydrate(this.threadId, hydrateOptions);
|
|
7555
8705
|
} catch (cause) {
|
|
7556
|
-
if (
|
|
8706
|
+
if (isCurrent()) this.failHydration(cause);
|
|
7557
8707
|
return;
|
|
8708
|
+
} finally {
|
|
8709
|
+
current = isCurrent();
|
|
8710
|
+
if (this.hydrationInFlight === generation) this.hydrationInFlight = void 0;
|
|
7558
8711
|
}
|
|
7559
|
-
if (
|
|
8712
|
+
if (!current) return;
|
|
7560
8713
|
if (this.disposed || !this.tailing) return;
|
|
7561
8714
|
if (this.isLoading || this.abortController) return;
|
|
7562
8715
|
if (this.hydrationError && this.error === this.hydrationError) {
|
|
@@ -7578,7 +8731,7 @@ var ChatClient = class {
|
|
|
7578
8731
|
pendingInterrupts: result.interrupts.pending
|
|
7579
8732
|
});
|
|
7580
8733
|
else if (result.activeRun?.runId) this.maybeRejoinInFlight(result.activeRun.runId);
|
|
7581
|
-
})();
|
|
8734
|
+
})().finally(() => this.syncIsHydrating());
|
|
7582
8735
|
}
|
|
7583
8736
|
/**
|
|
7584
8737
|
* Surface a mount-hydration failure (`persistence: true`) on the observable
|
|
@@ -7847,6 +9000,17 @@ var ChatClient = class {
|
|
|
7847
9000
|
this.isLoading = isLoading;
|
|
7848
9001
|
this.callbacksRef.current.onLoadingChange(isLoading);
|
|
7849
9002
|
this.events.loadingChanged(isLoading);
|
|
9003
|
+
if (isLoading) this.supersedeHydration();
|
|
9004
|
+
}
|
|
9005
|
+
/**
|
|
9006
|
+
* A send or a clear now owns the transcript. A load that is still pending can
|
|
9007
|
+
* no longer paint it (the generation guards drop its result), so it no longer
|
|
9008
|
+
* counts as hydrating.
|
|
9009
|
+
*/
|
|
9010
|
+
supersedeHydration() {
|
|
9011
|
+
this.hydrationInFlight = void 0;
|
|
9012
|
+
this.storeHydrating = false;
|
|
9013
|
+
this.syncIsHydrating();
|
|
7850
9014
|
}
|
|
7851
9015
|
setStatus(status) {
|
|
7852
9016
|
this.status = status;
|
|
@@ -7863,6 +9027,12 @@ var ChatClient = class {
|
|
|
7863
9027
|
this.callbacksRef.current.onConnectionStatusChange(status);
|
|
7864
9028
|
this.devtoolsBridge.emitSnapshot();
|
|
7865
9029
|
}
|
|
9030
|
+
syncIsHydrating() {
|
|
9031
|
+
const isHydrating = this.hydrationInFlight !== void 0 || this.storeHydrating;
|
|
9032
|
+
if (this.isHydrating === isHydrating) return;
|
|
9033
|
+
this.isHydrating = isHydrating;
|
|
9034
|
+
this.callbacksRef.current.onHydratingChange(isHydrating);
|
|
9035
|
+
}
|
|
7866
9036
|
setSessionGenerating(isGenerating) {
|
|
7867
9037
|
if (this.sessionGenerating === isGenerating) return;
|
|
7868
9038
|
this.sessionGenerating = isGenerating;
|
|
@@ -8128,7 +9298,12 @@ var ChatClient = class {
|
|
|
8128
9298
|
this.resolveJoinedRun(chunk);
|
|
8129
9299
|
return;
|
|
8130
9300
|
}
|
|
8131
|
-
this.
|
|
9301
|
+
this.handingOverPendingToolCalls = chunk.type === "RUN_FINISHED" && chunk.outcome?.type !== "interrupt";
|
|
9302
|
+
try {
|
|
9303
|
+
this.processor.processChunk(chunk);
|
|
9304
|
+
} finally {
|
|
9305
|
+
this.handingOverPendingToolCalls = false;
|
|
9306
|
+
}
|
|
8132
9307
|
this.syncSubagentHandles();
|
|
8133
9308
|
this.updateRunLifecycle(chunk);
|
|
8134
9309
|
this.observeInterruptState(chunk);
|
|
@@ -8351,6 +9526,14 @@ var ChatClient = class {
|
|
|
8351
9526
|
if (this.hasPendingInterrupts()) throw new Error("ChatClient: cannot append normal input while pending interrupts exist. Use resumeInterrupts() instead.");
|
|
8352
9527
|
const normalizedMessage = normalizeToUIMessage(message, generateMessageId);
|
|
8353
9528
|
if (normalizedMessage.role === "system") return;
|
|
9529
|
+
if (normalizedMessage.role === "activity") {
|
|
9530
|
+
const uiMessage = normalizedMessage;
|
|
9531
|
+
this.events.messageAppended(uiMessage);
|
|
9532
|
+
const messages = this.processor.getMessages();
|
|
9533
|
+
this.processor.setMessages([...messages, uiMessage]);
|
|
9534
|
+
this.devtoolsBridge.emitSnapshot();
|
|
9535
|
+
return;
|
|
9536
|
+
}
|
|
8354
9537
|
const uiMessage = normalizedMessage;
|
|
8355
9538
|
this.events.messageAppended(uiMessage);
|
|
8356
9539
|
const messages = this.processor.getMessages();
|
|
@@ -8567,6 +9750,7 @@ var ChatClient = class {
|
|
|
8567
9750
|
this.persistor?.beginClear();
|
|
8568
9751
|
this.processor.clearMessages();
|
|
8569
9752
|
this.resetHistoryPaging();
|
|
9753
|
+
this.supersedeHydration();
|
|
8570
9754
|
this.discardPendingSends();
|
|
8571
9755
|
this.persistor?.remove();
|
|
8572
9756
|
this.stoppedSubagentIds.clear();
|
|
@@ -8825,16 +10009,17 @@ var ChatClient = class {
|
|
|
8825
10009
|
this.rememberServerMessageIds(this.processor.getMessages());
|
|
8826
10010
|
}
|
|
8827
10011
|
messagesForSend(messages) {
|
|
8828
|
-
|
|
10012
|
+
const forModel = messages.filter((message) => message.role !== "activity");
|
|
10013
|
+
if (this.historyPageSize === void 0) return forModel;
|
|
8829
10014
|
const unknownMessages = [];
|
|
8830
|
-
for (const message of
|
|
10015
|
+
for (const message of forModel) {
|
|
8831
10016
|
if (this.knownServerMessageIds.has(message.id)) continue;
|
|
8832
10017
|
unknownMessages.push(message);
|
|
8833
10018
|
}
|
|
8834
10019
|
if (unknownMessages.length > 0) return unknownMessages;
|
|
8835
|
-
const lastUserIndex =
|
|
10020
|
+
const lastUserIndex = forModel.findLastIndex((message) => message.role === "user");
|
|
8836
10021
|
if (lastUserIndex === -1) return [];
|
|
8837
|
-
return
|
|
10022
|
+
return forModel.slice(lastUserIndex);
|
|
8838
10023
|
}
|
|
8839
10024
|
/**
|
|
8840
10025
|
* True when an interrupt (or another direct send) claimed the client during
|
|
@@ -8956,6 +10141,15 @@ var ChatClient = class {
|
|
|
8956
10141
|
return this.sessionGenerating;
|
|
8957
10142
|
}
|
|
8958
10143
|
/**
|
|
10144
|
+
* Whether the client is rebuilding the chat from persistence: the server
|
|
10145
|
+
* hydrate (`persistence: true`) or an async storage adapter. Turns false once
|
|
10146
|
+
* the transcript is applied and any in-flight run is re-joined (from then on
|
|
10147
|
+
* `isLoading` covers the stream), or when the load fails.
|
|
10148
|
+
*/
|
|
10149
|
+
getIsHydrating() {
|
|
10150
|
+
return this.isHydrating;
|
|
10151
|
+
}
|
|
10152
|
+
/**
|
|
8959
10153
|
* Get current error
|
|
8960
10154
|
*/
|
|
8961
10155
|
getError() {
|
|
@@ -9006,6 +10200,7 @@ var ChatClient = class {
|
|
|
9006
10200
|
if (options.onSubscriptionChange !== void 0) this.callbacksRef.current.onSubscriptionChange = options.onSubscriptionChange;
|
|
9007
10201
|
if (options.onConnectionStatusChange !== void 0) this.callbacksRef.current.onConnectionStatusChange = options.onConnectionStatusChange;
|
|
9008
10202
|
if (options.onSessionGeneratingChange !== void 0) this.callbacksRef.current.onSessionGeneratingChange = options.onSessionGeneratingChange;
|
|
10203
|
+
if (options.onHydratingChange !== void 0) this.callbacksRef.current.onHydratingChange = options.onHydratingChange;
|
|
9009
10204
|
if (options.onQueueChange !== void 0) this.callbacksRef.current.onQueueChange = options.onQueueChange;
|
|
9010
10205
|
if (options.onResumeStateChange !== void 0) this.callbacksRef.current.onResumeStateChange = options.onResumeStateChange;
|
|
9011
10206
|
if (options.onRunIdChange !== void 0) this.callbacksRef.current.onRunIdChange = options.onRunIdChange;
|
|
@@ -9083,9 +10278,10 @@ function buildAgentTools(widgets, hostTools, renderWidget, debug) {
|
|
|
9083
10278
|
];
|
|
9084
10279
|
}
|
|
9085
10280
|
function buildRenderWidgetTool(widgets, render) {
|
|
10281
|
+
const catalog = Object.entries(widgets).map(([name, { description, parameters }]) => `- ${name}: ${description} Props schema: ${JSON.stringify(toJsonSchema(parameters))}`).join("\n");
|
|
9086
10282
|
return toolDefinition({
|
|
9087
10283
|
name: RENDER_WIDGET_TOOL,
|
|
9088
|
-
description: "Render one of the host application's own UI widgets inline in the conversation. The widget appears in the transcript at the point of the call, so prefer it over describing the same information in text. Available widgets:\n" +
|
|
10284
|
+
description: "Render one of the host application's own UI widgets inline in the conversation. The widget appears in the transcript at the point of the call, so prefer it over describing the same information in text. Available widgets:\n" + catalog,
|
|
9089
10285
|
inputSchema: {
|
|
9090
10286
|
type: "object",
|
|
9091
10287
|
properties: {
|
|
@@ -9332,6 +10528,7 @@ async function loadChatAuthToken(options) {
|
|
|
9332
10528
|
} catch (cause) {
|
|
9333
10529
|
signal.throwIfAborted();
|
|
9334
10530
|
const error = cause instanceof Error ? cause : /* @__PURE__ */ new Error("Authentication failed");
|
|
10531
|
+
if (isAstralBeamApiError(error) && error.status === 401) error.message = "AstralBeam rejected the chat token after renewal. Check that apiUrl matches the deployment that issued your API key. If the key was revoked or expired, create a replacement in API Keys and update your server's secret.";
|
|
9335
10532
|
session.cached = void 0;
|
|
9336
10533
|
publishAuthentication(options, {
|
|
9337
10534
|
status: "error",
|
|
@@ -9450,6 +10647,100 @@ function startAuthentication(options) {
|
|
|
9450
10647
|
};
|
|
9451
10648
|
}
|
|
9452
10649
|
//#endregion
|
|
10650
|
+
//#region src/core/mcp.ts
|
|
10651
|
+
async function manageMcpConnection(operation, options) {
|
|
10652
|
+
switch (operation.action) {
|
|
10653
|
+
case "connect": return personalMcpCreateConnection({ mcp_server_id: operation.mcpServerId }, options);
|
|
10654
|
+
case "headers": {
|
|
10655
|
+
const connection = await personalMcpCreateConnection({ mcp_server_id: operation.mcpServerId }, options);
|
|
10656
|
+
await personalMcpSetHeaders(connection.id, {
|
|
10657
|
+
lock_version: connection.lock_version,
|
|
10658
|
+
headers: operation.headers
|
|
10659
|
+
}, options);
|
|
10660
|
+
return { id: connection.id };
|
|
10661
|
+
}
|
|
10662
|
+
case "disconnect": return personalMcpDisconnectConnection(operation.id, options);
|
|
10663
|
+
case "test": return personalMcpTestConnection(operation.id, options);
|
|
10664
|
+
}
|
|
10665
|
+
}
|
|
10666
|
+
async function authorizeMcpConnection(input, requestOptions) {
|
|
10667
|
+
const popup = window.open("about:blank", "_blank", "popup,width=600,height=720");
|
|
10668
|
+
if (!popup) throw new Error("Allow popups to authorize this connection.");
|
|
10669
|
+
try {
|
|
10670
|
+
const id = input.id ?? (await personalMcpCreateConnection({ mcp_server_id: input.mcpServerId }, await requestOptions())).id;
|
|
10671
|
+
const response = await personalMcpAuthorizeConnection(id, await requestOptions());
|
|
10672
|
+
const attempt = {
|
|
10673
|
+
organizationId: response.attempt.organization_id,
|
|
10674
|
+
tenantId: response.attempt.tenant_id,
|
|
10675
|
+
connectionId: response.attempt.connection_id,
|
|
10676
|
+
id: response.attempt.id
|
|
10677
|
+
};
|
|
10678
|
+
const url = new URL(response.popup_url);
|
|
10679
|
+
url.searchParams.set("origin", window.location.origin);
|
|
10680
|
+
await new Promise((resolve, reject) => {
|
|
10681
|
+
let challenge;
|
|
10682
|
+
let bound = false;
|
|
10683
|
+
let finished = false;
|
|
10684
|
+
let completing = false;
|
|
10685
|
+
const cleanup = () => {
|
|
10686
|
+
finished = true;
|
|
10687
|
+
window.removeEventListener("message", receive);
|
|
10688
|
+
clearInterval(poll);
|
|
10689
|
+
clearTimeout(expiry);
|
|
10690
|
+
};
|
|
10691
|
+
const fail = (error) => {
|
|
10692
|
+
cleanup();
|
|
10693
|
+
reject(error instanceof Error ? error : /* @__PURE__ */ new Error("Authorization failed."));
|
|
10694
|
+
};
|
|
10695
|
+
const complete = async () => {
|
|
10696
|
+
if (completing || finished) return;
|
|
10697
|
+
completing = true;
|
|
10698
|
+
try {
|
|
10699
|
+
if (challenge) {
|
|
10700
|
+
if (!bound) {
|
|
10701
|
+
await personalMcpBindBrowser(id, {
|
|
10702
|
+
attempt_id: attempt.id,
|
|
10703
|
+
challenge
|
|
10704
|
+
}, await requestOptions());
|
|
10705
|
+
bound = true;
|
|
10706
|
+
}
|
|
10707
|
+
if (finished) return;
|
|
10708
|
+
const connected = await personalMcpCompleteAuthorization(id, { attempt_id: attempt.id }, await requestOptions());
|
|
10709
|
+
if (finished) return;
|
|
10710
|
+
if (connected) {
|
|
10711
|
+
cleanup();
|
|
10712
|
+
resolve();
|
|
10713
|
+
return;
|
|
10714
|
+
}
|
|
10715
|
+
}
|
|
10716
|
+
if (popup.closed) fail(/* @__PURE__ */ new Error("Authorization window closed."));
|
|
10717
|
+
} catch (error) {
|
|
10718
|
+
const status = error instanceof Error ? error.status : void 0;
|
|
10719
|
+
if (!(error instanceof TypeError) && status !== 429 && (status ?? 0) < 500) fail(error);
|
|
10720
|
+
} finally {
|
|
10721
|
+
completing = false;
|
|
10722
|
+
}
|
|
10723
|
+
};
|
|
10724
|
+
const receive = (event) => {
|
|
10725
|
+
if (event.source !== popup || event.origin !== url.origin) return;
|
|
10726
|
+
const data = event.data;
|
|
10727
|
+
if (!data?.attempt || data.attempt.id !== attempt.id || data.attempt.organizationId !== attempt.organizationId || data.attempt.tenantId !== attempt.tenantId || data.attempt.connectionId !== attempt.connectionId) return;
|
|
10728
|
+
if (data.type === "mcp-browser-challenge" && !challenge && typeof data.challenge === "string") {
|
|
10729
|
+
challenge = data.challenge;
|
|
10730
|
+
complete();
|
|
10731
|
+
}
|
|
10732
|
+
};
|
|
10733
|
+
const poll = setInterval(() => void complete(), 5e3);
|
|
10734
|
+
const expiry = setTimeout(() => fail(/* @__PURE__ */ new Error("Authorization expired. Try connecting again.")), 6e5);
|
|
10735
|
+
window.addEventListener("message", receive);
|
|
10736
|
+
popup.location.replace(url.href);
|
|
10737
|
+
});
|
|
10738
|
+
return id;
|
|
10739
|
+
} finally {
|
|
10740
|
+
popup.close();
|
|
10741
|
+
}
|
|
10742
|
+
}
|
|
10743
|
+
//#endregion
|
|
9453
10744
|
//#region src/core/messages.ts
|
|
9454
10745
|
function isSettledToolCall(part) {
|
|
9455
10746
|
return part.state === "complete" || part.state === "error" || part.output !== void 0;
|
|
@@ -9463,6 +10754,11 @@ function hasPendingToolRun(messages, toolNames) {
|
|
|
9463
10754
|
return messages.some((message) => message.parts.some((part) => part.type === "tool-call" && !isSettledToolCall(part) && part.name !== "ask_questionnaire" && toolNames.has(part.name)));
|
|
9464
10755
|
}
|
|
9465
10756
|
//#endregion
|
|
10757
|
+
//#region src/core/web.ts
|
|
10758
|
+
function webPartMetadata(part) {
|
|
10759
|
+
return part.metadata ?? {};
|
|
10760
|
+
}
|
|
10761
|
+
//#endregion
|
|
9466
10762
|
//#region src/core/sandbox.ts
|
|
9467
10763
|
const SANDBOX_TOOLS = [
|
|
9468
10764
|
SANDBOX_WRITE_FILE_TOOL,
|
|
@@ -9513,19 +10809,19 @@ function sandboxPathLabel(part) {
|
|
|
9513
10809
|
if (relative !== void 0 && relative !== ".") return relative;
|
|
9514
10810
|
return text(part.output, "path") ?? text(part.input, "path");
|
|
9515
10811
|
}
|
|
9516
|
-
/** A `sandbox_publish_artifact` call whose output carries
|
|
10812
|
+
/** A `sandbox_publish_artifact` call whose output carries a durable file reference. */
|
|
9517
10813
|
function readSandboxArtifact(part) {
|
|
9518
10814
|
if (part.name !== "sandbox_publish_artifact") return void 0;
|
|
9519
10815
|
const path = text(part.output, "path") ?? text(part.input, "path");
|
|
9520
|
-
const
|
|
10816
|
+
const fileId = text(part.output, "fileId");
|
|
9521
10817
|
return {
|
|
9522
10818
|
toolCallId: part.id,
|
|
9523
10819
|
path: path ?? "",
|
|
9524
10820
|
label: sandboxPathLabel(part) ?? path ?? "",
|
|
9525
10821
|
mimeType: text(part.output, "mimeType"),
|
|
9526
10822
|
size: count(part.output, "size"),
|
|
9527
|
-
|
|
9528
|
-
published:
|
|
10823
|
+
fileId,
|
|
10824
|
+
published: fileId !== void 0 && sandboxRefusal(part) === void 0
|
|
9529
10825
|
};
|
|
9530
10826
|
}
|
|
9531
10827
|
/** A `sandbox_run_command` call. `stdout` holds combined output on providers with no stderr. */
|
|
@@ -9627,6 +10923,10 @@ function projectThreadMessages(records, pendingInteractions = [], liveToolMessag
|
|
|
9627
10923
|
const call = calls.get(savedToolCallId(message.source_assistant_message_id, message.source_tool_part_id, message.response_target_id));
|
|
9628
10924
|
if (!call) continue;
|
|
9629
10925
|
call.output = part.output ?? null;
|
|
10926
|
+
if (call.name === "sandbox_publish_artifact") {
|
|
10927
|
+
call.artifactMessageId = message.id;
|
|
10928
|
+
call.artifactPartId = String(part.id);
|
|
10929
|
+
}
|
|
9630
10930
|
Object.assign(call, { resultOutcome: part.outcome });
|
|
9631
10931
|
call.state = part.outcome === "succeeded" ? "complete" : "error";
|
|
9632
10932
|
}
|
|
@@ -9634,7 +10934,12 @@ function projectThreadMessages(records, pendingInteractions = [], liveToolMessag
|
|
|
9634
10934
|
}
|
|
9635
10935
|
const parts = message.parts.flatMap((part) => {
|
|
9636
10936
|
const source = part.source;
|
|
9637
|
-
if (
|
|
10937
|
+
if (typeof part.type === "string" && [
|
|
10938
|
+
"image",
|
|
10939
|
+
"document",
|
|
10940
|
+
"audio",
|
|
10941
|
+
"video"
|
|
10942
|
+
].includes(part.type) && source && typeof source === "object" && !Array.isArray(source) && "type" in source && source.type === "attachment") return [{
|
|
9638
10943
|
...part,
|
|
9639
10944
|
source: {
|
|
9640
10945
|
...source,
|
|
@@ -9644,12 +10949,14 @@ function projectThreadMessages(records, pendingInteractions = [], liveToolMessag
|
|
|
9644
10949
|
savedAttachmentId: part.id
|
|
9645
10950
|
}];
|
|
9646
10951
|
if (part.type !== "tool-call") return [part];
|
|
10952
|
+
if (part.executionLocation === "provider") return [part];
|
|
9647
10953
|
const toolCallId = String(part.toolCallId);
|
|
9648
10954
|
const targets = Array.isArray(part.targets) ? part.targets.flatMap((target) => target && typeof target === "object" && !Array.isArray(target) && "id" in target && typeof target.id === "string" ? [target.id] : []) : pendingInteractions.filter((pending) => pending.sourceMessageId === message.id && pending.sourcePartId === part.id).map((pending) => pending.responseTargetId);
|
|
9649
10955
|
return (targets.length ? targets : [void 0]).map((responseTargetId) => {
|
|
9650
10956
|
const savedId = savedToolCallId(message.id, String(part.id), responseTargetId);
|
|
9651
10957
|
const call = {
|
|
9652
10958
|
...part,
|
|
10959
|
+
savedToolTitle: part.declaration && typeof part.declaration === "object" && !Array.isArray(part.declaration) && "title" in part.declaration && typeof part.declaration.title === "string" ? part.declaration.title : void 0,
|
|
9653
10960
|
id: liveToolMessageIds.get(toolCallId) === message.id ? toolCallId : savedId,
|
|
9654
10961
|
upstreamToolCallId: toolCallId,
|
|
9655
10962
|
applicationPartId: part.id,
|
|
@@ -9714,6 +11021,7 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
9714
11021
|
capabilities: { attachments: true },
|
|
9715
11022
|
agentTools: [],
|
|
9716
11023
|
sandboxStatus: void 0,
|
|
11024
|
+
usageLimitReached: void 0,
|
|
9717
11025
|
sandbox: {
|
|
9718
11026
|
files: [],
|
|
9719
11027
|
commands: []
|
|
@@ -9764,6 +11072,14 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
9764
11072
|
} });
|
|
9765
11073
|
pendingSend.callbacks?.onAccepted?.();
|
|
9766
11074
|
};
|
|
11075
|
+
const replaceAcceptedMessage = (record) => {
|
|
11076
|
+
const messages = [...client.getMessages()];
|
|
11077
|
+
const index = messages.findLastIndex((message) => message.role === "user");
|
|
11078
|
+
if (index !== -1) {
|
|
11079
|
+
messages[index] = projectThreadMessages([record])[0];
|
|
11080
|
+
client.setMessagesManually(messages);
|
|
11081
|
+
}
|
|
11082
|
+
};
|
|
9767
11083
|
const liveToolCalls = /* @__PURE__ */ new Set();
|
|
9768
11084
|
const liveToolMessageIds = /* @__PURE__ */ new Map();
|
|
9769
11085
|
const historicalToolIds = /* @__PURE__ */ new Map();
|
|
@@ -9793,17 +11109,22 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
9793
11109
|
error: failure,
|
|
9794
11110
|
status: "error"
|
|
9795
11111
|
});
|
|
9796
|
-
live.streamCallbacks?.onError?.(failure);
|
|
11112
|
+
if (state.auth.status !== "error" || state.auth.error !== failure) live.streamCallbacks?.onError?.(failure);
|
|
11113
|
+
};
|
|
11114
|
+
const clearUnavailableMcpConnection = (id) => {
|
|
11115
|
+
update({ unavailableMcpConnections: state.unavailableMcpConnections?.filter((entry) => entry !== id) ?? [] });
|
|
9797
11116
|
};
|
|
9798
|
-
const requestOptions = async () => {
|
|
11117
|
+
const requestOptions = async (conversation = true) => {
|
|
9799
11118
|
const generation = selectionGeneration;
|
|
11119
|
+
const authSignal = authentication.session.abortController.signal;
|
|
9800
11120
|
const token = await getValidChatAuthToken(authentication);
|
|
9801
|
-
|
|
11121
|
+
authSignal.throwIfAborted();
|
|
11122
|
+
if (conversation && generation !== selectionGeneration) throw new DOMException("Conversation changed", "AbortError");
|
|
9802
11123
|
return {
|
|
9803
11124
|
apiUrl: authentication.apiUrl,
|
|
9804
11125
|
astralBeamToken: token,
|
|
9805
11126
|
cache: "no-store",
|
|
9806
|
-
signal: AbortSignal.any([requestController.signal,
|
|
11127
|
+
signal: conversation ? AbortSignal.any([requestController.signal, authSignal]) : authSignal,
|
|
9807
11128
|
fetchClient: (input, init) => fetchAuthenticatedChat({
|
|
9808
11129
|
...authentication,
|
|
9809
11130
|
input,
|
|
@@ -10007,6 +11328,11 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10007
11328
|
headers,
|
|
10008
11329
|
body: JSON.stringify(payload)
|
|
10009
11330
|
}).catch((error) => {
|
|
11331
|
+
const limit = isAstralBeamApiError(error) ? error.body?.usage_limit : void 0;
|
|
11332
|
+
if (limit) update({ usageLimitReached: {
|
|
11333
|
+
name: limit.name,
|
|
11334
|
+
resetsAt: limit.resets_at
|
|
11335
|
+
} });
|
|
10010
11336
|
if (submission && !previouslyAttempted && isAstralBeamApiError(error) && (error.status === 400 || error.status === 413 || error.status === 429)) delete submission.tools;
|
|
10011
11337
|
throw error;
|
|
10012
11338
|
});
|
|
@@ -10014,11 +11340,23 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10014
11340
|
if (response.headers.get("Content-Type")?.includes("application/json")) {
|
|
10015
11341
|
const receipt = await response.json();
|
|
10016
11342
|
if (generation !== selectionGeneration) throw new DOMException("Conversation changed", "AbortError");
|
|
10017
|
-
update({
|
|
10018
|
-
|
|
10019
|
-
|
|
10020
|
-
|
|
10021
|
-
|
|
11343
|
+
update({
|
|
11344
|
+
thread: {
|
|
11345
|
+
...state.thread,
|
|
11346
|
+
version: receipt.thread_version
|
|
11347
|
+
},
|
|
11348
|
+
...receipt.usage_limit ? { usageLimitReached: {
|
|
11349
|
+
name: receipt.usage_limit.name,
|
|
11350
|
+
resetsAt: receipt.usage_limit.resets_at
|
|
11351
|
+
} } : {}
|
|
11352
|
+
});
|
|
11353
|
+
if (submission) {
|
|
11354
|
+
const history = await loadThreadMessages(thread.id, auth, void 0, liveToolMessageIds);
|
|
11355
|
+
if (generation !== selectionGeneration) throw new DOMException("Conversation changed", "AbortError");
|
|
11356
|
+
const accepted = history.messages.find((message) => message.id === receipt.accepted_message_id);
|
|
11357
|
+
if (accepted) replaceAcceptedMessage(accepted);
|
|
11358
|
+
acceptPendingSend();
|
|
11359
|
+
}
|
|
10022
11360
|
return new Response("", { headers: { "Content-Type": "text/event-stream" } });
|
|
10023
11361
|
}
|
|
10024
11362
|
return response;
|
|
@@ -10143,6 +11481,11 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10143
11481
|
onMessagesChange: (messages) => {
|
|
10144
11482
|
if (client !== next || generation !== selectionGeneration) return;
|
|
10145
11483
|
restoreCompletedWidgets(messages);
|
|
11484
|
+
for (const message of messages) {
|
|
11485
|
+
if (message.role !== "user") continue;
|
|
11486
|
+
const saved = state.messages.find((previous) => previous.id === message.id);
|
|
11487
|
+
if (saved?.parts.some((part) => "savedAttachmentId" in part)) message.parts = saved.parts;
|
|
11488
|
+
}
|
|
10146
11489
|
update({
|
|
10147
11490
|
messages,
|
|
10148
11491
|
sandbox: collectSandboxActivity(messages),
|
|
@@ -10152,7 +11495,8 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10152
11495
|
onStatusChange: (status) => {
|
|
10153
11496
|
if (client === next && generation === selectionGeneration) update({
|
|
10154
11497
|
status,
|
|
10155
|
-
error: next.getError()
|
|
11498
|
+
error: next.getError(),
|
|
11499
|
+
...status === "submitted" ? { usageLimitReached: void 0 } : {}
|
|
10156
11500
|
});
|
|
10157
11501
|
},
|
|
10158
11502
|
onInterruptStateChange: (interrupts) => {
|
|
@@ -10163,6 +11507,7 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10163
11507
|
if (eventType === "astralbeam_thread") {
|
|
10164
11508
|
const event = data;
|
|
10165
11509
|
if (state.thread?.id === event.threadId) {
|
|
11510
|
+
if (event.acceptedMessage && pendingSend && !pendingSend.accepted) replaceAcceptedMessage(event.acceptedMessage);
|
|
10166
11511
|
if (event.acceptedMessageId) acceptPendingSend();
|
|
10167
11512
|
if (event.saved) for (const id of event.executableToolCallIds ?? []) {
|
|
10168
11513
|
if (!liveToolCalls.has(id)) toolResults.delete(toolResultKey(id));
|
|
@@ -10179,6 +11524,24 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10179
11524
|
}
|
|
10180
11525
|
return;
|
|
10181
11526
|
}
|
|
11527
|
+
if (eventType === "astralbeam_mcp_tools") {
|
|
11528
|
+
const event = data;
|
|
11529
|
+
const titles = {};
|
|
11530
|
+
for (const tool of event.tools ?? []) if (typeof tool.name === "string" && typeof tool.title === "string") titles[tool.name] = tool.title;
|
|
11531
|
+
update({
|
|
11532
|
+
serverToolTitles: titles,
|
|
11533
|
+
unavailableMcpConnections: event.unavailable ?? []
|
|
11534
|
+
});
|
|
11535
|
+
return;
|
|
11536
|
+
}
|
|
11537
|
+
const limit = data;
|
|
11538
|
+
if (eventType === "astralbeam.usage_limit.reached" && typeof limit?.name === "string" && typeof limit.resetsAt === "string") {
|
|
11539
|
+
update({ usageLimitReached: {
|
|
11540
|
+
name: limit.name,
|
|
11541
|
+
resetsAt: limit.resetsAt
|
|
11542
|
+
} });
|
|
11543
|
+
return;
|
|
11544
|
+
}
|
|
10182
11545
|
const value = data?.state;
|
|
10183
11546
|
if (eventType === "astralbeam.sandbox.status" && (value === "starting" || value === "ready" || value === "error")) {
|
|
10184
11547
|
debug?.("sandbox", `sandbox ${value}`);
|
|
@@ -10189,6 +11552,10 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10189
11552
|
},
|
|
10190
11553
|
onChunk: (chunk) => {
|
|
10191
11554
|
if (client !== next) return;
|
|
11555
|
+
if (chunk.type === EventType.RUN_STARTED) update({
|
|
11556
|
+
serverToolTitles: {},
|
|
11557
|
+
unavailableMcpConnections: []
|
|
11558
|
+
});
|
|
10192
11559
|
live.streamCallbacks?.onChunk?.(chunk);
|
|
10193
11560
|
},
|
|
10194
11561
|
onResponse: (response) => {
|
|
@@ -10198,7 +11565,7 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10198
11565
|
if (client === next) live.streamCallbacks?.onFinish?.(message);
|
|
10199
11566
|
},
|
|
10200
11567
|
onError: (error) => {
|
|
10201
|
-
if (client === next) live.streamCallbacks?.onError?.(error);
|
|
11568
|
+
if (client === next && (state.auth.status !== "error" || state.auth.error !== error)) live.streamCallbacks?.onError?.(error);
|
|
10202
11569
|
}
|
|
10203
11570
|
});
|
|
10204
11571
|
return next;
|
|
@@ -10220,7 +11587,7 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10220
11587
|
client.setMessagesManually(state.messages.map((message) => {
|
|
10221
11588
|
const aliases = /* @__PURE__ */ new Map();
|
|
10222
11589
|
const parts = message.parts.map((part) => {
|
|
10223
|
-
if (part.type !== "tool-call") return part;
|
|
11590
|
+
if (part.type !== "tool-call" || webPartMetadata(part).providerExecuted) return part;
|
|
10224
11591
|
const stored = part;
|
|
10225
11592
|
const upstreamToolCallId = stored.upstreamToolCallId ?? part.id;
|
|
10226
11593
|
if (liveToolMessageIds.get(upstreamToolCallId) === message.id && !isSettledToolCall(part)) return part;
|
|
@@ -10268,7 +11635,10 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10268
11635
|
commands: []
|
|
10269
11636
|
},
|
|
10270
11637
|
sandboxStatus: void 0,
|
|
11638
|
+
usageLimitReached: void 0,
|
|
10271
11639
|
pendingInteractions: [],
|
|
11640
|
+
serverToolTitles: {},
|
|
11641
|
+
unavailableMcpConnections: [],
|
|
10272
11642
|
threadLoadFailed: false,
|
|
10273
11643
|
messagesCursor: void 0,
|
|
10274
11644
|
olderMessagesLoading: false
|
|
@@ -10434,7 +11804,7 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10434
11804
|
});
|
|
10435
11805
|
}
|
|
10436
11806
|
scopeCompletedToolCalls();
|
|
10437
|
-
if (pending
|
|
11807
|
+
if (pending) {
|
|
10438
11808
|
replaceClient();
|
|
10439
11809
|
await hydration;
|
|
10440
11810
|
if (generation !== selectionGeneration) return;
|
|
@@ -10528,6 +11898,7 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10528
11898
|
};
|
|
10529
11899
|
const observeAuthentication = () => {
|
|
10530
11900
|
const auth = authenticationState(authentication);
|
|
11901
|
+
const previous = state.auth;
|
|
10531
11902
|
if (auth.status === "ready") {
|
|
10532
11903
|
const nextIdentity = authenticationIdentity(auth.currentUser);
|
|
10533
11904
|
if (identity !== void 0 && identity !== nextIdentity) {
|
|
@@ -10553,6 +11924,7 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10553
11924
|
}
|
|
10554
11925
|
}
|
|
10555
11926
|
update({ auth });
|
|
11927
|
+
if (auth.status === "error" && (previous.status !== "error" || previous.error !== auth.error)) live.streamCallbacks?.onError?.(auth.error);
|
|
10556
11928
|
};
|
|
10557
11929
|
const start = () => {
|
|
10558
11930
|
if (started) return;
|
|
@@ -10646,11 +12018,44 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10646
12018
|
deleteThread,
|
|
10647
12019
|
refreshThread,
|
|
10648
12020
|
loadOlderMessages,
|
|
12021
|
+
uploadAttachment: async ({ data, filename, mimeType }) => {
|
|
12022
|
+
const agentId = state.thread ? state.thread.agentId : live.agentId;
|
|
12023
|
+
const [encoded, options] = await Promise.all([data, requestOptions(false)]);
|
|
12024
|
+
return uploadChatFile({
|
|
12025
|
+
...agentId ? { agentId } : {},
|
|
12026
|
+
type: mimeType.startsWith("image/") ? "image" : "document",
|
|
12027
|
+
source: {
|
|
12028
|
+
type: "data",
|
|
12029
|
+
value: encoded,
|
|
12030
|
+
mimeType
|
|
12031
|
+
},
|
|
12032
|
+
metadata: { filename }
|
|
12033
|
+
}, options);
|
|
12034
|
+
},
|
|
12035
|
+
getFile: async (fileId) => {
|
|
12036
|
+
const thread = state.thread;
|
|
12037
|
+
if (!thread) throw new Error("Open a conversation before downloading files.");
|
|
12038
|
+
return (await getChatFile({
|
|
12039
|
+
threadId: thread.id,
|
|
12040
|
+
fileId
|
|
12041
|
+
}, await requestOptions())).blob();
|
|
12042
|
+
},
|
|
10649
12043
|
getAttachment: async (messageId, partId) => {
|
|
10650
12044
|
const thread = state.thread;
|
|
10651
12045
|
if (!thread) throw new Error("Open a conversation before downloading attachments.");
|
|
10652
12046
|
return (await getChatAttachment(thread.id, messageId, partId, await requestOptions())).blob();
|
|
10653
12047
|
},
|
|
12048
|
+
getMcpCatalog: async () => personalMcpGetCatalog(await requestOptions(false)),
|
|
12049
|
+
manageMcpConnection: async (operation) => {
|
|
12050
|
+
const result = await manageMcpConnection(operation, await requestOptions(false));
|
|
12051
|
+
if ("id" in operation) clearUnavailableMcpConnection(operation.id);
|
|
12052
|
+
else if (result && "id" in result) clearUnavailableMcpConnection(result.id);
|
|
12053
|
+
return result;
|
|
12054
|
+
},
|
|
12055
|
+
authorizeMcpConnection: async (input) => {
|
|
12056
|
+
const id = await authorizeMcpConnection(input, () => requestOptions(false));
|
|
12057
|
+
clearUnavailableMcpConnection(id);
|
|
12058
|
+
},
|
|
10654
12059
|
abandonToolCall,
|
|
10655
12060
|
reset: () => {
|
|
10656
12061
|
debug?.("status", "conversation reset");
|