@astralbeam/sdk 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/{api-DzeMhfHU.js → api-BaIPbj-Q.js} +66 -10
- package/dist/api.d.ts +2 -2
- package/dist/api.js +2 -2
- package/dist/client.js +1 -1
- package/dist/{core-D84VNYWJ.js → core-DeMY6_wQ.js} +1377 -103
- package/dist/core.d.ts +2 -2
- package/dist/core.js +1 -1
- package/dist/{index-CH3RVjha.d.ts → index-CfGnT6Od.d.ts} +129 -18
- package/dist/{index-CM3pzsKR.d.ts → index-NT05_Yw_.d.ts} +155 -58
- package/dist/listings-BH_hPkxx.js +1 -0
- package/dist/react.d.ts +2 -2
- package/dist/react.js +2 -2
- package/dist/rolldown-runtime-QTnfLwEv.js +1 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.js +6 -2
- package/dist/styles.generated-D8sDOLu3.js +98 -0
- package/dist/widget-BdiuWvPf.js +24 -0
- package/package.json +6 -6
- 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/widget-h5LX5aq8.js +0 -11
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Ct as isAstralBeamApiError, O as getCurrentUser, S as getChatFile, St as astralBeamChatFetch, X as getRunChatUrl, Y as getResolveChatToolResultUrl, b as getChatAttachment, ct as listChatThreads, g as createChatThread, ot as listChatMessages, vt as updateChatThread, wt as resolveApiUrl, x as getChatConfig, xt as uploadChatFile, y as deleteChatThread } from "./api-BaIPbj-Q.js";
|
|
2
2
|
import { d as JWTInvalid, h as strictDecoder, r as isObject, s as decode } from "./type_checks-C-WTHaWs.js";
|
|
3
3
|
//#region \0rolldown/runtime.js
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
4
5
|
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), 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
16
|
//#region node_modules/.deno/jose@6.2.9/node_modules/jose/dist/webapi/util/decode_jwt.js
|
|
7
17
|
function decodeJwt(jwt) {
|
|
@@ -26,7 +36,7 @@ function decodeJwt(jwt) {
|
|
|
26
36
|
return result;
|
|
27
37
|
}
|
|
28
38
|
//#endregion
|
|
29
|
-
//#region node_modules/.deno/@tanstack+ai-client@0.
|
|
39
|
+
//#region node_modules/.deno/@tanstack+ai-client@0.39.2/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/.deno/@tanstack+ai-client@0.
|
|
61
|
+
//#region node_modules/.deno/@tanstack+ai-client@0.39.2/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/.deno/@tanstack+ai-client@0.
|
|
68
|
+
//#region node_modules/.deno/@tanstack+ai-client@0.39.2/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/.deno/@tanstack+ai@0.
|
|
100
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/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/.deno/@tanstack+ai@0.
|
|
145
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/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
|
}
|
|
@@ -211,7 +221,7 @@ let EventType = /* @__PURE__ */ function(EventType) {
|
|
|
211
221
|
return EventType;
|
|
212
222
|
}({});
|
|
213
223
|
//#endregion
|
|
214
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
224
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/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/.deno/@tanstack+ai@0.
|
|
236
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/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/.deno/@tanstack+ai@0.
|
|
411
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/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/.deno/@tanstack+ai@0.
|
|
422
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/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/.deno/@tanstack+ai@0.
|
|
690
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/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",
|
|
@@ -789,7 +799,7 @@ function hashSchemaInput(schema) {
|
|
|
789
799
|
return digestInterruptJson(canonicalInterruptJson(schemaToWire(schema).jsonSchema ?? { standardValidator: "unserialized" }));
|
|
790
800
|
}
|
|
791
801
|
//#endregion
|
|
792
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
802
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/interrupt-resume.js
|
|
793
803
|
/**
|
|
794
804
|
* The `Interrupt.metadata` key under which this package's resume binding
|
|
795
805
|
* travels.
|
|
@@ -910,7 +920,7 @@ function readInterruptBinding(descriptor) {
|
|
|
910
920
|
};
|
|
911
921
|
}
|
|
912
922
|
//#endregion
|
|
913
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
923
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/interrupt-definition.js
|
|
914
924
|
var INTERRUPT_PAYLOAD_METADATA_KEY = "tanstack:interruptPayload";
|
|
915
925
|
function schemaJson(schema, name) {
|
|
916
926
|
if (!isStandardJSONSchema(schema)) throw new TypeError(`${name} must be a Standard Schema with a JSON Schema converter.`);
|
|
@@ -935,7 +945,7 @@ function hashInterruptDefinitionSchema(schema) {
|
|
|
935
945
|
return digestInterruptJson(schemaJson(schema, "Interrupt schema").canonicalJson);
|
|
936
946
|
}
|
|
937
947
|
//#endregion
|
|
938
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
948
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/generic-interrupt-continuation.js
|
|
939
949
|
/**
|
|
940
950
|
* `ResumeEntry.metadata` key for a first-party generic request.
|
|
941
951
|
*
|
|
@@ -974,7 +984,7 @@ function genericInterruptContinuationFromDescriptor(interrupt) {
|
|
|
974
984
|
};
|
|
975
985
|
}
|
|
976
986
|
//#endregion
|
|
977
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
987
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/utilities/provider-executed.js
|
|
978
988
|
/**
|
|
979
989
|
* Narrow a tool call's opaque `metadata` to the provider-executed convention.
|
|
980
990
|
* Returns the typed metadata when the call is provider-executed, else `null`.
|
|
@@ -1004,7 +1014,7 @@ function isAssistantSegmentOf(id, parentId) {
|
|
|
1004
1014
|
return id?.startsWith(`${parentId}-segment-`) === true;
|
|
1005
1015
|
}
|
|
1006
1016
|
//#endregion
|
|
1007
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
1017
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/utilities/tool-result.js
|
|
1008
1018
|
var CONTENT_PART_TYPES = /* @__PURE__ */ new Set([
|
|
1009
1019
|
"text",
|
|
1010
1020
|
"image",
|
|
@@ -1065,7 +1075,7 @@ function normalizeToolResult(result) {
|
|
|
1065
1075
|
return JSON.stringify(result);
|
|
1066
1076
|
}
|
|
1067
1077
|
//#endregion
|
|
1068
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
1078
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/utilities/subagent-wire.js
|
|
1069
1079
|
function isRecord$2(value) {
|
|
1070
1080
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1071
1081
|
}
|
|
@@ -1169,7 +1179,7 @@ function splitSubagentWire(messages) {
|
|
|
1169
1179
|
};
|
|
1170
1180
|
}
|
|
1171
1181
|
//#endregion
|
|
1172
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
1182
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/activities/chat/messages.js
|
|
1173
1183
|
function isRecord$1(value) {
|
|
1174
1184
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1175
1185
|
}
|
|
@@ -1362,6 +1372,7 @@ function assistantMetadata(uiMessage) {
|
|
|
1362
1372
|
*/
|
|
1363
1373
|
function uiMessageToModelMessages(uiMessage) {
|
|
1364
1374
|
if (uiMessage.role === "system") return [];
|
|
1375
|
+
if (uiMessage.role === "activity") return [];
|
|
1365
1376
|
if (uiMessage.role !== "assistant") return [buildUserOrToolMessage(uiMessage)];
|
|
1366
1377
|
return buildAssistantMessages(uiMessage);
|
|
1367
1378
|
}
|
|
@@ -1491,6 +1502,7 @@ function buildAssistantMessages(uiMessage) {
|
|
|
1491
1502
|
}
|
|
1492
1503
|
break;
|
|
1493
1504
|
case "ui-resource": break;
|
|
1505
|
+
case "activity": break;
|
|
1494
1506
|
case "subagent": {
|
|
1495
1507
|
const block = part.subagent.parentToolCallId === void 0 ? subagentHistoryText(part) : "";
|
|
1496
1508
|
if (block !== "") {
|
|
@@ -1707,6 +1719,15 @@ function aguiSnapshotMessageToUIMessage(message) {
|
|
|
1707
1719
|
}] : []
|
|
1708
1720
|
});
|
|
1709
1721
|
}
|
|
1722
|
+
case "activity": return applySnapshotMetadata(message, {
|
|
1723
|
+
id,
|
|
1724
|
+
role: "activity",
|
|
1725
|
+
parts: [{
|
|
1726
|
+
type: "activity",
|
|
1727
|
+
activityType: message.activityType,
|
|
1728
|
+
content: structuredClone(message.content)
|
|
1729
|
+
}]
|
|
1730
|
+
});
|
|
1710
1731
|
default: return applySnapshotMetadata(message, {
|
|
1711
1732
|
id,
|
|
1712
1733
|
role: "assistant",
|
|
@@ -1752,15 +1773,23 @@ function applySnapshotMetadata(source, ui) {
|
|
|
1752
1773
|
}
|
|
1753
1774
|
function snapshotStructuredOutput(value) {
|
|
1754
1775
|
if (value == null || value.status !== "streaming" && value.status !== "complete" && value.status !== "error" || typeof value.raw !== "string") return;
|
|
1755
|
-
|
|
1776
|
+
const base = {
|
|
1756
1777
|
type: "structured-output",
|
|
1757
|
-
status: value.status,
|
|
1758
1778
|
raw: value.raw,
|
|
1759
1779
|
...value.partial !== void 0 ? { partial: value.partial } : {},
|
|
1760
|
-
...value.data !== void 0 ? { data: value.data } : {},
|
|
1761
1780
|
...value.reasoning ? { reasoning: value.reasoning } : {},
|
|
1762
1781
|
...value.errorMessage !== void 0 ? { errorMessage: value.errorMessage } : {}
|
|
1763
1782
|
};
|
|
1783
|
+
if (value.status !== "complete") return {
|
|
1784
|
+
...base,
|
|
1785
|
+
status: value.status
|
|
1786
|
+
};
|
|
1787
|
+
if (value.data === void 0) return void 0;
|
|
1788
|
+
return {
|
|
1789
|
+
...base,
|
|
1790
|
+
status: "complete",
|
|
1791
|
+
data: value.data
|
|
1792
|
+
};
|
|
1764
1793
|
}
|
|
1765
1794
|
/**
|
|
1766
1795
|
* Convert AG-UI user message content into `UIMessage` parts.
|
|
@@ -1818,7 +1847,7 @@ function generateMessageId() {
|
|
|
1818
1847
|
return `msg-${Date.now()}-${Math.random().toString(36).substring(7)}`;
|
|
1819
1848
|
}
|
|
1820
1849
|
//#endregion
|
|
1821
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
1850
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/utilities/ag-ui-wire.js
|
|
1822
1851
|
function isRecord(value) {
|
|
1823
1852
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1824
1853
|
}
|
|
@@ -1849,15 +1878,35 @@ function rebuiltToolMetadata(metadata, createdAt, id, content, anchorOwnsUiResou
|
|
|
1849
1878
|
* on assistant messages are additionally emitted as fan-out
|
|
1850
1879
|
* `{role:'tool',...}` and `{role:'reasoning',...}` entries for strict AG-UI
|
|
1851
1880
|
* server consumers. Set `includeSnapshotStructuredOutput` to retain complete
|
|
1852
|
-
* structured-output metadata for UI snapshots.
|
|
1881
|
+
* structured-output metadata for UI snapshots. Set `includeActivity` to emit
|
|
1882
|
+
* AG-UI `ActivityMessage` rows (MESSAGES_SNAPSHOT only — default omit so
|
|
1883
|
+
* RunAgentInput never carries activity).
|
|
1853
1884
|
*/
|
|
1854
1885
|
function uiMessagesToWire(messages, options) {
|
|
1855
1886
|
const wire = [];
|
|
1856
1887
|
const usedWireIds = new Set(messages.flatMap((message) => "id" in message && message.id && message.role !== "tool" ? [message.id] : []));
|
|
1857
1888
|
const includeSnapshotStructuredOutput = options?.includeSnapshotStructuredOutput ?? false;
|
|
1889
|
+
const includeActivity = options?.includeActivity ?? false;
|
|
1858
1890
|
const assistantIds = /* @__PURE__ */ new Set();
|
|
1859
1891
|
for (const msg of messages) if (msg.role === "assistant" && msg.id !== void 0) assistantIds.add(msg.id);
|
|
1860
1892
|
for (const msg of messages) {
|
|
1893
|
+
if (msg.role === "activity") {
|
|
1894
|
+
if (includeActivity && "parts" in msg) {
|
|
1895
|
+
const part = msg.parts.find((p) => p.type === "activity");
|
|
1896
|
+
if (part) {
|
|
1897
|
+
const activity = {
|
|
1898
|
+
id: msg.id,
|
|
1899
|
+
role: "activity",
|
|
1900
|
+
activityType: part.activityType,
|
|
1901
|
+
content: structuredClone(part.content),
|
|
1902
|
+
...msg.metadata != null && { metadata: msg.metadata },
|
|
1903
|
+
...part.subagentRunId !== void 0 && { subagentRunId: part.subagentRunId }
|
|
1904
|
+
};
|
|
1905
|
+
wire.push(activity);
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
continue;
|
|
1909
|
+
}
|
|
1861
1910
|
if (!("parts" in msg) && msg.role === "tool" && msg.toolCallId) {
|
|
1862
1911
|
const id = uniqueToolWireId(toolWireId(msg.id, msg.toolCallId, assistantIds), usedWireIds);
|
|
1863
1912
|
const metadata = rebuiltToolMetadata(msg.metadata, msg.createdAt, msg.id, msg.content);
|
|
@@ -2132,7 +2181,7 @@ function hashContent(s) {
|
|
|
2132
2181
|
return Math.abs(h).toString(36);
|
|
2133
2182
|
}
|
|
2134
2183
|
//#endregion
|
|
2135
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
2184
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/utilities/restore-inbound-chunk.js
|
|
2136
2185
|
/**
|
|
2137
2186
|
* Rebuild TanStack `TokenUsage` (`promptTokens`) from spec `usage[]` plus
|
|
2138
2187
|
* leftover fields in `metadata.tanstack.usage`. Restore in-process aliases
|
|
@@ -2169,7 +2218,7 @@ function restoreInboundChunk(chunk) {
|
|
|
2169
2218
|
return next;
|
|
2170
2219
|
}
|
|
2171
2220
|
//#endregion
|
|
2172
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
2221
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/activities/chat/tools/tool-definition.js
|
|
2173
2222
|
/**
|
|
2174
2223
|
* Create an isomorphic tool definition that can be used directly or instantiated for server/client
|
|
2175
2224
|
*
|
|
@@ -2267,7 +2316,7 @@ function toolDefinition(config) {
|
|
|
2267
2316
|
};
|
|
2268
2317
|
}
|
|
2269
2318
|
//#endregion
|
|
2270
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
2319
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/utilities/chunk-ids.js
|
|
2271
2320
|
function stringField(value) {
|
|
2272
2321
|
return typeof value === "string" && value !== "" ? value : void 0;
|
|
2273
2322
|
}
|
|
@@ -2370,7 +2419,7 @@ var require_options = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
2370
2419
|
exports.default = exports.Allow;
|
|
2371
2420
|
}));
|
|
2372
2421
|
//#endregion
|
|
2373
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
2422
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/activities/chat/stream/json-parser.js
|
|
2374
2423
|
var import_dist = (/* @__PURE__ */ __commonJSMin(((exports) => {
|
|
2375
2424
|
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
2376
2425
|
if (k2 === void 0) k2 = k;
|
|
@@ -2592,7 +2641,7 @@ function parsePartialJSON(jsonString) {
|
|
|
2592
2641
|
return defaultJSONParser.parse(jsonString);
|
|
2593
2642
|
}
|
|
2594
2643
|
//#endregion
|
|
2595
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
2644
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/activities/chat/stream/strategies.js
|
|
2596
2645
|
/**
|
|
2597
2646
|
* Immediate Strategy - emit on every chunk (default behavior)
|
|
2598
2647
|
*/
|
|
@@ -2602,7 +2651,7 @@ var ImmediateStrategy = class {
|
|
|
2602
2651
|
}
|
|
2603
2652
|
};
|
|
2604
2653
|
//#endregion
|
|
2605
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
2654
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/utilities/errors.js
|
|
2606
2655
|
/**
|
|
2607
2656
|
* Convert an AG-UI RUN_ERROR event to the Error shape exposed to consumers.
|
|
2608
2657
|
* Preserves the provider code and sanitized raw event when available, while
|
|
@@ -2616,7 +2665,730 @@ function runErrorEventToError(chunk) {
|
|
|
2616
2665
|
return error;
|
|
2617
2666
|
}
|
|
2618
2667
|
//#endregion
|
|
2619
|
-
//#region node_modules/.deno
|
|
2668
|
+
//#region node_modules/.deno/fast-json-patch@3.1.1/node_modules/fast-json-patch/module/helpers.mjs
|
|
2669
|
+
/*!
|
|
2670
|
+
* https://github.com/Starcounter-Jack/JSON-Patch
|
|
2671
|
+
* (c) 2017-2022 Joachim Wester
|
|
2672
|
+
* MIT licensed
|
|
2673
|
+
*/
|
|
2674
|
+
var __extends = (function() {
|
|
2675
|
+
var extendStatics = function(d, b) {
|
|
2676
|
+
extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d, b) {
|
|
2677
|
+
d.__proto__ = b;
|
|
2678
|
+
} || function(d, b) {
|
|
2679
|
+
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
|
2680
|
+
};
|
|
2681
|
+
return extendStatics(d, b);
|
|
2682
|
+
};
|
|
2683
|
+
return function(d, b) {
|
|
2684
|
+
extendStatics(d, b);
|
|
2685
|
+
function __() {
|
|
2686
|
+
this.constructor = d;
|
|
2687
|
+
}
|
|
2688
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
2689
|
+
};
|
|
2690
|
+
})();
|
|
2691
|
+
var _hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
2692
|
+
function hasOwnProperty(obj, key) {
|
|
2693
|
+
return _hasOwnProperty.call(obj, key);
|
|
2694
|
+
}
|
|
2695
|
+
function _objectKeys(obj) {
|
|
2696
|
+
if (Array.isArray(obj)) {
|
|
2697
|
+
var keys_1 = new Array(obj.length);
|
|
2698
|
+
for (var k = 0; k < keys_1.length; k++) keys_1[k] = "" + k;
|
|
2699
|
+
return keys_1;
|
|
2700
|
+
}
|
|
2701
|
+
if (Object.keys) return Object.keys(obj);
|
|
2702
|
+
var keys = [];
|
|
2703
|
+
for (var i in obj) if (hasOwnProperty(obj, i)) keys.push(i);
|
|
2704
|
+
return keys;
|
|
2705
|
+
}
|
|
2706
|
+
/**
|
|
2707
|
+
* Deeply clone the object.
|
|
2708
|
+
* https://jsperf.com/deep-copy-vs-json-stringify-json-parse/25 (recursiveDeepCopy)
|
|
2709
|
+
* @param {any} obj value to clone
|
|
2710
|
+
* @return {any} cloned obj
|
|
2711
|
+
*/
|
|
2712
|
+
function _deepClone(obj) {
|
|
2713
|
+
switch (typeof obj) {
|
|
2714
|
+
case "object": return JSON.parse(JSON.stringify(obj));
|
|
2715
|
+
case "undefined": return null;
|
|
2716
|
+
default: return obj;
|
|
2717
|
+
}
|
|
2718
|
+
}
|
|
2719
|
+
function isInteger(str) {
|
|
2720
|
+
var i = 0;
|
|
2721
|
+
var len = str.length;
|
|
2722
|
+
var charCode;
|
|
2723
|
+
while (i < len) {
|
|
2724
|
+
charCode = str.charCodeAt(i);
|
|
2725
|
+
if (charCode >= 48 && charCode <= 57) {
|
|
2726
|
+
i++;
|
|
2727
|
+
continue;
|
|
2728
|
+
}
|
|
2729
|
+
return false;
|
|
2730
|
+
}
|
|
2731
|
+
return true;
|
|
2732
|
+
}
|
|
2733
|
+
/**
|
|
2734
|
+
* Escapes a json pointer path
|
|
2735
|
+
* @param path The raw pointer
|
|
2736
|
+
* @return the Escaped path
|
|
2737
|
+
*/
|
|
2738
|
+
function escapePathComponent(path) {
|
|
2739
|
+
if (path.indexOf("/") === -1 && path.indexOf("~") === -1) return path;
|
|
2740
|
+
return path.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
2741
|
+
}
|
|
2742
|
+
/**
|
|
2743
|
+
* Unescapes a json pointer path
|
|
2744
|
+
* @param path The escaped pointer
|
|
2745
|
+
* @return The unescaped path
|
|
2746
|
+
*/
|
|
2747
|
+
function unescapePathComponent(path) {
|
|
2748
|
+
return path.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
2749
|
+
}
|
|
2750
|
+
/**
|
|
2751
|
+
* Recursively checks whether an object has any undefined values inside.
|
|
2752
|
+
*/
|
|
2753
|
+
function hasUndefined(obj) {
|
|
2754
|
+
if (obj === void 0) return true;
|
|
2755
|
+
if (obj) {
|
|
2756
|
+
if (Array.isArray(obj)) {
|
|
2757
|
+
for (var i_1 = 0, len = obj.length; i_1 < len; i_1++) if (hasUndefined(obj[i_1])) return true;
|
|
2758
|
+
} else if (typeof obj === "object") {
|
|
2759
|
+
var objKeys = _objectKeys(obj);
|
|
2760
|
+
var objKeysLength = objKeys.length;
|
|
2761
|
+
for (var i = 0; i < objKeysLength; i++) if (hasUndefined(obj[objKeys[i]])) return true;
|
|
2762
|
+
}
|
|
2763
|
+
}
|
|
2764
|
+
return false;
|
|
2765
|
+
}
|
|
2766
|
+
function patchErrorMessageFormatter(message, args) {
|
|
2767
|
+
var messageParts = [message];
|
|
2768
|
+
for (var key in args) {
|
|
2769
|
+
var value = typeof args[key] === "object" ? JSON.stringify(args[key], null, 2) : args[key];
|
|
2770
|
+
if (typeof value !== "undefined") messageParts.push(key + ": " + value);
|
|
2771
|
+
}
|
|
2772
|
+
return messageParts.join("\n");
|
|
2773
|
+
}
|
|
2774
|
+
var PatchError = function(_super) {
|
|
2775
|
+
__extends(PatchError, _super);
|
|
2776
|
+
function PatchError(message, name, index, operation, tree) {
|
|
2777
|
+
var _newTarget = this.constructor;
|
|
2778
|
+
var _this = _super.call(this, patchErrorMessageFormatter(message, {
|
|
2779
|
+
name,
|
|
2780
|
+
index,
|
|
2781
|
+
operation,
|
|
2782
|
+
tree
|
|
2783
|
+
})) || this;
|
|
2784
|
+
_this.name = name;
|
|
2785
|
+
_this.index = index;
|
|
2786
|
+
_this.operation = operation;
|
|
2787
|
+
_this.tree = tree;
|
|
2788
|
+
Object.setPrototypeOf(_this, _newTarget.prototype);
|
|
2789
|
+
_this.message = patchErrorMessageFormatter(message, {
|
|
2790
|
+
name,
|
|
2791
|
+
index,
|
|
2792
|
+
operation,
|
|
2793
|
+
tree
|
|
2794
|
+
});
|
|
2795
|
+
return _this;
|
|
2796
|
+
}
|
|
2797
|
+
return PatchError;
|
|
2798
|
+
}(Error);
|
|
2799
|
+
//#endregion
|
|
2800
|
+
//#region node_modules/.deno/fast-json-patch@3.1.1/node_modules/fast-json-patch/module/core.mjs
|
|
2801
|
+
var core_exports = /* @__PURE__ */ __exportAll({
|
|
2802
|
+
JsonPatchError: () => JsonPatchError,
|
|
2803
|
+
_areEquals: () => _areEquals,
|
|
2804
|
+
applyOperation: () => applyOperation,
|
|
2805
|
+
applyPatch: () => applyPatch,
|
|
2806
|
+
applyReducer: () => applyReducer,
|
|
2807
|
+
deepClone: () => deepClone,
|
|
2808
|
+
getValueByPointer: () => getValueByPointer,
|
|
2809
|
+
validate: () => validate,
|
|
2810
|
+
validator: () => validator
|
|
2811
|
+
});
|
|
2812
|
+
var JsonPatchError = PatchError;
|
|
2813
|
+
var deepClone = _deepClone;
|
|
2814
|
+
var objOps = {
|
|
2815
|
+
add: function(obj, key, document) {
|
|
2816
|
+
obj[key] = this.value;
|
|
2817
|
+
return { newDocument: document };
|
|
2818
|
+
},
|
|
2819
|
+
remove: function(obj, key, document) {
|
|
2820
|
+
var removed = obj[key];
|
|
2821
|
+
delete obj[key];
|
|
2822
|
+
return {
|
|
2823
|
+
newDocument: document,
|
|
2824
|
+
removed
|
|
2825
|
+
};
|
|
2826
|
+
},
|
|
2827
|
+
replace: function(obj, key, document) {
|
|
2828
|
+
var removed = obj[key];
|
|
2829
|
+
obj[key] = this.value;
|
|
2830
|
+
return {
|
|
2831
|
+
newDocument: document,
|
|
2832
|
+
removed
|
|
2833
|
+
};
|
|
2834
|
+
},
|
|
2835
|
+
move: function(obj, key, document) {
|
|
2836
|
+
var removed = getValueByPointer(document, this.path);
|
|
2837
|
+
if (removed) removed = _deepClone(removed);
|
|
2838
|
+
var originalValue = applyOperation(document, {
|
|
2839
|
+
op: "remove",
|
|
2840
|
+
path: this.from
|
|
2841
|
+
}).removed;
|
|
2842
|
+
applyOperation(document, {
|
|
2843
|
+
op: "add",
|
|
2844
|
+
path: this.path,
|
|
2845
|
+
value: originalValue
|
|
2846
|
+
});
|
|
2847
|
+
return {
|
|
2848
|
+
newDocument: document,
|
|
2849
|
+
removed
|
|
2850
|
+
};
|
|
2851
|
+
},
|
|
2852
|
+
copy: function(obj, key, document) {
|
|
2853
|
+
var valueToCopy = getValueByPointer(document, this.from);
|
|
2854
|
+
applyOperation(document, {
|
|
2855
|
+
op: "add",
|
|
2856
|
+
path: this.path,
|
|
2857
|
+
value: _deepClone(valueToCopy)
|
|
2858
|
+
});
|
|
2859
|
+
return { newDocument: document };
|
|
2860
|
+
},
|
|
2861
|
+
test: function(obj, key, document) {
|
|
2862
|
+
return {
|
|
2863
|
+
newDocument: document,
|
|
2864
|
+
test: _areEquals(obj[key], this.value)
|
|
2865
|
+
};
|
|
2866
|
+
},
|
|
2867
|
+
_get: function(obj, key, document) {
|
|
2868
|
+
this.value = obj[key];
|
|
2869
|
+
return { newDocument: document };
|
|
2870
|
+
}
|
|
2871
|
+
};
|
|
2872
|
+
var arrOps = {
|
|
2873
|
+
add: function(arr, i, document) {
|
|
2874
|
+
if (isInteger(i)) arr.splice(i, 0, this.value);
|
|
2875
|
+
else arr[i] = this.value;
|
|
2876
|
+
return {
|
|
2877
|
+
newDocument: document,
|
|
2878
|
+
index: i
|
|
2879
|
+
};
|
|
2880
|
+
},
|
|
2881
|
+
remove: function(arr, i, document) {
|
|
2882
|
+
return {
|
|
2883
|
+
newDocument: document,
|
|
2884
|
+
removed: arr.splice(i, 1)[0]
|
|
2885
|
+
};
|
|
2886
|
+
},
|
|
2887
|
+
replace: function(arr, i, document) {
|
|
2888
|
+
var removed = arr[i];
|
|
2889
|
+
arr[i] = this.value;
|
|
2890
|
+
return {
|
|
2891
|
+
newDocument: document,
|
|
2892
|
+
removed
|
|
2893
|
+
};
|
|
2894
|
+
},
|
|
2895
|
+
move: objOps.move,
|
|
2896
|
+
copy: objOps.copy,
|
|
2897
|
+
test: objOps.test,
|
|
2898
|
+
_get: objOps._get
|
|
2899
|
+
};
|
|
2900
|
+
/**
|
|
2901
|
+
* Retrieves a value from a JSON document by a JSON pointer.
|
|
2902
|
+
* Returns the value.
|
|
2903
|
+
*
|
|
2904
|
+
* @param document The document to get the value from
|
|
2905
|
+
* @param pointer an escaped JSON pointer
|
|
2906
|
+
* @return The retrieved value
|
|
2907
|
+
*/
|
|
2908
|
+
function getValueByPointer(document, pointer) {
|
|
2909
|
+
if (pointer == "") return document;
|
|
2910
|
+
var getOriginalDestination = {
|
|
2911
|
+
op: "_get",
|
|
2912
|
+
path: pointer
|
|
2913
|
+
};
|
|
2914
|
+
applyOperation(document, getOriginalDestination);
|
|
2915
|
+
return getOriginalDestination.value;
|
|
2916
|
+
}
|
|
2917
|
+
/**
|
|
2918
|
+
* Apply a single JSON Patch Operation on a JSON document.
|
|
2919
|
+
* Returns the {newDocument, result} of the operation.
|
|
2920
|
+
* It modifies the `document` and `operation` objects - it gets the values by reference.
|
|
2921
|
+
* If you would like to avoid touching your values, clone them:
|
|
2922
|
+
* `jsonpatch.applyOperation(document, jsonpatch._deepClone(operation))`.
|
|
2923
|
+
*
|
|
2924
|
+
* @param document The document to patch
|
|
2925
|
+
* @param operation The operation to apply
|
|
2926
|
+
* @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.
|
|
2927
|
+
* @param mutateDocument Whether to mutate the original document or clone it before applying
|
|
2928
|
+
* @param banPrototypeModifications Whether to ban modifications to `__proto__`, defaults to `true`.
|
|
2929
|
+
* @return `{newDocument, result}` after the operation
|
|
2930
|
+
*/
|
|
2931
|
+
function applyOperation(document, operation, validateOperation, mutateDocument, banPrototypeModifications, index) {
|
|
2932
|
+
if (validateOperation === void 0) validateOperation = false;
|
|
2933
|
+
if (mutateDocument === void 0) mutateDocument = true;
|
|
2934
|
+
if (banPrototypeModifications === void 0) banPrototypeModifications = true;
|
|
2935
|
+
if (index === void 0) index = 0;
|
|
2936
|
+
if (validateOperation) if (typeof validateOperation == "function") validateOperation(operation, 0, document, operation.path);
|
|
2937
|
+
else validator(operation, 0);
|
|
2938
|
+
if (operation.path === "") {
|
|
2939
|
+
var returnValue = { newDocument: document };
|
|
2940
|
+
if (operation.op === "add") {
|
|
2941
|
+
returnValue.newDocument = operation.value;
|
|
2942
|
+
return returnValue;
|
|
2943
|
+
} else if (operation.op === "replace") {
|
|
2944
|
+
returnValue.newDocument = operation.value;
|
|
2945
|
+
returnValue.removed = document;
|
|
2946
|
+
return returnValue;
|
|
2947
|
+
} else if (operation.op === "move" || operation.op === "copy") {
|
|
2948
|
+
returnValue.newDocument = getValueByPointer(document, operation.from);
|
|
2949
|
+
if (operation.op === "move") returnValue.removed = document;
|
|
2950
|
+
return returnValue;
|
|
2951
|
+
} else if (operation.op === "test") {
|
|
2952
|
+
returnValue.test = _areEquals(document, operation.value);
|
|
2953
|
+
if (returnValue.test === false) throw new JsonPatchError("Test operation failed", "TEST_OPERATION_FAILED", index, operation, document);
|
|
2954
|
+
returnValue.newDocument = document;
|
|
2955
|
+
return returnValue;
|
|
2956
|
+
} else if (operation.op === "remove") {
|
|
2957
|
+
returnValue.removed = document;
|
|
2958
|
+
returnValue.newDocument = null;
|
|
2959
|
+
return returnValue;
|
|
2960
|
+
} else if (operation.op === "_get") {
|
|
2961
|
+
operation.value = document;
|
|
2962
|
+
return returnValue;
|
|
2963
|
+
} else if (validateOperation) throw new JsonPatchError("Operation `op` property is not one of operations defined in RFC-6902", "OPERATION_OP_INVALID", index, operation, document);
|
|
2964
|
+
else return returnValue;
|
|
2965
|
+
} else {
|
|
2966
|
+
if (!mutateDocument) document = _deepClone(document);
|
|
2967
|
+
var keys = (operation.path || "").split("/");
|
|
2968
|
+
var obj = document;
|
|
2969
|
+
var t = 1;
|
|
2970
|
+
var len = keys.length;
|
|
2971
|
+
var existingPathFragment = void 0;
|
|
2972
|
+
var key = void 0;
|
|
2973
|
+
var validateFunction = void 0;
|
|
2974
|
+
if (typeof validateOperation == "function") validateFunction = validateOperation;
|
|
2975
|
+
else validateFunction = validator;
|
|
2976
|
+
while (true) {
|
|
2977
|
+
key = keys[t];
|
|
2978
|
+
if (key && key.indexOf("~") != -1) key = unescapePathComponent(key);
|
|
2979
|
+
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");
|
|
2980
|
+
if (validateOperation) {
|
|
2981
|
+
if (existingPathFragment === void 0) {
|
|
2982
|
+
if (obj[key] === void 0) existingPathFragment = keys.slice(0, t).join("/");
|
|
2983
|
+
else if (t == len - 1) existingPathFragment = operation.path;
|
|
2984
|
+
if (existingPathFragment !== void 0) validateFunction(operation, 0, document, existingPathFragment);
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
2987
|
+
t++;
|
|
2988
|
+
if (Array.isArray(obj)) {
|
|
2989
|
+
if (key === "-") key = obj.length;
|
|
2990
|
+
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);
|
|
2991
|
+
else if (isInteger(key)) key = ~~key;
|
|
2992
|
+
if (t >= len) {
|
|
2993
|
+
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);
|
|
2994
|
+
var returnValue = arrOps[operation.op].call(operation, obj, key, document);
|
|
2995
|
+
if (returnValue.test === false) throw new JsonPatchError("Test operation failed", "TEST_OPERATION_FAILED", index, operation, document);
|
|
2996
|
+
return returnValue;
|
|
2997
|
+
}
|
|
2998
|
+
} else if (t >= len) {
|
|
2999
|
+
var returnValue = objOps[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
|
+
obj = obj[key];
|
|
3004
|
+
if (validateOperation && t < len && (!obj || typeof obj !== "object")) throw new JsonPatchError("Cannot perform operation at the desired path", "OPERATION_PATH_UNRESOLVABLE", index, operation, document);
|
|
3005
|
+
}
|
|
3006
|
+
}
|
|
3007
|
+
}
|
|
3008
|
+
/**
|
|
3009
|
+
* Apply a full JSON Patch array on a JSON document.
|
|
3010
|
+
* Returns the {newDocument, result} of the patch.
|
|
3011
|
+
* It modifies the `document` object and `patch` - it gets the values by reference.
|
|
3012
|
+
* If you would like to avoid touching your values, clone them:
|
|
3013
|
+
* `jsonpatch.applyPatch(document, jsonpatch._deepClone(patch))`.
|
|
3014
|
+
*
|
|
3015
|
+
* @param document The document to patch
|
|
3016
|
+
* @param patch The patch to apply
|
|
3017
|
+
* @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.
|
|
3018
|
+
* @param mutateDocument Whether to mutate the original document or clone it before applying
|
|
3019
|
+
* @param banPrototypeModifications Whether to ban modifications to `__proto__`, defaults to `true`.
|
|
3020
|
+
* @return An array of `{newDocument, result}` after the patch
|
|
3021
|
+
*/
|
|
3022
|
+
function applyPatch(document, patch, validateOperation, mutateDocument, banPrototypeModifications) {
|
|
3023
|
+
if (mutateDocument === void 0) mutateDocument = true;
|
|
3024
|
+
if (banPrototypeModifications === void 0) banPrototypeModifications = true;
|
|
3025
|
+
if (validateOperation) {
|
|
3026
|
+
if (!Array.isArray(patch)) throw new JsonPatchError("Patch sequence must be an array", "SEQUENCE_NOT_AN_ARRAY");
|
|
3027
|
+
}
|
|
3028
|
+
if (!mutateDocument) document = _deepClone(document);
|
|
3029
|
+
var results = new Array(patch.length);
|
|
3030
|
+
for (var i = 0, length_1 = patch.length; i < length_1; i++) {
|
|
3031
|
+
results[i] = applyOperation(document, patch[i], validateOperation, true, banPrototypeModifications, i);
|
|
3032
|
+
document = results[i].newDocument;
|
|
3033
|
+
}
|
|
3034
|
+
results.newDocument = document;
|
|
3035
|
+
return results;
|
|
3036
|
+
}
|
|
3037
|
+
/**
|
|
3038
|
+
* Apply a single JSON Patch Operation on a JSON document.
|
|
3039
|
+
* Returns the updated document.
|
|
3040
|
+
* Suitable as a reducer.
|
|
3041
|
+
*
|
|
3042
|
+
* @param document The document to patch
|
|
3043
|
+
* @param operation The operation to apply
|
|
3044
|
+
* @return The updated document
|
|
3045
|
+
*/
|
|
3046
|
+
function applyReducer(document, operation, index) {
|
|
3047
|
+
var operationResult = applyOperation(document, operation);
|
|
3048
|
+
if (operationResult.test === false) throw new JsonPatchError("Test operation failed", "TEST_OPERATION_FAILED", index, operation, document);
|
|
3049
|
+
return operationResult.newDocument;
|
|
3050
|
+
}
|
|
3051
|
+
/**
|
|
3052
|
+
* Validates a single operation. Called from `jsonpatch.validate`. Throws `JsonPatchError` in case of an error.
|
|
3053
|
+
* @param {object} operation - operation object (patch)
|
|
3054
|
+
* @param {number} index - index of operation in the sequence
|
|
3055
|
+
* @param {object} [document] - object where the operation is supposed to be applied
|
|
3056
|
+
* @param {string} [existingPathFragment] - comes along with `document`
|
|
3057
|
+
*/
|
|
3058
|
+
function validator(operation, index, document, existingPathFragment) {
|
|
3059
|
+
if (typeof operation !== "object" || operation === null || Array.isArray(operation)) throw new JsonPatchError("Operation is not an object", "OPERATION_NOT_AN_OBJECT", index, operation, document);
|
|
3060
|
+
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);
|
|
3061
|
+
else if (typeof operation.path !== "string") throw new JsonPatchError("Operation `path` property is not a string", "OPERATION_PATH_INVALID", index, operation, document);
|
|
3062
|
+
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);
|
|
3063
|
+
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);
|
|
3064
|
+
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);
|
|
3065
|
+
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);
|
|
3066
|
+
else if (document) {
|
|
3067
|
+
if (operation.op == "add") {
|
|
3068
|
+
var pathLen = operation.path.split("/").length;
|
|
3069
|
+
var existingPathLen = existingPathFragment.split("/").length;
|
|
3070
|
+
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);
|
|
3071
|
+
} else if (operation.op === "replace" || operation.op === "remove" || operation.op === "_get") {
|
|
3072
|
+
if (operation.path !== existingPathFragment) throw new JsonPatchError("Cannot perform the operation at a path that does not exist", "OPERATION_PATH_UNRESOLVABLE", index, operation, document);
|
|
3073
|
+
} else if (operation.op === "move" || operation.op === "copy") {
|
|
3074
|
+
var error = validate([{
|
|
3075
|
+
op: "_get",
|
|
3076
|
+
path: operation.from,
|
|
3077
|
+
value: void 0
|
|
3078
|
+
}], document);
|
|
3079
|
+
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);
|
|
3080
|
+
}
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
3083
|
+
/**
|
|
3084
|
+
* Validates a sequence of operations. If `document` parameter is provided, the sequence is additionally validated against the object document.
|
|
3085
|
+
* If error is encountered, returns a JsonPatchError object
|
|
3086
|
+
* @param sequence
|
|
3087
|
+
* @param document
|
|
3088
|
+
* @returns {JsonPatchError|undefined}
|
|
3089
|
+
*/
|
|
3090
|
+
function validate(sequence, document, externalValidator) {
|
|
3091
|
+
try {
|
|
3092
|
+
if (!Array.isArray(sequence)) throw new JsonPatchError("Patch sequence must be an array", "SEQUENCE_NOT_AN_ARRAY");
|
|
3093
|
+
if (document) applyPatch(_deepClone(document), _deepClone(sequence), externalValidator || true);
|
|
3094
|
+
else {
|
|
3095
|
+
externalValidator = externalValidator || validator;
|
|
3096
|
+
for (var i = 0; i < sequence.length; i++) externalValidator(sequence[i], i, document, void 0);
|
|
3097
|
+
}
|
|
3098
|
+
} catch (e) {
|
|
3099
|
+
if (e instanceof JsonPatchError) return e;
|
|
3100
|
+
else throw e;
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3103
|
+
function _areEquals(a, b) {
|
|
3104
|
+
if (a === b) return true;
|
|
3105
|
+
if (a && b && typeof a == "object" && typeof b == "object") {
|
|
3106
|
+
var arrA = Array.isArray(a), arrB = Array.isArray(b), i, length, key;
|
|
3107
|
+
if (arrA && arrB) {
|
|
3108
|
+
length = a.length;
|
|
3109
|
+
if (length != b.length) return false;
|
|
3110
|
+
for (i = length; i-- !== 0;) if (!_areEquals(a[i], b[i])) return false;
|
|
3111
|
+
return true;
|
|
3112
|
+
}
|
|
3113
|
+
if (arrA != arrB) return false;
|
|
3114
|
+
var keys = Object.keys(a);
|
|
3115
|
+
length = keys.length;
|
|
3116
|
+
if (length !== Object.keys(b).length) return false;
|
|
3117
|
+
for (i = length; i-- !== 0;) if (!b.hasOwnProperty(keys[i])) return false;
|
|
3118
|
+
for (i = length; i-- !== 0;) {
|
|
3119
|
+
key = keys[i];
|
|
3120
|
+
if (!_areEquals(a[key], b[key])) return false;
|
|
3121
|
+
}
|
|
3122
|
+
return true;
|
|
3123
|
+
}
|
|
3124
|
+
return a !== a && b !== b;
|
|
3125
|
+
}
|
|
3126
|
+
//#endregion
|
|
3127
|
+
//#region node_modules/.deno/fast-json-patch@3.1.1/node_modules/fast-json-patch/module/duplex.mjs
|
|
3128
|
+
/*!
|
|
3129
|
+
* https://github.com/Starcounter-Jack/JSON-Patch
|
|
3130
|
+
* (c) 2017-2021 Joachim Wester
|
|
3131
|
+
* MIT license
|
|
3132
|
+
*/
|
|
3133
|
+
var duplex_exports = /* @__PURE__ */ __exportAll({
|
|
3134
|
+
compare: () => compare,
|
|
3135
|
+
generate: () => generate,
|
|
3136
|
+
observe: () => observe,
|
|
3137
|
+
unobserve: () => unobserve
|
|
3138
|
+
});
|
|
3139
|
+
var beforeDict = /* @__PURE__ */ new WeakMap();
|
|
3140
|
+
var Mirror = function() {
|
|
3141
|
+
function Mirror(obj) {
|
|
3142
|
+
this.observers = /* @__PURE__ */ new Map();
|
|
3143
|
+
this.obj = obj;
|
|
3144
|
+
}
|
|
3145
|
+
return Mirror;
|
|
3146
|
+
}();
|
|
3147
|
+
var ObserverInfo = function() {
|
|
3148
|
+
function ObserverInfo(callback, observer) {
|
|
3149
|
+
this.callback = callback;
|
|
3150
|
+
this.observer = observer;
|
|
3151
|
+
}
|
|
3152
|
+
return ObserverInfo;
|
|
3153
|
+
}();
|
|
3154
|
+
function getMirror(obj) {
|
|
3155
|
+
return beforeDict.get(obj);
|
|
3156
|
+
}
|
|
3157
|
+
function getObserverFromMirror(mirror, callback) {
|
|
3158
|
+
return mirror.observers.get(callback);
|
|
3159
|
+
}
|
|
3160
|
+
function removeObserverFromMirror(mirror, observer) {
|
|
3161
|
+
mirror.observers.delete(observer.callback);
|
|
3162
|
+
}
|
|
3163
|
+
/**
|
|
3164
|
+
* Detach an observer from an object
|
|
3165
|
+
*/
|
|
3166
|
+
function unobserve(root, observer) {
|
|
3167
|
+
observer.unobserve();
|
|
3168
|
+
}
|
|
3169
|
+
/**
|
|
3170
|
+
* Observes changes made to an object, which can then be retrieved using generate
|
|
3171
|
+
*/
|
|
3172
|
+
function observe(obj, callback) {
|
|
3173
|
+
var patches = [];
|
|
3174
|
+
var observer;
|
|
3175
|
+
var mirror = getMirror(obj);
|
|
3176
|
+
if (!mirror) {
|
|
3177
|
+
mirror = new Mirror(obj);
|
|
3178
|
+
beforeDict.set(obj, mirror);
|
|
3179
|
+
} else {
|
|
3180
|
+
var observerInfo = getObserverFromMirror(mirror, callback);
|
|
3181
|
+
observer = observerInfo && observerInfo.observer;
|
|
3182
|
+
}
|
|
3183
|
+
if (observer) return observer;
|
|
3184
|
+
observer = {};
|
|
3185
|
+
mirror.value = _deepClone(obj);
|
|
3186
|
+
if (callback) {
|
|
3187
|
+
observer.callback = callback;
|
|
3188
|
+
observer.next = null;
|
|
3189
|
+
var dirtyCheck = function() {
|
|
3190
|
+
generate(observer);
|
|
3191
|
+
};
|
|
3192
|
+
var fastCheck = function() {
|
|
3193
|
+
clearTimeout(observer.next);
|
|
3194
|
+
observer.next = setTimeout(dirtyCheck);
|
|
3195
|
+
};
|
|
3196
|
+
if (typeof window !== "undefined") {
|
|
3197
|
+
window.addEventListener("mouseup", fastCheck);
|
|
3198
|
+
window.addEventListener("keyup", fastCheck);
|
|
3199
|
+
window.addEventListener("mousedown", fastCheck);
|
|
3200
|
+
window.addEventListener("keydown", fastCheck);
|
|
3201
|
+
window.addEventListener("change", fastCheck);
|
|
3202
|
+
}
|
|
3203
|
+
}
|
|
3204
|
+
observer.patches = patches;
|
|
3205
|
+
observer.object = obj;
|
|
3206
|
+
observer.unobserve = function() {
|
|
3207
|
+
generate(observer);
|
|
3208
|
+
clearTimeout(observer.next);
|
|
3209
|
+
removeObserverFromMirror(mirror, observer);
|
|
3210
|
+
if (typeof window !== "undefined") {
|
|
3211
|
+
window.removeEventListener("mouseup", fastCheck);
|
|
3212
|
+
window.removeEventListener("keyup", fastCheck);
|
|
3213
|
+
window.removeEventListener("mousedown", fastCheck);
|
|
3214
|
+
window.removeEventListener("keydown", fastCheck);
|
|
3215
|
+
window.removeEventListener("change", fastCheck);
|
|
3216
|
+
}
|
|
3217
|
+
};
|
|
3218
|
+
mirror.observers.set(callback, new ObserverInfo(callback, observer));
|
|
3219
|
+
return observer;
|
|
3220
|
+
}
|
|
3221
|
+
/**
|
|
3222
|
+
* Generate an array of patches from an observer
|
|
3223
|
+
*/
|
|
3224
|
+
function generate(observer, invertible) {
|
|
3225
|
+
if (invertible === void 0) invertible = false;
|
|
3226
|
+
var mirror = beforeDict.get(observer.object);
|
|
3227
|
+
_generate(mirror.value, observer.object, observer.patches, "", invertible);
|
|
3228
|
+
if (observer.patches.length) applyPatch(mirror.value, observer.patches);
|
|
3229
|
+
var temp = observer.patches;
|
|
3230
|
+
if (temp.length > 0) {
|
|
3231
|
+
observer.patches = [];
|
|
3232
|
+
if (observer.callback) observer.callback(temp);
|
|
3233
|
+
}
|
|
3234
|
+
return temp;
|
|
3235
|
+
}
|
|
3236
|
+
function _generate(mirror, obj, patches, path, invertible) {
|
|
3237
|
+
if (obj === mirror) return;
|
|
3238
|
+
if (typeof obj.toJSON === "function") obj = obj.toJSON();
|
|
3239
|
+
var newKeys = _objectKeys(obj);
|
|
3240
|
+
var oldKeys = _objectKeys(mirror);
|
|
3241
|
+
var deleted = false;
|
|
3242
|
+
for (var t = oldKeys.length - 1; t >= 0; t--) {
|
|
3243
|
+
var key = oldKeys[t];
|
|
3244
|
+
var oldVal = mirror[key];
|
|
3245
|
+
if (hasOwnProperty(obj, key) && !(obj[key] === void 0 && oldVal !== void 0 && Array.isArray(obj) === false)) {
|
|
3246
|
+
var newVal = obj[key];
|
|
3247
|
+
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);
|
|
3248
|
+
else if (oldVal !== newVal) {
|
|
3249
|
+
if (invertible) patches.push({
|
|
3250
|
+
op: "test",
|
|
3251
|
+
path: path + "/" + escapePathComponent(key),
|
|
3252
|
+
value: _deepClone(oldVal)
|
|
3253
|
+
});
|
|
3254
|
+
patches.push({
|
|
3255
|
+
op: "replace",
|
|
3256
|
+
path: path + "/" + escapePathComponent(key),
|
|
3257
|
+
value: _deepClone(newVal)
|
|
3258
|
+
});
|
|
3259
|
+
}
|
|
3260
|
+
} else if (Array.isArray(mirror) === Array.isArray(obj)) {
|
|
3261
|
+
if (invertible) patches.push({
|
|
3262
|
+
op: "test",
|
|
3263
|
+
path: path + "/" + escapePathComponent(key),
|
|
3264
|
+
value: _deepClone(oldVal)
|
|
3265
|
+
});
|
|
3266
|
+
patches.push({
|
|
3267
|
+
op: "remove",
|
|
3268
|
+
path: path + "/" + escapePathComponent(key)
|
|
3269
|
+
});
|
|
3270
|
+
deleted = true;
|
|
3271
|
+
} else {
|
|
3272
|
+
if (invertible) patches.push({
|
|
3273
|
+
op: "test",
|
|
3274
|
+
path,
|
|
3275
|
+
value: mirror
|
|
3276
|
+
});
|
|
3277
|
+
patches.push({
|
|
3278
|
+
op: "replace",
|
|
3279
|
+
path,
|
|
3280
|
+
value: obj
|
|
3281
|
+
});
|
|
3282
|
+
}
|
|
3283
|
+
}
|
|
3284
|
+
if (!deleted && newKeys.length == oldKeys.length) return;
|
|
3285
|
+
for (var t = 0; t < newKeys.length; t++) {
|
|
3286
|
+
var key = newKeys[t];
|
|
3287
|
+
if (!hasOwnProperty(mirror, key) && obj[key] !== void 0) patches.push({
|
|
3288
|
+
op: "add",
|
|
3289
|
+
path: path + "/" + escapePathComponent(key),
|
|
3290
|
+
value: _deepClone(obj[key])
|
|
3291
|
+
});
|
|
3292
|
+
}
|
|
3293
|
+
}
|
|
3294
|
+
/**
|
|
3295
|
+
* Create an array of patches from the differences in two objects
|
|
3296
|
+
*/
|
|
3297
|
+
function compare(tree1, tree2, invertible) {
|
|
3298
|
+
if (invertible === void 0) invertible = false;
|
|
3299
|
+
var patches = [];
|
|
3300
|
+
_generate(tree1, tree2, patches, "", invertible);
|
|
3301
|
+
return patches;
|
|
3302
|
+
}
|
|
3303
|
+
//#endregion
|
|
3304
|
+
//#region node_modules/.deno/fast-json-patch@3.1.1/node_modules/fast-json-patch/index.mjs
|
|
3305
|
+
/**
|
|
3306
|
+
* Default export for backwards compat
|
|
3307
|
+
*/
|
|
3308
|
+
var fast_json_patch_default = Object.assign({}, core_exports, duplex_exports, {
|
|
3309
|
+
JsonPatchError: PatchError,
|
|
3310
|
+
deepClone: _deepClone,
|
|
3311
|
+
escapePathComponent,
|
|
3312
|
+
unescapePathComponent
|
|
3313
|
+
});
|
|
3314
|
+
//#endregion
|
|
3315
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/activities/chat/activity-records.js
|
|
3316
|
+
function isActivityPart(part) {
|
|
3317
|
+
return part.type === "activity";
|
|
3318
|
+
}
|
|
3319
|
+
function isActivityContent(value) {
|
|
3320
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
3321
|
+
}
|
|
3322
|
+
function applyActivitySnapshotToUIMessages(messages, chunk) {
|
|
3323
|
+
const { messageId, activityType, content } = chunk;
|
|
3324
|
+
const replace = chunk.replace ?? true;
|
|
3325
|
+
const existingIndex = messages.findIndex((m) => m.id === messageId);
|
|
3326
|
+
const existing = existingIndex >= 0 ? messages[existingIndex] : void 0;
|
|
3327
|
+
if (existing && existing.role !== "activity") {
|
|
3328
|
+
console.warn(`ACTIVITY_SNAPSHOT: Message '${messageId}' is not an activity message`);
|
|
3329
|
+
return messages;
|
|
3330
|
+
}
|
|
3331
|
+
if (existing && !replace) return messages;
|
|
3332
|
+
const metadata = mergeMetadata(existing?.role === "activity" ? existing.metadata : void 0, chunk.metadata);
|
|
3333
|
+
const next = {
|
|
3334
|
+
id: messageId,
|
|
3335
|
+
role: "activity",
|
|
3336
|
+
parts: [{
|
|
3337
|
+
type: "activity",
|
|
3338
|
+
activityType,
|
|
3339
|
+
content: structuredClone(content ?? {})
|
|
3340
|
+
}],
|
|
3341
|
+
...metadata != null ? { metadata } : {},
|
|
3342
|
+
...existing?.role === "activity" && existing.createdAt != null ? { createdAt: existing.createdAt } : {},
|
|
3343
|
+
...existing?.role === "activity" && existing.name != null ? { name: existing.name } : {}
|
|
3344
|
+
};
|
|
3345
|
+
if (existingIndex === -1) return [...messages, next];
|
|
3346
|
+
return messages.map((msg, index) => index === existingIndex ? next : msg);
|
|
3347
|
+
}
|
|
3348
|
+
function applyActivityDeltaToUIMessages(messages, chunk) {
|
|
3349
|
+
const { messageId, activityType, patch } = chunk;
|
|
3350
|
+
const existingIndex = messages.findIndex((m) => m.id === messageId);
|
|
3351
|
+
if (existingIndex === -1) {
|
|
3352
|
+
console.warn(`ACTIVITY_DELTA: No activity message '${messageId}'`);
|
|
3353
|
+
return messages;
|
|
3354
|
+
}
|
|
3355
|
+
const existing = messages[existingIndex];
|
|
3356
|
+
if (existing == null || existing.role !== "activity") {
|
|
3357
|
+
console.warn(`ACTIVITY_DELTA: Message '${messageId}' is not an activity message`);
|
|
3358
|
+
return messages;
|
|
3359
|
+
}
|
|
3360
|
+
const activityPart = existing.parts.find(isActivityPart);
|
|
3361
|
+
if (activityPart && activityPart.activityType !== activityType) {
|
|
3362
|
+
console.warn(`ACTIVITY_DELTA: activityType '${activityType}' does not match '${activityPart.activityType}' for '${messageId}'`);
|
|
3363
|
+
return messages;
|
|
3364
|
+
}
|
|
3365
|
+
const baseContent = structuredClone(activityPart?.content ?? {});
|
|
3366
|
+
try {
|
|
3367
|
+
const result = fast_json_patch_default.applyPatch(baseContent, patch ?? [], true, false);
|
|
3368
|
+
if (!isActivityContent(result.newDocument)) {
|
|
3369
|
+
console.warn(`ACTIVITY_DELTA: patched content for '${messageId}' is not an object`);
|
|
3370
|
+
return messages;
|
|
3371
|
+
}
|
|
3372
|
+
const nextPart = {
|
|
3373
|
+
type: "activity",
|
|
3374
|
+
activityType,
|
|
3375
|
+
content: structuredClone(result.newDocument)
|
|
3376
|
+
};
|
|
3377
|
+
const parts = activityPart ? existing.parts.map((part) => part.type === "activity" ? nextPart : part) : [nextPart];
|
|
3378
|
+
const metadata = mergeMetadata(existing.metadata, chunk.metadata);
|
|
3379
|
+
return messages.map((msg, index) => index === existingIndex ? {
|
|
3380
|
+
...msg,
|
|
3381
|
+
parts,
|
|
3382
|
+
...metadata != null ? { metadata } : {}
|
|
3383
|
+
} : msg);
|
|
3384
|
+
} catch (error) {
|
|
3385
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3386
|
+
console.warn(`Failed to apply activity patch for '${messageId}': ${errorMessage}`);
|
|
3387
|
+
return messages;
|
|
3388
|
+
}
|
|
3389
|
+
}
|
|
3390
|
+
//#endregion
|
|
3391
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/activities/chat/stream/message-updaters.js
|
|
2620
3392
|
/**
|
|
2621
3393
|
* Message Updaters (Internal)
|
|
2622
3394
|
*
|
|
@@ -2918,7 +3690,7 @@ function updateThinkingPart(messages, messageId, stepId, content, signature) {
|
|
|
2918
3690
|
});
|
|
2919
3691
|
}
|
|
2920
3692
|
//#endregion
|
|
2921
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
3693
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/activities/chat/stream/processor.js
|
|
2922
3694
|
/**
|
|
2923
3695
|
* Unified Stream Processor
|
|
2924
3696
|
*
|
|
@@ -2939,6 +3711,28 @@ function updateThinkingPart(messages, messageId, stepId, content, signature) {
|
|
|
2939
3711
|
* adapter contract, single-shot flows, and expected UIMessage output.
|
|
2940
3712
|
*/
|
|
2941
3713
|
var STRUCTURED_OUTPUT_UPDATE_BATCH_SIZE = 12;
|
|
3714
|
+
/**
|
|
3715
|
+
* Events that leave this processor's open *_CHUNK stream open.
|
|
3716
|
+
* RAW, activity events, and REASONING_ENCRYPTED_VALUE match the AG-UI client.
|
|
3717
|
+
* Subagent lifecycle events stay here too: the child processor owns that
|
|
3718
|
+
* lane, and SUBAGENT_FINISHED or SUBAGENT_ERROR finalizes the child.
|
|
3719
|
+
*/
|
|
3720
|
+
var CHUNK_PASS_THROUGH = /* @__PURE__ */ new Set([
|
|
3721
|
+
"RAW",
|
|
3722
|
+
"ACTIVITY_SNAPSHOT",
|
|
3723
|
+
"ACTIVITY_DELTA",
|
|
3724
|
+
"REASONING_ENCRYPTED_VALUE",
|
|
3725
|
+
"SUBAGENT_STARTED",
|
|
3726
|
+
"SUBAGENT_FINISHED",
|
|
3727
|
+
"SUBAGENT_ERROR"
|
|
3728
|
+
]);
|
|
3729
|
+
/** A run-level event closes every open shorthand lane, including children. */
|
|
3730
|
+
var RUN_LEVEL_CLOSES_LANES = /* @__PURE__ */ new Set([
|
|
3731
|
+
"RUN_STARTED",
|
|
3732
|
+
"RUN_FINISHED",
|
|
3733
|
+
"RUN_ERROR",
|
|
3734
|
+
"MESSAGES_SNAPSHOT"
|
|
3735
|
+
]);
|
|
2942
3736
|
function interruptBatchHasGeneric(interrupts) {
|
|
2943
3737
|
return interrupts.some((interrupt) => {
|
|
2944
3738
|
const metadata = interrupt.metadata;
|
|
@@ -2964,6 +3758,19 @@ function serializeToolInput(input) {
|
|
|
2964
3758
|
}
|
|
2965
3759
|
}
|
|
2966
3760
|
/**
|
|
3761
|
+
* The input of a tool call from its raw arguments: `{}` for an empty string,
|
|
3762
|
+
* `undefined` when the arguments are not complete JSON (for example cut off)
|
|
3763
|
+
* or are `null`.
|
|
3764
|
+
*/
|
|
3765
|
+
function parseToolArguments(args) {
|
|
3766
|
+
if (args.trim() === "") return {};
|
|
3767
|
+
try {
|
|
3768
|
+
return JSON.parse(args) ?? void 0;
|
|
3769
|
+
} catch {
|
|
3770
|
+
return;
|
|
3771
|
+
}
|
|
3772
|
+
}
|
|
3773
|
+
/**
|
|
2967
3774
|
* StreamProcessor - State machine for processing AI response streams
|
|
2968
3775
|
*
|
|
2969
3776
|
* Manages the full UIMessage[] conversation and emits events on changes.
|
|
@@ -2990,9 +3797,12 @@ var StreamProcessor = class StreamProcessor {
|
|
|
2990
3797
|
toolCallToMessage = /* @__PURE__ */ new Map();
|
|
2991
3798
|
pendingManualMessageId = null;
|
|
2992
3799
|
pendingThinkingStepId = null;
|
|
3800
|
+
openChunk = null;
|
|
2993
3801
|
structuredMessageIds = /* @__PURE__ */ new Set();
|
|
2994
3802
|
structuredOutputUpdateBatches = /* @__PURE__ */ new Map();
|
|
2995
3803
|
activeRuns = /* @__PURE__ */ new Set();
|
|
3804
|
+
runToolCallIds = [];
|
|
3805
|
+
toolCallsSentToClient = /* @__PURE__ */ new Set();
|
|
2996
3806
|
childProcessors = /* @__PURE__ */ new Map();
|
|
2997
3807
|
childToolCalls = /* @__PURE__ */ new Map();
|
|
2998
3808
|
finishReason = null;
|
|
@@ -3199,6 +4009,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3199
4009
|
this.structuredMessageIds.clear();
|
|
3200
4010
|
this.structuredOutputUpdateBatches.clear();
|
|
3201
4011
|
this.pendingManualMessageId = null;
|
|
4012
|
+
this.openChunk = null;
|
|
3202
4013
|
this.childProcessors.clear();
|
|
3203
4014
|
this.childToolCalls.clear();
|
|
3204
4015
|
this.emitMessagesChange();
|
|
@@ -3219,7 +4030,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3219
4030
|
*
|
|
3220
4031
|
* Central dispatch for all AG-UI events. Each event type maps to a specific
|
|
3221
4032
|
* handler. Events not listed in the switch are intentionally ignored
|
|
3222
|
-
* (
|
|
4033
|
+
* (STATE_SNAPSHOT, STATE_DELTA).
|
|
3223
4034
|
*
|
|
3224
4035
|
* @see docs/chat-architecture.md#adapter-contract — Expected event types and ordering
|
|
3225
4036
|
*/
|
|
@@ -3230,6 +4041,10 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3230
4041
|
index: this.recording.chunks.length
|
|
3231
4042
|
});
|
|
3232
4043
|
if (this.routeToChild(chunk)) return;
|
|
4044
|
+
for (const event of this.expandChunk(chunk)) this.dispatchChunk(event);
|
|
4045
|
+
}
|
|
4046
|
+
/** Send one event, after expandChunk(), to its handler. */
|
|
4047
|
+
dispatchChunk(chunk) {
|
|
3233
4048
|
switch (chunk.type) {
|
|
3234
4049
|
case "SUBAGENT_STARTED":
|
|
3235
4050
|
this.handleSubagentStartedEvent(chunk);
|
|
@@ -3289,7 +4104,178 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3289
4104
|
case "TOOL_CALL_RESULT":
|
|
3290
4105
|
this.handleToolCallResultEvent(chunk);
|
|
3291
4106
|
break;
|
|
3292
|
-
case "STEP_STARTED":
|
|
4107
|
+
case "STEP_STARTED":
|
|
4108
|
+
this.handleStepStartedEvent(chunk);
|
|
4109
|
+
break;
|
|
4110
|
+
case "ACTIVITY_SNAPSHOT":
|
|
4111
|
+
this.handleActivitySnapshotEvent(chunk);
|
|
4112
|
+
break;
|
|
4113
|
+
case "ACTIVITY_DELTA": this.handleActivityDeltaEvent(chunk);
|
|
4114
|
+
}
|
|
4115
|
+
}
|
|
4116
|
+
/**
|
|
4117
|
+
* AG-UI lets a producer send one TEXT_MESSAGE_CHUNK, TOOL_CALL_CHUNK or
|
|
4118
|
+
* REASONING_MESSAGE_CHUNK in place of the START / CONTENT (ARGS) / END
|
|
4119
|
+
* events. A chunk with a new id opens a stream. A chunk with the same id or
|
|
4120
|
+
* no id continues it. Any other event closes it, except the ones in
|
|
4121
|
+
* CHUNK_PASS_THROUGH. Expand the shorthand into the START / CONTENT (ARGS)
|
|
4122
|
+
* / END events, so both forms build the same message.
|
|
4123
|
+
*/
|
|
4124
|
+
expandChunk(chunk) {
|
|
4125
|
+
const open = this.openChunk;
|
|
4126
|
+
const timestamp = chunk.timestamp;
|
|
4127
|
+
switch (chunk.type) {
|
|
4128
|
+
case "TEXT_MESSAGE_CHUNK": {
|
|
4129
|
+
const id = this.chunkStreamId("TEXT_MESSAGE", chunk.messageId, chunk.type);
|
|
4130
|
+
if (id === void 0) return this.closeChunk();
|
|
4131
|
+
const events = [];
|
|
4132
|
+
if (open?.family !== "TEXT_MESSAGE" || open.id !== id) {
|
|
4133
|
+
events.push(...this.closeChunk(), {
|
|
4134
|
+
type: EventType.TEXT_MESSAGE_START,
|
|
4135
|
+
messageId: id,
|
|
4136
|
+
role: chunk.role ?? "assistant",
|
|
4137
|
+
...chunk.name !== void 0 ? { name: chunk.name } : {},
|
|
4138
|
+
timestamp
|
|
4139
|
+
});
|
|
4140
|
+
this.openChunk = {
|
|
4141
|
+
family: "TEXT_MESSAGE",
|
|
4142
|
+
id
|
|
4143
|
+
};
|
|
4144
|
+
}
|
|
4145
|
+
if (chunk.delta !== void 0 || chunk.metadata !== void 0) events.push({
|
|
4146
|
+
type: EventType.TEXT_MESSAGE_CONTENT,
|
|
4147
|
+
messageId: id,
|
|
4148
|
+
delta: chunk.delta ?? "",
|
|
4149
|
+
metadata: chunk.metadata,
|
|
4150
|
+
timestamp
|
|
4151
|
+
});
|
|
4152
|
+
return events;
|
|
4153
|
+
}
|
|
4154
|
+
case "TOOL_CALL_CHUNK": {
|
|
4155
|
+
const id = this.chunkStreamId("TOOL_CALL", chunk.toolCallId, chunk.type);
|
|
4156
|
+
if (id === void 0) return this.closeChunk();
|
|
4157
|
+
const events = [];
|
|
4158
|
+
if (open?.family !== "TOOL_CALL" || open.id !== id) {
|
|
4159
|
+
if (chunk.toolCallName === void 0) {
|
|
4160
|
+
console.warn(`[StreamProcessor] Dropped TOOL_CALL_CHUNK ${id}: the first chunk of a tool call needs a toolCallName`);
|
|
4161
|
+
return this.closeChunk();
|
|
4162
|
+
}
|
|
4163
|
+
events.push(...this.closeChunk(), {
|
|
4164
|
+
type: EventType.TOOL_CALL_START,
|
|
4165
|
+
toolCallId: id,
|
|
4166
|
+
toolCallName: chunk.toolCallName,
|
|
4167
|
+
parentMessageId: chunk.parentMessageId,
|
|
4168
|
+
metadata: chunk.metadata,
|
|
4169
|
+
timestamp
|
|
4170
|
+
});
|
|
4171
|
+
this.openChunk = {
|
|
4172
|
+
family: "TOOL_CALL",
|
|
4173
|
+
id
|
|
4174
|
+
};
|
|
4175
|
+
}
|
|
4176
|
+
if (chunk.delta !== void 0 || chunk.metadata !== void 0) events.push({
|
|
4177
|
+
type: EventType.TOOL_CALL_ARGS,
|
|
4178
|
+
toolCallId: id,
|
|
4179
|
+
delta: chunk.delta ?? "",
|
|
4180
|
+
...chunk.metadata !== void 0 ? { metadata: chunk.metadata } : {},
|
|
4181
|
+
timestamp
|
|
4182
|
+
});
|
|
4183
|
+
return events;
|
|
4184
|
+
}
|
|
4185
|
+
case "REASONING_MESSAGE_CHUNK": {
|
|
4186
|
+
const id = this.chunkStreamId("REASONING_MESSAGE", chunk.messageId, chunk.type);
|
|
4187
|
+
if (id === void 0) return this.closeChunk();
|
|
4188
|
+
const events = [];
|
|
4189
|
+
if (open?.family !== "REASONING_MESSAGE" || open.id !== id) {
|
|
4190
|
+
events.push(...this.closeChunk(), {
|
|
4191
|
+
type: EventType.REASONING_MESSAGE_START,
|
|
4192
|
+
messageId: id,
|
|
4193
|
+
role: "reasoning",
|
|
4194
|
+
timestamp
|
|
4195
|
+
});
|
|
4196
|
+
this.openChunk = {
|
|
4197
|
+
family: "REASONING_MESSAGE",
|
|
4198
|
+
id
|
|
4199
|
+
};
|
|
4200
|
+
}
|
|
4201
|
+
if (chunk.delta !== void 0 || chunk.metadata !== void 0) events.push({
|
|
4202
|
+
type: EventType.REASONING_MESSAGE_CONTENT,
|
|
4203
|
+
messageId: id,
|
|
4204
|
+
delta: chunk.delta ?? "",
|
|
4205
|
+
...chunk.metadata !== void 0 ? { metadata: chunk.metadata } : {},
|
|
4206
|
+
timestamp
|
|
4207
|
+
});
|
|
4208
|
+
return events;
|
|
4209
|
+
}
|
|
4210
|
+
default: {
|
|
4211
|
+
const events = open && !CHUNK_PASS_THROUGH.has(chunk.type) ? this.closeChunk() : [];
|
|
4212
|
+
if (RUN_LEVEL_CLOSES_LANES.has(chunk.type)) this.closeChildChunkLanes();
|
|
4213
|
+
return [...events, chunk];
|
|
4214
|
+
}
|
|
4215
|
+
}
|
|
4216
|
+
}
|
|
4217
|
+
/** Synthesize *_END on every nested shorthand lane and apply those events there. */
|
|
4218
|
+
closeChildChunkLanes() {
|
|
4219
|
+
for (const child of this.childProcessors.values()) {
|
|
4220
|
+
for (const event of child.closeChunk()) child.dispatchChunk(event);
|
|
4221
|
+
child.closeChildChunkLanes();
|
|
4222
|
+
}
|
|
4223
|
+
}
|
|
4224
|
+
/**
|
|
4225
|
+
* The child an untagged chunk with no id continues: the only child whose
|
|
4226
|
+
* subtree has an open chunk stream of its kind, when this processor has
|
|
4227
|
+
* none. The AG-UI client resolves a chunk that tags only its opener the
|
|
4228
|
+
* same way.
|
|
4229
|
+
*/
|
|
4230
|
+
childContinuing(chunk) {
|
|
4231
|
+
let family;
|
|
4232
|
+
if (chunk.type === "TEXT_MESSAGE_CHUNK" && chunk.messageId === void 0) family = "TEXT_MESSAGE";
|
|
4233
|
+
else if (chunk.type === "REASONING_MESSAGE_CHUNK" && chunk.messageId === void 0) family = "REASONING_MESSAGE";
|
|
4234
|
+
else if (chunk.type === "TOOL_CALL_CHUNK" && chunk.toolCallId === void 0) family = "TOOL_CALL";
|
|
4235
|
+
else return;
|
|
4236
|
+
if (this.openChunkCount(family) !== 1) return void 0;
|
|
4237
|
+
for (const [id, child] of this.childProcessors) if (child.openChunkCount(family) === 1) return id;
|
|
4238
|
+
}
|
|
4239
|
+
/**
|
|
4240
|
+
* How many open chunk streams of a kind this processor and all its nested
|
|
4241
|
+
* children hold.
|
|
4242
|
+
*/
|
|
4243
|
+
openChunkCount(family) {
|
|
4244
|
+
let count = this.openChunk?.family === family ? 1 : 0;
|
|
4245
|
+
for (const child of this.childProcessors.values()) count += child.openChunkCount(family);
|
|
4246
|
+
return count;
|
|
4247
|
+
}
|
|
4248
|
+
/**
|
|
4249
|
+
* The id a chunk opens or continues. A chunk with no id continues. If it
|
|
4250
|
+
* continues nothing, the caller drops it and closes the open stream, so a
|
|
4251
|
+
* later chunk with no id cannot continue that stream either.
|
|
4252
|
+
*/
|
|
4253
|
+
chunkStreamId(family, id, type) {
|
|
4254
|
+
if (id !== void 0) return id;
|
|
4255
|
+
if (this.openChunk?.family === family) return this.openChunk.id;
|
|
4256
|
+
console.warn(`[StreamProcessor] Dropped ${type}: it has no id and continues nothing`);
|
|
4257
|
+
}
|
|
4258
|
+
closeChunk() {
|
|
4259
|
+
const open = this.openChunk;
|
|
4260
|
+
if (!open) return [];
|
|
4261
|
+
this.openChunk = null;
|
|
4262
|
+
const timestamp = Date.now();
|
|
4263
|
+
switch (open.family) {
|
|
4264
|
+
case "TEXT_MESSAGE": return [{
|
|
4265
|
+
type: EventType.TEXT_MESSAGE_END,
|
|
4266
|
+
messageId: open.id,
|
|
4267
|
+
timestamp
|
|
4268
|
+
}];
|
|
4269
|
+
case "TOOL_CALL": return [{
|
|
4270
|
+
type: EventType.TOOL_CALL_END,
|
|
4271
|
+
toolCallId: open.id,
|
|
4272
|
+
timestamp
|
|
4273
|
+
}];
|
|
4274
|
+
case "REASONING_MESSAGE": return [{
|
|
4275
|
+
type: EventType.REASONING_MESSAGE_END,
|
|
4276
|
+
messageId: open.id,
|
|
4277
|
+
timestamp
|
|
4278
|
+
}];
|
|
3293
4279
|
}
|
|
3294
4280
|
}
|
|
3295
4281
|
/**
|
|
@@ -3366,7 +4352,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3366
4352
|
* MESSAGES_SNAPSHOT) but whose transient state was cleared. In that case we
|
|
3367
4353
|
* hydrate state from the existing message rather than creating a duplicate.
|
|
3368
4354
|
*/
|
|
3369
|
-
ensureAssistantMessage(preferredId) {
|
|
4355
|
+
ensureAssistantMessage(preferredId, fallbackToActive = true) {
|
|
3370
4356
|
if (preferredId) {
|
|
3371
4357
|
const state = this.getMessageState(preferredId);
|
|
3372
4358
|
if (state) {
|
|
@@ -3377,7 +4363,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3377
4363
|
};
|
|
3378
4364
|
}
|
|
3379
4365
|
}
|
|
3380
|
-
const activeId = this.getActiveAssistantMessageId();
|
|
4366
|
+
const activeId = fallbackToActive ? this.getActiveAssistantMessageId() : null;
|
|
3381
4367
|
if (activeId) {
|
|
3382
4368
|
const state = this.getMessageState(activeId);
|
|
3383
4369
|
if (state) {
|
|
@@ -3390,7 +4376,8 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3390
4376
|
}
|
|
3391
4377
|
if (preferredId) {
|
|
3392
4378
|
const existingMsg = this.messages.find((m) => m.id === preferredId);
|
|
3393
|
-
if (existingMsg)
|
|
4379
|
+
if (existingMsg?.role === "activity") preferredId = void 0;
|
|
4380
|
+
else if (existingMsg) {
|
|
3394
4381
|
const state = this.createMessageState(preferredId, existingMsg.role);
|
|
3395
4382
|
this.activeMessageIds.add(preferredId);
|
|
3396
4383
|
const lastPart = existingMsg.parts.length > 0 ? existingMsg.parts[existingMsg.parts.length - 1] : null;
|
|
@@ -3415,7 +4402,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3415
4402
|
this.messages = [...this.messages, assistantMessage];
|
|
3416
4403
|
const state = this.createMessageState(id, "assistant");
|
|
3417
4404
|
this.activeMessageIds.add(id);
|
|
3418
|
-
this.pendingManualMessageId = id;
|
|
4405
|
+
if (!preferredId) this.pendingManualMessageId = id;
|
|
3419
4406
|
this.events.onStreamStart?.();
|
|
3420
4407
|
this.emitMessagesChange();
|
|
3421
4408
|
return {
|
|
@@ -3585,7 +4572,9 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3585
4572
|
/**
|
|
3586
4573
|
* Send a child's chunk to that child's processor, so the card keeps text,
|
|
3587
4574
|
* reasoning, tool calls, results, and nested children. A tool event without
|
|
3588
|
-
* `subagentRunId` follows its `TOOL_CALL_START`.
|
|
4575
|
+
* `subagentRunId` follows its `TOOL_CALL_START` or `TOOL_CALL_CHUNK`. An
|
|
4576
|
+
* untagged chunk with no id follows a child's open chunk stream (see
|
|
4577
|
+
* childContinuing()).
|
|
3589
4578
|
*/
|
|
3590
4579
|
routeToChild(chunk) {
|
|
3591
4580
|
let id;
|
|
@@ -3595,6 +4584,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3595
4584
|
id = chunk.subagentRunId;
|
|
3596
4585
|
} else if ("subagentRunId" in chunk && chunk.subagentRunId) id = chunk.subagentRunId;
|
|
3597
4586
|
else if ("toolCallId" in chunk && typeof chunk.toolCallId === "string") id = this.childToolCalls.get(chunk.toolCallId);
|
|
4587
|
+
else id = this.childContinuing(chunk);
|
|
3598
4588
|
if (id === void 0) return false;
|
|
3599
4589
|
const owner = this.childOwning(id);
|
|
3600
4590
|
if (owner === void 0) {
|
|
@@ -3603,34 +4593,45 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3603
4593
|
return true;
|
|
3604
4594
|
}
|
|
3605
4595
|
if (this.findSubagentPart(owner)?.part.subagent.status === "error") return true;
|
|
3606
|
-
if (chunk.type === "TOOL_CALL_START") this.childToolCalls.set(chunk.toolCallId, owner);
|
|
4596
|
+
if ((chunk.type === "TOOL_CALL_START" || chunk.type === "TOOL_CALL_CHUNK") && chunk.toolCallId !== void 0) this.childToolCalls.set(chunk.toolCallId, owner);
|
|
3607
4597
|
this.updateChild(owner, (child) => child.processChunk(chunk));
|
|
3608
4598
|
return true;
|
|
3609
4599
|
}
|
|
4600
|
+
renameMessage(fromId, toId) {
|
|
4601
|
+
this.messages = this.messages.map((msg) => msg.id === fromId ? {
|
|
4602
|
+
...msg,
|
|
4603
|
+
id: toId
|
|
4604
|
+
} : msg);
|
|
4605
|
+
const existingState = this.messageStates.get(fromId);
|
|
4606
|
+
if (existingState) {
|
|
4607
|
+
existingState.id = toId;
|
|
4608
|
+
this.messageStates.delete(fromId);
|
|
4609
|
+
this.messageStates.set(toId, existingState);
|
|
4610
|
+
}
|
|
4611
|
+
this.activeMessageIds.delete(fromId);
|
|
4612
|
+
this.activeMessageIds.add(toId);
|
|
4613
|
+
for (const [toolCallId, mappedMessageId] of this.toolCallToMessage) if (mappedMessageId === fromId) this.toolCallToMessage.set(toolCallId, toId);
|
|
4614
|
+
if (this.structuredMessageIds.delete(fromId)) this.structuredMessageIds.add(toId);
|
|
4615
|
+
const batch = this.structuredOutputUpdateBatches.get(fromId);
|
|
4616
|
+
if (batch) {
|
|
4617
|
+
this.structuredOutputUpdateBatches.delete(fromId);
|
|
4618
|
+
this.structuredOutputUpdateBatches.set(toId, batch);
|
|
4619
|
+
}
|
|
4620
|
+
}
|
|
3610
4621
|
/**
|
|
3611
4622
|
* Handle TEXT_MESSAGE_START event
|
|
3612
4623
|
*/
|
|
3613
4624
|
handleTextMessageStartEvent(chunk) {
|
|
3614
4625
|
const { messageId, role } = chunk;
|
|
4626
|
+
if (this.messages.some((m) => m.id === messageId && m.role === "activity")) {
|
|
4627
|
+
console.warn(`TEXT_MESSAGE_START: Dropped text for '${messageId}', the id of an activity message`);
|
|
4628
|
+
return;
|
|
4629
|
+
}
|
|
3615
4630
|
const uiRole = role === "user" || role === "system" ? role : "assistant";
|
|
3616
4631
|
if (this.pendingManualMessageId) {
|
|
3617
4632
|
const pendingId = this.pendingManualMessageId;
|
|
3618
4633
|
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
|
-
}
|
|
4634
|
+
if (pendingId !== messageId) this.renameMessage(pendingId, messageId);
|
|
3634
4635
|
let pendingState = this.messageStates.get(messageId);
|
|
3635
4636
|
if (!pendingState) {
|
|
3636
4637
|
pendingState = this.createMessageState(messageId, uiRole);
|
|
@@ -3641,6 +4642,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3641
4642
|
pendingState.lastEmittedText = "";
|
|
3642
4643
|
pendingState.hasToolCallsSinceTextStart = false;
|
|
3643
4644
|
}
|
|
4645
|
+
this.applySenderName(messageId, chunk.name);
|
|
3644
4646
|
this.mergeMessageMetadata(messageId, chunk.metadata);
|
|
3645
4647
|
this.emitMessagesChange();
|
|
3646
4648
|
return;
|
|
@@ -3655,6 +4657,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3655
4657
|
existingState.lastEmittedText = "";
|
|
3656
4658
|
existingState.hasToolCallsSinceTextStart = false;
|
|
3657
4659
|
}
|
|
4660
|
+
this.applySenderName(messageId, chunk.name);
|
|
3658
4661
|
this.mergeMessageMetadata(messageId, chunk.metadata);
|
|
3659
4662
|
return;
|
|
3660
4663
|
}
|
|
@@ -3667,10 +4670,18 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3667
4670
|
this.messages = [...this.messages, newMessage];
|
|
3668
4671
|
this.createMessageState(messageId, uiRole);
|
|
3669
4672
|
this.activeMessageIds.add(messageId);
|
|
4673
|
+
this.applySenderName(messageId, chunk.name);
|
|
3670
4674
|
this.mergeMessageMetadata(messageId, chunk.metadata);
|
|
3671
4675
|
this.events.onStreamStart?.();
|
|
3672
4676
|
this.emitMessagesChange();
|
|
3673
4677
|
}
|
|
4678
|
+
applySenderName(messageId, name) {
|
|
4679
|
+
if (name === void 0) return;
|
|
4680
|
+
this.messages = this.messages.map((msg) => msg.id === messageId ? {
|
|
4681
|
+
...msg,
|
|
4682
|
+
name
|
|
4683
|
+
} : msg);
|
|
4684
|
+
}
|
|
3674
4685
|
/**
|
|
3675
4686
|
* Handle TEXT_MESSAGE_END event
|
|
3676
4687
|
*/
|
|
@@ -3700,10 +4711,31 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3700
4711
|
metadata: prev.metadata
|
|
3701
4712
|
};
|
|
3702
4713
|
});
|
|
3703
|
-
this.messages = this.attachSnapshotSubagents(reconciled, top, groups, prevMessages);
|
|
4714
|
+
this.messages = this.mergeOmittedActivity(prevMessages, this.attachSnapshotSubagents(reconciled, top, groups, prevMessages));
|
|
3704
4715
|
this.emitMessagesChange();
|
|
3705
4716
|
}
|
|
3706
4717
|
/**
|
|
4718
|
+
* Snapshot is authoritative for user/assistant/system. Activity omitted
|
|
4719
|
+
* from the snapshot (TanStack chat() still builds snapshots from
|
|
4720
|
+
* ModelMessage[]) stays in the transcript so persist/reconnect cannot
|
|
4721
|
+
* wipe it. Snapshot activity rows win when the id is present.
|
|
4722
|
+
*
|
|
4723
|
+
* Keep every snapshot row, including two assistants that share an id
|
|
4724
|
+
* (agent-loop retry reuses `currentMessageId`). A Map keyed by id would
|
|
4725
|
+
* drop the earlier error tool-call (#1192).
|
|
4726
|
+
*/
|
|
4727
|
+
mergeOmittedActivity(prevMessages, snapshot) {
|
|
4728
|
+
const snapshotIds = new Set(snapshot.map((msg) => msg.id));
|
|
4729
|
+
const omitted = prevMessages.filter((msg) => msg.role === "activity" && !snapshotIds.has(msg.id));
|
|
4730
|
+
if (omitted.length === 0) return snapshot;
|
|
4731
|
+
const out = [...snapshot];
|
|
4732
|
+
for (const activity of omitted) {
|
|
4733
|
+
const prevIndex = prevMessages.findIndex((msg) => msg.id === activity.id);
|
|
4734
|
+
out.splice(Math.min(Math.max(prevIndex, 0), out.length), 0, activity);
|
|
4735
|
+
}
|
|
4736
|
+
return out;
|
|
4737
|
+
}
|
|
4738
|
+
/**
|
|
3707
4739
|
* Put subagent cards back on a snapshot. Child wire messages (tagged with
|
|
3708
4740
|
* `subagentRunId`) become a card on the nearest assistant message before
|
|
3709
4741
|
* them, or a new assistant message when there is none. A card that the
|
|
@@ -3923,6 +4955,10 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3923
4955
|
* @see docs/chat-architecture.md#uimessage-part-ordering-invariants — Replace vs. push logic
|
|
3924
4956
|
*/
|
|
3925
4957
|
handleTextMessageContentEvent(chunk) {
|
|
4958
|
+
if (this.messages.some((m) => m.id === chunk.messageId && m.role === "activity")) {
|
|
4959
|
+
console.warn(`TEXT_MESSAGE_CONTENT: Dropped text for '${chunk.messageId}', the id of an activity message`);
|
|
4960
|
+
return;
|
|
4961
|
+
}
|
|
3926
4962
|
const { messageId, state } = this.ensureAssistantMessage(chunk.messageId);
|
|
3927
4963
|
this.mergeMessageMetadata(messageId, chunk.metadata);
|
|
3928
4964
|
if (this.structuredMessageIds.has(messageId)) {
|
|
@@ -3966,8 +5002,25 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3966
5002
|
* @see docs/chat-architecture.md#adapter-contract — Ordering requirements
|
|
3967
5003
|
*/
|
|
3968
5004
|
handleToolCallStartEvent(chunk) {
|
|
5005
|
+
const pendingId = this.pendingManualMessageId;
|
|
5006
|
+
const parentId = chunk.parentMessageId;
|
|
5007
|
+
if (pendingId && parentId && parentId !== pendingId) {
|
|
5008
|
+
const parent = this.messages.find((m) => m.id === parentId);
|
|
5009
|
+
const placeholder = this.messages.find((m) => m.id === pendingId);
|
|
5010
|
+
if (!parent) {
|
|
5011
|
+
this.pendingManualMessageId = null;
|
|
5012
|
+
this.renameMessage(pendingId, parentId);
|
|
5013
|
+
} else if (parent.role === "assistant" && placeholder) {
|
|
5014
|
+
this.pendingManualMessageId = null;
|
|
5015
|
+
this.messages = this.messages.filter((m) => m.id !== pendingId).map((m) => m.id === parentId ? {
|
|
5016
|
+
...m,
|
|
5017
|
+
parts: [...m.parts, ...placeholder.parts]
|
|
5018
|
+
} : m);
|
|
5019
|
+
this.renameMessage(pendingId, parentId);
|
|
5020
|
+
}
|
|
5021
|
+
}
|
|
3969
5022
|
const targetMessageId = chunk.parentMessageId ?? this.getActiveAssistantMessageId();
|
|
3970
|
-
const { messageId, state } = this.ensureAssistantMessage(targetMessageId ?? void 0);
|
|
5023
|
+
const { messageId, state } = this.ensureAssistantMessage(targetMessageId ?? void 0, chunk.parentMessageId === void 0);
|
|
3971
5024
|
state.hasToolCallsSinceTextStart = true;
|
|
3972
5025
|
const toolCallId = chunk.toolCallId;
|
|
3973
5026
|
if (!state.toolCalls.get(toolCallId)) {
|
|
@@ -3985,6 +5038,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3985
5038
|
};
|
|
3986
5039
|
state.toolCalls.set(toolCallId, newToolCall);
|
|
3987
5040
|
state.toolCallOrder.push(toolCallId);
|
|
5041
|
+
this.runToolCallIds.push(toolCallId);
|
|
3988
5042
|
this.toolCallToMessage.set(toolCallId, messageId);
|
|
3989
5043
|
this.messages = updateToolCallPart(this.messages, messageId, {
|
|
3990
5044
|
id: chunk.toolCallId,
|
|
@@ -4018,6 +5072,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4018
5072
|
const existingToolCall = state.toolCalls.get(toolCallId);
|
|
4019
5073
|
if (!existingToolCall) return;
|
|
4020
5074
|
const wasAwaitingInput = existingToolCall.state === "awaiting-input";
|
|
5075
|
+
if (chunk.metadata !== void 0) existingToolCall.metadata = mergeMetadata(existingToolCall.metadata, chunk.metadata);
|
|
4021
5076
|
existingToolCall.arguments += chunk.delta || "";
|
|
4022
5077
|
if (wasAwaitingInput && chunk.delta) existingToolCall.state = "input-streaming";
|
|
4023
5078
|
existingToolCall.parsedArguments = this.jsonParser.parse(existingToolCall.arguments);
|
|
@@ -4025,7 +5080,8 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4025
5080
|
id: existingToolCall.id,
|
|
4026
5081
|
name: existingToolCall.name,
|
|
4027
5082
|
arguments: existingToolCall.arguments,
|
|
4028
|
-
state: existingToolCall.state
|
|
5083
|
+
state: existingToolCall.state,
|
|
5084
|
+
...existingToolCall.metadata !== void 0 && { metadata: existingToolCall.metadata }
|
|
4029
5085
|
});
|
|
4030
5086
|
this.emitMessagesChange();
|
|
4031
5087
|
this.events.onToolCallStateChange?.(messageId, existingToolCall.id, existingToolCall.state, existingToolCall.arguments);
|
|
@@ -4102,6 +5158,10 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4102
5158
|
* runs are still active before finalizing.
|
|
4103
5159
|
*/
|
|
4104
5160
|
handleRunStartedEvent(chunk) {
|
|
5161
|
+
if (this.activeRuns.size === 0) {
|
|
5162
|
+
this.runToolCallIds = [];
|
|
5163
|
+
this.toolCallsSentToClient.clear();
|
|
5164
|
+
}
|
|
4105
5165
|
this.activeRuns.add(chunk.runId);
|
|
4106
5166
|
}
|
|
4107
5167
|
/**
|
|
@@ -4122,11 +5182,39 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4122
5182
|
if (this.activeRuns.size === 0) {
|
|
4123
5183
|
this.completeAllToolCalls();
|
|
4124
5184
|
if (this.finishReason === "tool_calls" && chunk.outcome?.type !== "interrupt") return;
|
|
5185
|
+
if (!chunk.outcome || chunk.outcome.type === "success") this.handlePendingToolCalls(chunk.outcome?.pendingToolCallIds);
|
|
4125
5186
|
this.isDone = true;
|
|
4126
5187
|
this.finalizeStream();
|
|
4127
5188
|
}
|
|
4128
5189
|
}
|
|
4129
5190
|
/**
|
|
5191
|
+
* AG-UI ends a run that calls a frontend tool with a success outcome and
|
|
5192
|
+
* leaves the call unanswered. The pending calls are the ones named in
|
|
5193
|
+
* `pendingToolCallIds` that this run started, or else every call this run
|
|
5194
|
+
* started that has no result. Fire onToolCall once for each, so the client
|
|
5195
|
+
* runs it and continues.
|
|
5196
|
+
*/
|
|
5197
|
+
handlePendingToolCalls(pendingToolCallIds) {
|
|
5198
|
+
const ids = pendingToolCallIds?.length ? pendingToolCallIds.filter((id) => this.runToolCallIds.includes(id)) : this.runToolCallIds;
|
|
5199
|
+
const parts = this.messages.flatMap((msg) => msg.parts ?? []);
|
|
5200
|
+
for (const toolCallId of ids) {
|
|
5201
|
+
if (this.toolCallsSentToClient.has(toolCallId)) continue;
|
|
5202
|
+
const part = parts.find((p) => p.type === "tool-call" && p.id === toolCallId);
|
|
5203
|
+
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;
|
|
5204
|
+
const input = part.input ?? parseToolArguments(part.arguments);
|
|
5205
|
+
if (input === void 0) {
|
|
5206
|
+
console.warn(`[StreamProcessor] Did not run tool call ${toolCallId}: the arguments of ${part.name} are not complete JSON`);
|
|
5207
|
+
continue;
|
|
5208
|
+
}
|
|
5209
|
+
this.toolCallsSentToClient.add(toolCallId);
|
|
5210
|
+
this.events.onToolCall?.({
|
|
5211
|
+
toolCallId,
|
|
5212
|
+
toolName: part.name,
|
|
5213
|
+
input
|
|
5214
|
+
});
|
|
5215
|
+
}
|
|
5216
|
+
}
|
|
5217
|
+
/**
|
|
4130
5218
|
* Apply interrupt state to tool-call parts, then fire the client events.
|
|
4131
5219
|
* A child's interrupt updates the child's card. `emit` is false there, so
|
|
4132
5220
|
* the events fire once, from the top processor.
|
|
@@ -4168,6 +5256,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4168
5256
|
}
|
|
4169
5257
|
if (kind === "client_tool" || interrupt.reason === "client_tool_input") {
|
|
4170
5258
|
if (hasGeneric || !emit) continue;
|
|
5259
|
+
this.toolCallsSentToClient.add(toolCallId);
|
|
4171
5260
|
this.events.onToolCall?.({
|
|
4172
5261
|
toolCallId,
|
|
4173
5262
|
toolName,
|
|
@@ -4228,6 +5317,24 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4228
5317
|
this.pendingThinkingStepId = stepId;
|
|
4229
5318
|
}
|
|
4230
5319
|
/**
|
|
5320
|
+
* Handle ACTIVITY_SNAPSHOT. Creates or replaces a frontend-only activity
|
|
5321
|
+
* message. Does not create MessageStreamState (that path feeds
|
|
5322
|
+
* ProcessorResult.content).
|
|
5323
|
+
*/
|
|
5324
|
+
handleActivitySnapshotEvent(chunk) {
|
|
5325
|
+
this.messages = applyActivitySnapshotToUIMessages(this.messages, chunk);
|
|
5326
|
+
this.emitMessagesChange();
|
|
5327
|
+
}
|
|
5328
|
+
/**
|
|
5329
|
+
* Handle ACTIVITY_DELTA. Applies RFC 6902 patches to an existing activity
|
|
5330
|
+
* `content`. Missing or non-activity ids are no-ops. Patch failure leaves
|
|
5331
|
+
* the previous content in place.
|
|
5332
|
+
*/
|
|
5333
|
+
handleActivityDeltaEvent(chunk) {
|
|
5334
|
+
this.messages = applyActivityDeltaToUIMessages(this.messages, chunk);
|
|
5335
|
+
this.emitMessagesChange();
|
|
5336
|
+
}
|
|
5337
|
+
/**
|
|
4231
5338
|
* Handle STEP_FINISHED event.
|
|
4232
5339
|
*
|
|
4233
5340
|
* Thinking *content* comes from REASONING_MESSAGE_CONTENT, not STEP_FINISHED.
|
|
@@ -4256,6 +5363,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4256
5363
|
*/
|
|
4257
5364
|
handleReasoningMessageContentEvent(chunk) {
|
|
4258
5365
|
const { messageId, state } = this.ensureAssistantMessage(this.getActiveAssistantMessageId() ?? void 0);
|
|
5366
|
+
this.mergeMessageMetadata(messageId, chunk.metadata);
|
|
4259
5367
|
state.hasSeenReasoningEvents = true;
|
|
4260
5368
|
const delta = chunk.delta || "";
|
|
4261
5369
|
this.consumePendingThinkingStep(state);
|
|
@@ -4368,6 +5476,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4368
5476
|
}
|
|
4369
5477
|
if (chunk.name === "tool-input-available" && chunk.value) {
|
|
4370
5478
|
const { toolCallId, toolName, input } = chunk.value;
|
|
5479
|
+
this.toolCallsSentToClient.add(toolCallId);
|
|
4371
5480
|
this.events.onToolCall?.({
|
|
4372
5481
|
toolCallId,
|
|
4373
5482
|
toolName,
|
|
@@ -4546,6 +5655,8 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4546
5655
|
*/
|
|
4547
5656
|
finalizeStream() {
|
|
4548
5657
|
this.isDone = true;
|
|
5658
|
+
for (const event of this.closeChunk()) this.dispatchChunk(event);
|
|
5659
|
+
this.closeChildChunkLanes();
|
|
4549
5660
|
let lastAssistantMessage;
|
|
4550
5661
|
for (const messageId of this.activeMessageIds) {
|
|
4551
5662
|
const state = this.getMessageState(messageId);
|
|
@@ -4663,6 +5774,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4663
5774
|
this.structuredOutputUpdateBatches.clear();
|
|
4664
5775
|
this.pendingManualMessageId = null;
|
|
4665
5776
|
this.pendingThinkingStepId = null;
|
|
5777
|
+
this.openChunk = null;
|
|
4666
5778
|
this.finishReason = null;
|
|
4667
5779
|
this.hasError = false;
|
|
4668
5780
|
this.isDone = false;
|
|
@@ -4702,14 +5814,14 @@ function createReplayStream(recording) {
|
|
|
4702
5814
|
} };
|
|
4703
5815
|
}
|
|
4704
5816
|
//#endregion
|
|
4705
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
5817
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/byok/providers.js
|
|
4706
5818
|
/** `[a-z][a-z0-9-]{0,63}` — lowercase, no underscores, max 64 chars. */
|
|
4707
5819
|
var BYOK_PROVIDER_ID_PATTERN = /^[a-z][a-z0-9-]{0,63}$/;
|
|
4708
5820
|
function isProviderId(value) {
|
|
4709
5821
|
return typeof value === "string" && BYOK_PROVIDER_ID_PATTERN.test(value);
|
|
4710
5822
|
}
|
|
4711
5823
|
//#endregion
|
|
4712
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
5824
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/byok/missing.js
|
|
4713
5825
|
function isByokMissingBody(value) {
|
|
4714
5826
|
if (typeof value !== "object" || value === null) return false;
|
|
4715
5827
|
if (!("error" in value)) return false;
|
|
@@ -4722,7 +5834,7 @@ function isByokMissingBody(value) {
|
|
|
4722
5834
|
return true;
|
|
4723
5835
|
}
|
|
4724
5836
|
//#endregion
|
|
4725
|
-
//#region node_modules/.deno/@tanstack+ai@0.
|
|
5837
|
+
//#region node_modules/.deno/@tanstack+ai@0.68.0/node_modules/@tanstack/ai/dist/esm/byok/errors.js
|
|
4726
5838
|
var ByokMissingError = class extends Error {
|
|
4727
5839
|
provider;
|
|
4728
5840
|
constructor(provider) {
|
|
@@ -4748,7 +5860,7 @@ var ByokUnresolvedProviderError = class extends Error {
|
|
|
4748
5860
|
}
|
|
4749
5861
|
};
|
|
4750
5862
|
//#endregion
|
|
4751
|
-
//#region node_modules/.deno/@tanstack+ai-client@0.
|
|
5863
|
+
//#region node_modules/.deno/@tanstack+ai-client@0.39.2/node_modules/@tanstack/ai-client/dist/esm/connection-adapters.js
|
|
4752
5864
|
/**
|
|
4753
5865
|
* Associates connect-wrapped chunks with the run they were produced under.
|
|
4754
5866
|
* Content events (TEXT_MESSAGE_CONTENT, TOOL_CALL_*, …) carry no `runId` of
|
|
@@ -4941,6 +6053,9 @@ async function* readStreamLines(reader, abortSignal) {
|
|
|
4941
6053
|
buffer += decoder.decode();
|
|
4942
6054
|
if (buffer.trim() && !abortSignal?.aborted) throw new StreamTruncatedError();
|
|
4943
6055
|
} finally {
|
|
6056
|
+
try {
|
|
6057
|
+
reader.cancel().catch(() => {});
|
|
6058
|
+
} catch {}
|
|
4944
6059
|
reader.releaseLock();
|
|
4945
6060
|
}
|
|
4946
6061
|
}
|
|
@@ -5443,7 +6558,7 @@ async function* abortableIterable(iterable, signal) {
|
|
|
5443
6558
|
}
|
|
5444
6559
|
}
|
|
5445
6560
|
//#endregion
|
|
5446
|
-
//#region node_modules/.deno/@tanstack+ai-client@0.
|
|
6561
|
+
//#region node_modules/.deno/@tanstack+ai-client@0.39.2/node_modules/@tanstack/ai-client/dist/esm/interrupt-manager.js
|
|
5447
6562
|
function isClientOwnedInterrupt(item) {
|
|
5448
6563
|
return item.resumable;
|
|
5449
6564
|
}
|
|
@@ -6385,7 +7500,7 @@ var InterruptManager = class {
|
|
|
6385
7500
|
}
|
|
6386
7501
|
};
|
|
6387
7502
|
//#endregion
|
|
6388
|
-
//#region node_modules/.deno/@tanstack+ai-client@0.
|
|
7503
|
+
//#region node_modules/.deno/@tanstack+ai-client@0.39.2/node_modules/@tanstack/ai-client/dist/esm/byok/client.js
|
|
6389
7504
|
var registeredProviderIds = /* @__PURE__ */ new WeakMap();
|
|
6390
7505
|
/**
|
|
6391
7506
|
* Provider to stamp when the caller did not pass a slug.
|
|
@@ -6398,7 +7513,7 @@ function byokFallbackProviderId(byok) {
|
|
|
6398
7513
|
if (registered.length === 1) return registered[0];
|
|
6399
7514
|
}
|
|
6400
7515
|
//#endregion
|
|
6401
|
-
//#region node_modules/.deno/@tanstack+ai-client@0.
|
|
7516
|
+
//#region node_modules/.deno/@tanstack+ai-client@0.39.2/node_modules/@tanstack/ai-client/dist/esm/byok/resolve.js
|
|
6402
7517
|
function resolveByokProviderId(byokProvider, ...candidates) {
|
|
6403
7518
|
const fromFn = byokProvider?.();
|
|
6404
7519
|
if (isProviderId(fromFn)) return fromFn;
|
|
@@ -6414,7 +7529,7 @@ async function prepareResolvedByokHeaders(byok, provider) {
|
|
|
6414
7529
|
return byok.headers(provider);
|
|
6415
7530
|
}
|
|
6416
7531
|
//#endregion
|
|
6417
|
-
//#region node_modules/.deno/@tanstack+ai-client@0.
|
|
7532
|
+
//#region node_modules/.deno/@tanstack+ai-client@0.39.2/node_modules/@tanstack/ai-client/dist/esm/events.js
|
|
6418
7533
|
/**
|
|
6419
7534
|
* Abstract base class for ChatClient event emission
|
|
6420
7535
|
*/
|
|
@@ -6588,7 +7703,7 @@ var ChatClientEventEmitter = class {
|
|
|
6588
7703
|
}
|
|
6589
7704
|
};
|
|
6590
7705
|
//#endregion
|
|
6591
|
-
//#region node_modules/.deno/@tanstack+ai-client@0.
|
|
7706
|
+
//#region node_modules/.deno/@tanstack+ai-client@0.39.2/node_modules/@tanstack/ai-client/dist/esm/devtools-noop.js
|
|
6592
7707
|
var NoOpChatClientEventEmitter = class extends ChatClientEventEmitter {
|
|
6593
7708
|
emitEvent() {}
|
|
6594
7709
|
};
|
|
@@ -6633,7 +7748,7 @@ var NoOpChatDevtoolsBridge = class {
|
|
|
6633
7748
|
};
|
|
6634
7749
|
var createNoOpChatDevtoolsBridge = (options) => new NoOpChatDevtoolsBridge(options);
|
|
6635
7750
|
//#endregion
|
|
6636
|
-
//#region node_modules/.deno/@tanstack+ai-client@0.
|
|
7751
|
+
//#region node_modules/.deno/@tanstack+ai-client@0.39.2/node_modules/@tanstack/ai-client/dist/esm/client-persistor.js
|
|
6637
7752
|
/** Normalize a raw `getItem` result (legacy bare array or combined record). */
|
|
6638
7753
|
function normalizePersistedState(raw) {
|
|
6639
7754
|
if (Array.isArray(raw)) return { messages: raw };
|
|
@@ -6732,12 +7847,13 @@ var ChatPersistor = class {
|
|
|
6732
7847
|
}
|
|
6733
7848
|
/**
|
|
6734
7849
|
* Apply state from an async `getItem` once it resolves, unless the message
|
|
6735
|
-
* list has already changed since hydration began.
|
|
7850
|
+
* list has already changed since hydration began. Returns a promise that
|
|
7851
|
+
* settles (never rejects) when it is done, or `undefined` for sync state.
|
|
6736
7852
|
*/
|
|
6737
7853
|
hydrateAsync(persistedState) {
|
|
6738
7854
|
if (!(persistedState instanceof Promise)) return;
|
|
6739
7855
|
const hydrationGeneration = this.messagesGeneration;
|
|
6740
|
-
persistedState.then((state) => {
|
|
7856
|
+
return persistedState.then((state) => {
|
|
6741
7857
|
if (!state || this.messagesGeneration !== hydrationGeneration) return;
|
|
6742
7858
|
this.lastResume = state.resume ?? null;
|
|
6743
7859
|
this.lastMessages = state.messages;
|
|
@@ -6893,11 +8009,11 @@ var ChatPersistor = class {
|
|
|
6893
8009
|
isRunlessChunkFromIgnoredRun(chunk) {
|
|
6894
8010
|
if (getChunkRunId$1(chunk) || !this.currentRunlessRunId) return false;
|
|
6895
8011
|
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";
|
|
8012
|
+
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
8013
|
}
|
|
6898
8014
|
};
|
|
6899
8015
|
//#endregion
|
|
6900
|
-
//#region node_modules/.deno/@tanstack+ai-client@0.
|
|
8016
|
+
//#region node_modules/.deno/@tanstack+ai-client@0.39.2/node_modules/@tanstack/ai-client/dist/esm/cleared-stream-tracker.js
|
|
6901
8017
|
function getChunkToolCallId(chunk) {
|
|
6902
8018
|
return "toolCallId" in chunk && typeof chunk.toolCallId === "string" ? chunk.toolCallId : void 0;
|
|
6903
8019
|
}
|
|
@@ -6986,11 +8102,11 @@ var ClearedStreamTracker = class {
|
|
|
6986
8102
|
isRunlessChunkFromIgnoredRun(chunk) {
|
|
6987
8103
|
if (getChunkRunId$1(chunk) || !this.currentRunlessRunId) return false;
|
|
6988
8104
|
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";
|
|
8105
|
+
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
8106
|
}
|
|
6991
8107
|
};
|
|
6992
8108
|
//#endregion
|
|
6993
|
-
//#region node_modules/.deno/@tanstack+ai-client@0.
|
|
8109
|
+
//#region node_modules/.deno/@tanstack+ai-client@0.39.2/node_modules/@tanstack/ai-client/dist/esm/chat-client.js
|
|
6994
8110
|
var STREAM_PROCESSING_BUDGET_MS = 8;
|
|
6995
8111
|
function yieldToHost() {
|
|
6996
8112
|
const { scheduler } = globalThis;
|
|
@@ -7126,8 +8242,11 @@ var REJOIN_CONNECT_DEADLINE_MS = 2e3;
|
|
|
7126
8242
|
var REJOIN_REBUILD_TRIGGERS = /* @__PURE__ */ new Set([
|
|
7127
8243
|
"TEXT_MESSAGE_START",
|
|
7128
8244
|
"TEXT_MESSAGE_CONTENT",
|
|
8245
|
+
"TEXT_MESSAGE_CHUNK",
|
|
7129
8246
|
"REASONING_MESSAGE_CONTENT",
|
|
8247
|
+
"REASONING_MESSAGE_CHUNK",
|
|
7130
8248
|
"TOOL_CALL_START",
|
|
8249
|
+
"TOOL_CALL_CHUNK",
|
|
7131
8250
|
"MESSAGES_SNAPSHOT",
|
|
7132
8251
|
"SUBAGENT_STARTED"
|
|
7133
8252
|
]);
|
|
@@ -7231,6 +8350,7 @@ var ChatClient = class {
|
|
|
7231
8350
|
currentMessageId = null;
|
|
7232
8351
|
postStreamActions = [];
|
|
7233
8352
|
pendingToolExecutions = /* @__PURE__ */ new Map();
|
|
8353
|
+
handingOverPendingToolCalls = false;
|
|
7234
8354
|
activeClientTools = null;
|
|
7235
8355
|
activeContext = void 0;
|
|
7236
8356
|
continuationPending = false;
|
|
@@ -7256,6 +8376,12 @@ var ChatClient = class {
|
|
|
7256
8376
|
hydrationError;
|
|
7257
8377
|
/** Whether a view is currently watching. See `attach` / `detach`. */
|
|
7258
8378
|
tailing = false;
|
|
8379
|
+
/** `historyGeneration` of the mount hydration GET still in flight, if any. */
|
|
8380
|
+
hydrationInFlight;
|
|
8381
|
+
/** An async storage adapter is still reading the persisted transcript. */
|
|
8382
|
+
storeHydrating = false;
|
|
8383
|
+
/** See {@link getIsHydrating}. */
|
|
8384
|
+
isHydrating = false;
|
|
7259
8385
|
/** Constructor inputs `attach()` needs on every re-attach, not just the first. */
|
|
7260
8386
|
rejoinRunId;
|
|
7261
8387
|
cachesMessages;
|
|
@@ -7310,6 +8436,7 @@ var ChatClient = class {
|
|
|
7310
8436
|
onSubscriptionChange: options.onSubscriptionChange || (() => {}),
|
|
7311
8437
|
onConnectionStatusChange: options.onConnectionStatusChange || (() => {}),
|
|
7312
8438
|
onSessionGeneratingChange: options.onSessionGeneratingChange || (() => {}),
|
|
8439
|
+
onHydratingChange: options.onHydratingChange || (() => {}),
|
|
7313
8440
|
onQueueChange: options.onQueueChange || (() => {}),
|
|
7314
8441
|
onResumeStateChange: options.onResumeStateChange || (() => {}),
|
|
7315
8442
|
onRunIdChange: options.onRunIdChange || (() => {}),
|
|
@@ -7391,6 +8518,10 @@ var ChatClient = class {
|
|
|
7391
8518
|
onToolCall: (args) => {
|
|
7392
8519
|
const clientTool = (this.activeClientTools ?? this.clientToolsRef.current).get(args.toolName);
|
|
7393
8520
|
const executeFunc = clientTool?.execute;
|
|
8521
|
+
if (this.handingOverPendingToolCalls && clientTool?.needsApproval === true) {
|
|
8522
|
+
console.warn(`[ChatClient] Did not run tool call ${args.toolCallId}: ${args.toolName} needs approval, and the server did not ask for it`);
|
|
8523
|
+
return;
|
|
8524
|
+
}
|
|
7394
8525
|
if (executeFunc) {
|
|
7395
8526
|
const continuationGeneration = this.continuationGeneration;
|
|
7396
8527
|
const runEventContext = this.devtoolsBridge.getCurrentRunEventContext();
|
|
@@ -7437,9 +8568,17 @@ var ChatClient = class {
|
|
|
7437
8568
|
}
|
|
7438
8569
|
});
|
|
7439
8570
|
this.syncSubagentHandles();
|
|
7440
|
-
this.persistor?.hydrateAsync(persistedState);
|
|
8571
|
+
const storeHydration = this.persistor?.hydrateAsync(persistedState);
|
|
8572
|
+
if (storeHydration) {
|
|
8573
|
+
this.storeHydrating = true;
|
|
8574
|
+
storeHydration.finally(() => {
|
|
8575
|
+
this.storeHydrating = false;
|
|
8576
|
+
this.syncIsHydrating();
|
|
8577
|
+
});
|
|
8578
|
+
}
|
|
7441
8579
|
this.rejoinRunId = rejoinRunId;
|
|
7442
8580
|
this.cachesMessages = cachesMessages;
|
|
8581
|
+
this.isHydrating = this.storeHydrating || !cachesMessages && !!this.connection.hydrate;
|
|
7443
8582
|
}
|
|
7444
8583
|
/**
|
|
7445
8584
|
* START TAILING: re-attach to an in-flight run so its chunks arrive here.
|
|
@@ -7542,21 +8681,30 @@ var ChatClient = class {
|
|
|
7542
8681
|
*/
|
|
7543
8682
|
hydrateFromServer() {
|
|
7544
8683
|
const hydrate = this.connection.hydrate;
|
|
7545
|
-
if (!hydrate)
|
|
7546
|
-
|
|
7547
|
-
|
|
8684
|
+
if (!hydrate || this.isLoading || this.abortController || this.disposed) {
|
|
8685
|
+
this.syncIsHydrating();
|
|
8686
|
+
return;
|
|
8687
|
+
}
|
|
8688
|
+
if (this.hydrationInFlight === this.historyGeneration) return;
|
|
7548
8689
|
const pageSize = this.historyPageSize;
|
|
7549
8690
|
const hydrateOptions = pageSize === void 0 ? void 0 : { limit: pageSize };
|
|
7550
8691
|
(async () => {
|
|
7551
8692
|
let result;
|
|
7552
8693
|
const generation = this.historyGeneration;
|
|
8694
|
+
this.hydrationInFlight = generation;
|
|
8695
|
+
this.syncIsHydrating();
|
|
8696
|
+
const isCurrent = () => this.hydrationInFlight === generation && generation === this.historyGeneration;
|
|
8697
|
+
let current;
|
|
7553
8698
|
try {
|
|
7554
8699
|
result = await hydrate(this.threadId, hydrateOptions);
|
|
7555
8700
|
} catch (cause) {
|
|
7556
|
-
if (
|
|
8701
|
+
if (isCurrent()) this.failHydration(cause);
|
|
7557
8702
|
return;
|
|
8703
|
+
} finally {
|
|
8704
|
+
current = isCurrent();
|
|
8705
|
+
if (this.hydrationInFlight === generation) this.hydrationInFlight = void 0;
|
|
7558
8706
|
}
|
|
7559
|
-
if (
|
|
8707
|
+
if (!current) return;
|
|
7560
8708
|
if (this.disposed || !this.tailing) return;
|
|
7561
8709
|
if (this.isLoading || this.abortController) return;
|
|
7562
8710
|
if (this.hydrationError && this.error === this.hydrationError) {
|
|
@@ -7578,7 +8726,7 @@ var ChatClient = class {
|
|
|
7578
8726
|
pendingInterrupts: result.interrupts.pending
|
|
7579
8727
|
});
|
|
7580
8728
|
else if (result.activeRun?.runId) this.maybeRejoinInFlight(result.activeRun.runId);
|
|
7581
|
-
})();
|
|
8729
|
+
})().finally(() => this.syncIsHydrating());
|
|
7582
8730
|
}
|
|
7583
8731
|
/**
|
|
7584
8732
|
* Surface a mount-hydration failure (`persistence: true`) on the observable
|
|
@@ -7847,6 +8995,17 @@ var ChatClient = class {
|
|
|
7847
8995
|
this.isLoading = isLoading;
|
|
7848
8996
|
this.callbacksRef.current.onLoadingChange(isLoading);
|
|
7849
8997
|
this.events.loadingChanged(isLoading);
|
|
8998
|
+
if (isLoading) this.supersedeHydration();
|
|
8999
|
+
}
|
|
9000
|
+
/**
|
|
9001
|
+
* A send or a clear now owns the transcript. A load that is still pending can
|
|
9002
|
+
* no longer paint it (the generation guards drop its result), so it no longer
|
|
9003
|
+
* counts as hydrating.
|
|
9004
|
+
*/
|
|
9005
|
+
supersedeHydration() {
|
|
9006
|
+
this.hydrationInFlight = void 0;
|
|
9007
|
+
this.storeHydrating = false;
|
|
9008
|
+
this.syncIsHydrating();
|
|
7850
9009
|
}
|
|
7851
9010
|
setStatus(status) {
|
|
7852
9011
|
this.status = status;
|
|
@@ -7863,6 +9022,12 @@ var ChatClient = class {
|
|
|
7863
9022
|
this.callbacksRef.current.onConnectionStatusChange(status);
|
|
7864
9023
|
this.devtoolsBridge.emitSnapshot();
|
|
7865
9024
|
}
|
|
9025
|
+
syncIsHydrating() {
|
|
9026
|
+
const isHydrating = this.hydrationInFlight !== void 0 || this.storeHydrating;
|
|
9027
|
+
if (this.isHydrating === isHydrating) return;
|
|
9028
|
+
this.isHydrating = isHydrating;
|
|
9029
|
+
this.callbacksRef.current.onHydratingChange(isHydrating);
|
|
9030
|
+
}
|
|
7866
9031
|
setSessionGenerating(isGenerating) {
|
|
7867
9032
|
if (this.sessionGenerating === isGenerating) return;
|
|
7868
9033
|
this.sessionGenerating = isGenerating;
|
|
@@ -8128,7 +9293,12 @@ var ChatClient = class {
|
|
|
8128
9293
|
this.resolveJoinedRun(chunk);
|
|
8129
9294
|
return;
|
|
8130
9295
|
}
|
|
8131
|
-
this.
|
|
9296
|
+
this.handingOverPendingToolCalls = chunk.type === "RUN_FINISHED" && chunk.outcome?.type !== "interrupt";
|
|
9297
|
+
try {
|
|
9298
|
+
this.processor.processChunk(chunk);
|
|
9299
|
+
} finally {
|
|
9300
|
+
this.handingOverPendingToolCalls = false;
|
|
9301
|
+
}
|
|
8132
9302
|
this.syncSubagentHandles();
|
|
8133
9303
|
this.updateRunLifecycle(chunk);
|
|
8134
9304
|
this.observeInterruptState(chunk);
|
|
@@ -8351,6 +9521,14 @@ var ChatClient = class {
|
|
|
8351
9521
|
if (this.hasPendingInterrupts()) throw new Error("ChatClient: cannot append normal input while pending interrupts exist. Use resumeInterrupts() instead.");
|
|
8352
9522
|
const normalizedMessage = normalizeToUIMessage(message, generateMessageId);
|
|
8353
9523
|
if (normalizedMessage.role === "system") return;
|
|
9524
|
+
if (normalizedMessage.role === "activity") {
|
|
9525
|
+
const uiMessage = normalizedMessage;
|
|
9526
|
+
this.events.messageAppended(uiMessage);
|
|
9527
|
+
const messages = this.processor.getMessages();
|
|
9528
|
+
this.processor.setMessages([...messages, uiMessage]);
|
|
9529
|
+
this.devtoolsBridge.emitSnapshot();
|
|
9530
|
+
return;
|
|
9531
|
+
}
|
|
8354
9532
|
const uiMessage = normalizedMessage;
|
|
8355
9533
|
this.events.messageAppended(uiMessage);
|
|
8356
9534
|
const messages = this.processor.getMessages();
|
|
@@ -8567,6 +9745,7 @@ var ChatClient = class {
|
|
|
8567
9745
|
this.persistor?.beginClear();
|
|
8568
9746
|
this.processor.clearMessages();
|
|
8569
9747
|
this.resetHistoryPaging();
|
|
9748
|
+
this.supersedeHydration();
|
|
8570
9749
|
this.discardPendingSends();
|
|
8571
9750
|
this.persistor?.remove();
|
|
8572
9751
|
this.stoppedSubagentIds.clear();
|
|
@@ -8825,16 +10004,17 @@ var ChatClient = class {
|
|
|
8825
10004
|
this.rememberServerMessageIds(this.processor.getMessages());
|
|
8826
10005
|
}
|
|
8827
10006
|
messagesForSend(messages) {
|
|
8828
|
-
|
|
10007
|
+
const forModel = messages.filter((message) => message.role !== "activity");
|
|
10008
|
+
if (this.historyPageSize === void 0) return forModel;
|
|
8829
10009
|
const unknownMessages = [];
|
|
8830
|
-
for (const message of
|
|
10010
|
+
for (const message of forModel) {
|
|
8831
10011
|
if (this.knownServerMessageIds.has(message.id)) continue;
|
|
8832
10012
|
unknownMessages.push(message);
|
|
8833
10013
|
}
|
|
8834
10014
|
if (unknownMessages.length > 0) return unknownMessages;
|
|
8835
|
-
const lastUserIndex =
|
|
10015
|
+
const lastUserIndex = forModel.findLastIndex((message) => message.role === "user");
|
|
8836
10016
|
if (lastUserIndex === -1) return [];
|
|
8837
|
-
return
|
|
10017
|
+
return forModel.slice(lastUserIndex);
|
|
8838
10018
|
}
|
|
8839
10019
|
/**
|
|
8840
10020
|
* True when an interrupt (or another direct send) claimed the client during
|
|
@@ -8956,6 +10136,15 @@ var ChatClient = class {
|
|
|
8956
10136
|
return this.sessionGenerating;
|
|
8957
10137
|
}
|
|
8958
10138
|
/**
|
|
10139
|
+
* Whether the client is rebuilding the chat from persistence: the server
|
|
10140
|
+
* hydrate (`persistence: true`) or an async storage adapter. Turns false once
|
|
10141
|
+
* the transcript is applied and any in-flight run is re-joined (from then on
|
|
10142
|
+
* `isLoading` covers the stream), or when the load fails.
|
|
10143
|
+
*/
|
|
10144
|
+
getIsHydrating() {
|
|
10145
|
+
return this.isHydrating;
|
|
10146
|
+
}
|
|
10147
|
+
/**
|
|
8959
10148
|
* Get current error
|
|
8960
10149
|
*/
|
|
8961
10150
|
getError() {
|
|
@@ -9006,6 +10195,7 @@ var ChatClient = class {
|
|
|
9006
10195
|
if (options.onSubscriptionChange !== void 0) this.callbacksRef.current.onSubscriptionChange = options.onSubscriptionChange;
|
|
9007
10196
|
if (options.onConnectionStatusChange !== void 0) this.callbacksRef.current.onConnectionStatusChange = options.onConnectionStatusChange;
|
|
9008
10197
|
if (options.onSessionGeneratingChange !== void 0) this.callbacksRef.current.onSessionGeneratingChange = options.onSessionGeneratingChange;
|
|
10198
|
+
if (options.onHydratingChange !== void 0) this.callbacksRef.current.onHydratingChange = options.onHydratingChange;
|
|
9009
10199
|
if (options.onQueueChange !== void 0) this.callbacksRef.current.onQueueChange = options.onQueueChange;
|
|
9010
10200
|
if (options.onResumeStateChange !== void 0) this.callbacksRef.current.onResumeStateChange = options.onResumeStateChange;
|
|
9011
10201
|
if (options.onRunIdChange !== void 0) this.callbacksRef.current.onRunIdChange = options.onRunIdChange;
|
|
@@ -9332,6 +10522,7 @@ async function loadChatAuthToken(options) {
|
|
|
9332
10522
|
} catch (cause) {
|
|
9333
10523
|
signal.throwIfAborted();
|
|
9334
10524
|
const error = cause instanceof Error ? cause : /* @__PURE__ */ new Error("Authentication failed");
|
|
10525
|
+
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
10526
|
session.cached = void 0;
|
|
9336
10527
|
publishAuthentication(options, {
|
|
9337
10528
|
status: "error",
|
|
@@ -9463,6 +10654,11 @@ function hasPendingToolRun(messages, toolNames) {
|
|
|
9463
10654
|
return messages.some((message) => message.parts.some((part) => part.type === "tool-call" && !isSettledToolCall(part) && part.name !== "ask_questionnaire" && toolNames.has(part.name)));
|
|
9464
10655
|
}
|
|
9465
10656
|
//#endregion
|
|
10657
|
+
//#region src/core/web.ts
|
|
10658
|
+
function webPartMetadata(part) {
|
|
10659
|
+
return part.metadata ?? {};
|
|
10660
|
+
}
|
|
10661
|
+
//#endregion
|
|
9466
10662
|
//#region src/core/sandbox.ts
|
|
9467
10663
|
const SANDBOX_TOOLS = [
|
|
9468
10664
|
SANDBOX_WRITE_FILE_TOOL,
|
|
@@ -9513,19 +10709,19 @@ function sandboxPathLabel(part) {
|
|
|
9513
10709
|
if (relative !== void 0 && relative !== ".") return relative;
|
|
9514
10710
|
return text(part.output, "path") ?? text(part.input, "path");
|
|
9515
10711
|
}
|
|
9516
|
-
/** A `sandbox_publish_artifact` call whose output carries
|
|
10712
|
+
/** A `sandbox_publish_artifact` call whose output carries a durable file reference. */
|
|
9517
10713
|
function readSandboxArtifact(part) {
|
|
9518
10714
|
if (part.name !== "sandbox_publish_artifact") return void 0;
|
|
9519
10715
|
const path = text(part.output, "path") ?? text(part.input, "path");
|
|
9520
|
-
const
|
|
10716
|
+
const fileId = text(part.output, "fileId");
|
|
9521
10717
|
return {
|
|
9522
10718
|
toolCallId: part.id,
|
|
9523
10719
|
path: path ?? "",
|
|
9524
10720
|
label: sandboxPathLabel(part) ?? path ?? "",
|
|
9525
10721
|
mimeType: text(part.output, "mimeType"),
|
|
9526
10722
|
size: count(part.output, "size"),
|
|
9527
|
-
|
|
9528
|
-
published:
|
|
10723
|
+
fileId,
|
|
10724
|
+
published: fileId !== void 0 && sandboxRefusal(part) === void 0
|
|
9529
10725
|
};
|
|
9530
10726
|
}
|
|
9531
10727
|
/** A `sandbox_run_command` call. `stdout` holds combined output on providers with no stderr. */
|
|
@@ -9627,6 +10823,10 @@ function projectThreadMessages(records, pendingInteractions = [], liveToolMessag
|
|
|
9627
10823
|
const call = calls.get(savedToolCallId(message.source_assistant_message_id, message.source_tool_part_id, message.response_target_id));
|
|
9628
10824
|
if (!call) continue;
|
|
9629
10825
|
call.output = part.output ?? null;
|
|
10826
|
+
if (call.name === "sandbox_publish_artifact") {
|
|
10827
|
+
call.artifactMessageId = message.id;
|
|
10828
|
+
call.artifactPartId = String(part.id);
|
|
10829
|
+
}
|
|
9630
10830
|
Object.assign(call, { resultOutcome: part.outcome });
|
|
9631
10831
|
call.state = part.outcome === "succeeded" ? "complete" : "error";
|
|
9632
10832
|
}
|
|
@@ -9634,7 +10834,12 @@ function projectThreadMessages(records, pendingInteractions = [], liveToolMessag
|
|
|
9634
10834
|
}
|
|
9635
10835
|
const parts = message.parts.flatMap((part) => {
|
|
9636
10836
|
const source = part.source;
|
|
9637
|
-
if (
|
|
10837
|
+
if (typeof part.type === "string" && [
|
|
10838
|
+
"image",
|
|
10839
|
+
"document",
|
|
10840
|
+
"audio",
|
|
10841
|
+
"video"
|
|
10842
|
+
].includes(part.type) && source && typeof source === "object" && !Array.isArray(source) && "type" in source && source.type === "attachment") return [{
|
|
9638
10843
|
...part,
|
|
9639
10844
|
source: {
|
|
9640
10845
|
...source,
|
|
@@ -9644,6 +10849,7 @@ function projectThreadMessages(records, pendingInteractions = [], liveToolMessag
|
|
|
9644
10849
|
savedAttachmentId: part.id
|
|
9645
10850
|
}];
|
|
9646
10851
|
if (part.type !== "tool-call") return [part];
|
|
10852
|
+
if (part.executionLocation === "provider") return [part];
|
|
9647
10853
|
const toolCallId = String(part.toolCallId);
|
|
9648
10854
|
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
10855
|
return (targets.length ? targets : [void 0]).map((responseTargetId) => {
|
|
@@ -9714,6 +10920,7 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
9714
10920
|
capabilities: { attachments: true },
|
|
9715
10921
|
agentTools: [],
|
|
9716
10922
|
sandboxStatus: void 0,
|
|
10923
|
+
usageLimitReached: void 0,
|
|
9717
10924
|
sandbox: {
|
|
9718
10925
|
files: [],
|
|
9719
10926
|
commands: []
|
|
@@ -9764,6 +10971,14 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
9764
10971
|
} });
|
|
9765
10972
|
pendingSend.callbacks?.onAccepted?.();
|
|
9766
10973
|
};
|
|
10974
|
+
const replaceAcceptedMessage = (record) => {
|
|
10975
|
+
const messages = [...client.getMessages()];
|
|
10976
|
+
const index = messages.findLastIndex((message) => message.role === "user");
|
|
10977
|
+
if (index !== -1) {
|
|
10978
|
+
messages[index] = projectThreadMessages([record])[0];
|
|
10979
|
+
client.setMessagesManually(messages);
|
|
10980
|
+
}
|
|
10981
|
+
};
|
|
9767
10982
|
const liveToolCalls = /* @__PURE__ */ new Set();
|
|
9768
10983
|
const liveToolMessageIds = /* @__PURE__ */ new Map();
|
|
9769
10984
|
const historicalToolIds = /* @__PURE__ */ new Map();
|
|
@@ -9793,17 +11008,19 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
9793
11008
|
error: failure,
|
|
9794
11009
|
status: "error"
|
|
9795
11010
|
});
|
|
9796
|
-
live.streamCallbacks?.onError?.(failure);
|
|
11011
|
+
if (state.auth.status !== "error" || state.auth.error !== failure) live.streamCallbacks?.onError?.(failure);
|
|
9797
11012
|
};
|
|
9798
|
-
const requestOptions = async () => {
|
|
11013
|
+
const requestOptions = async (conversation = true) => {
|
|
9799
11014
|
const generation = selectionGeneration;
|
|
11015
|
+
const authSignal = authentication.session.abortController.signal;
|
|
9800
11016
|
const token = await getValidChatAuthToken(authentication);
|
|
9801
|
-
|
|
11017
|
+
authSignal.throwIfAborted();
|
|
11018
|
+
if (conversation && generation !== selectionGeneration) throw new DOMException("Conversation changed", "AbortError");
|
|
9802
11019
|
return {
|
|
9803
11020
|
apiUrl: authentication.apiUrl,
|
|
9804
11021
|
astralBeamToken: token,
|
|
9805
11022
|
cache: "no-store",
|
|
9806
|
-
signal: AbortSignal.any([requestController.signal,
|
|
11023
|
+
signal: conversation ? AbortSignal.any([requestController.signal, authSignal]) : authSignal,
|
|
9807
11024
|
fetchClient: (input, init) => fetchAuthenticatedChat({
|
|
9808
11025
|
...authentication,
|
|
9809
11026
|
input,
|
|
@@ -10007,6 +11224,11 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10007
11224
|
headers,
|
|
10008
11225
|
body: JSON.stringify(payload)
|
|
10009
11226
|
}).catch((error) => {
|
|
11227
|
+
const limit = isAstralBeamApiError(error) ? error.body?.usage_limit : void 0;
|
|
11228
|
+
if (limit) update({ usageLimitReached: {
|
|
11229
|
+
name: limit.name,
|
|
11230
|
+
resetsAt: limit.resets_at
|
|
11231
|
+
} });
|
|
10010
11232
|
if (submission && !previouslyAttempted && isAstralBeamApiError(error) && (error.status === 400 || error.status === 413 || error.status === 429)) delete submission.tools;
|
|
10011
11233
|
throw error;
|
|
10012
11234
|
});
|
|
@@ -10014,11 +11236,23 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10014
11236
|
if (response.headers.get("Content-Type")?.includes("application/json")) {
|
|
10015
11237
|
const receipt = await response.json();
|
|
10016
11238
|
if (generation !== selectionGeneration) throw new DOMException("Conversation changed", "AbortError");
|
|
10017
|
-
update({
|
|
10018
|
-
|
|
10019
|
-
|
|
10020
|
-
|
|
10021
|
-
|
|
11239
|
+
update({
|
|
11240
|
+
thread: {
|
|
11241
|
+
...state.thread,
|
|
11242
|
+
version: receipt.thread_version
|
|
11243
|
+
},
|
|
11244
|
+
...receipt.usage_limit ? { usageLimitReached: {
|
|
11245
|
+
name: receipt.usage_limit.name,
|
|
11246
|
+
resetsAt: receipt.usage_limit.resets_at
|
|
11247
|
+
} } : {}
|
|
11248
|
+
});
|
|
11249
|
+
if (submission) {
|
|
11250
|
+
const history = await loadThreadMessages(thread.id, auth, void 0, liveToolMessageIds);
|
|
11251
|
+
if (generation !== selectionGeneration) throw new DOMException("Conversation changed", "AbortError");
|
|
11252
|
+
const accepted = history.messages.find((message) => message.id === receipt.accepted_message_id);
|
|
11253
|
+
if (accepted) replaceAcceptedMessage(accepted);
|
|
11254
|
+
acceptPendingSend();
|
|
11255
|
+
}
|
|
10022
11256
|
return new Response("", { headers: { "Content-Type": "text/event-stream" } });
|
|
10023
11257
|
}
|
|
10024
11258
|
return response;
|
|
@@ -10143,6 +11377,11 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10143
11377
|
onMessagesChange: (messages) => {
|
|
10144
11378
|
if (client !== next || generation !== selectionGeneration) return;
|
|
10145
11379
|
restoreCompletedWidgets(messages);
|
|
11380
|
+
for (const message of messages) {
|
|
11381
|
+
if (message.role !== "user") continue;
|
|
11382
|
+
const saved = state.messages.find((previous) => previous.id === message.id);
|
|
11383
|
+
if (saved?.parts.some((part) => "savedAttachmentId" in part)) message.parts = saved.parts;
|
|
11384
|
+
}
|
|
10146
11385
|
update({
|
|
10147
11386
|
messages,
|
|
10148
11387
|
sandbox: collectSandboxActivity(messages),
|
|
@@ -10152,7 +11391,8 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10152
11391
|
onStatusChange: (status) => {
|
|
10153
11392
|
if (client === next && generation === selectionGeneration) update({
|
|
10154
11393
|
status,
|
|
10155
|
-
error: next.getError()
|
|
11394
|
+
error: next.getError(),
|
|
11395
|
+
...status === "submitted" ? { usageLimitReached: void 0 } : {}
|
|
10156
11396
|
});
|
|
10157
11397
|
},
|
|
10158
11398
|
onInterruptStateChange: (interrupts) => {
|
|
@@ -10163,6 +11403,7 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10163
11403
|
if (eventType === "astralbeam_thread") {
|
|
10164
11404
|
const event = data;
|
|
10165
11405
|
if (state.thread?.id === event.threadId) {
|
|
11406
|
+
if (event.acceptedMessage && pendingSend && !pendingSend.accepted) replaceAcceptedMessage(event.acceptedMessage);
|
|
10166
11407
|
if (event.acceptedMessageId) acceptPendingSend();
|
|
10167
11408
|
if (event.saved) for (const id of event.executableToolCallIds ?? []) {
|
|
10168
11409
|
if (!liveToolCalls.has(id)) toolResults.delete(toolResultKey(id));
|
|
@@ -10179,6 +11420,14 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10179
11420
|
}
|
|
10180
11421
|
return;
|
|
10181
11422
|
}
|
|
11423
|
+
const limit = data;
|
|
11424
|
+
if (eventType === "astralbeam.usage_limit.reached" && typeof limit?.name === "string" && typeof limit.resetsAt === "string") {
|
|
11425
|
+
update({ usageLimitReached: {
|
|
11426
|
+
name: limit.name,
|
|
11427
|
+
resetsAt: limit.resetsAt
|
|
11428
|
+
} });
|
|
11429
|
+
return;
|
|
11430
|
+
}
|
|
10182
11431
|
const value = data?.state;
|
|
10183
11432
|
if (eventType === "astralbeam.sandbox.status" && (value === "starting" || value === "ready" || value === "error")) {
|
|
10184
11433
|
debug?.("sandbox", `sandbox ${value}`);
|
|
@@ -10198,7 +11447,7 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10198
11447
|
if (client === next) live.streamCallbacks?.onFinish?.(message);
|
|
10199
11448
|
},
|
|
10200
11449
|
onError: (error) => {
|
|
10201
|
-
if (client === next) live.streamCallbacks?.onError?.(error);
|
|
11450
|
+
if (client === next && (state.auth.status !== "error" || state.auth.error !== error)) live.streamCallbacks?.onError?.(error);
|
|
10202
11451
|
}
|
|
10203
11452
|
});
|
|
10204
11453
|
return next;
|
|
@@ -10220,7 +11469,7 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10220
11469
|
client.setMessagesManually(state.messages.map((message) => {
|
|
10221
11470
|
const aliases = /* @__PURE__ */ new Map();
|
|
10222
11471
|
const parts = message.parts.map((part) => {
|
|
10223
|
-
if (part.type !== "tool-call") return part;
|
|
11472
|
+
if (part.type !== "tool-call" || webPartMetadata(part).providerExecuted) return part;
|
|
10224
11473
|
const stored = part;
|
|
10225
11474
|
const upstreamToolCallId = stored.upstreamToolCallId ?? part.id;
|
|
10226
11475
|
if (liveToolMessageIds.get(upstreamToolCallId) === message.id && !isSettledToolCall(part)) return part;
|
|
@@ -10268,6 +11517,7 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10268
11517
|
commands: []
|
|
10269
11518
|
},
|
|
10270
11519
|
sandboxStatus: void 0,
|
|
11520
|
+
usageLimitReached: void 0,
|
|
10271
11521
|
pendingInteractions: [],
|
|
10272
11522
|
threadLoadFailed: false,
|
|
10273
11523
|
messagesCursor: void 0,
|
|
@@ -10434,7 +11684,7 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10434
11684
|
});
|
|
10435
11685
|
}
|
|
10436
11686
|
scopeCompletedToolCalls();
|
|
10437
|
-
if (pending
|
|
11687
|
+
if (pending) {
|
|
10438
11688
|
replaceClient();
|
|
10439
11689
|
await hydration;
|
|
10440
11690
|
if (generation !== selectionGeneration) return;
|
|
@@ -10528,6 +11778,7 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10528
11778
|
};
|
|
10529
11779
|
const observeAuthentication = () => {
|
|
10530
11780
|
const auth = authenticationState(authentication);
|
|
11781
|
+
const previous = state.auth;
|
|
10531
11782
|
if (auth.status === "ready") {
|
|
10532
11783
|
const nextIdentity = authenticationIdentity(auth.currentUser);
|
|
10533
11784
|
if (identity !== void 0 && identity !== nextIdentity) {
|
|
@@ -10553,6 +11804,7 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10553
11804
|
}
|
|
10554
11805
|
}
|
|
10555
11806
|
update({ auth });
|
|
11807
|
+
if (auth.status === "error" && (previous.status !== "error" || previous.error !== auth.error)) live.streamCallbacks?.onError?.(auth.error);
|
|
10556
11808
|
};
|
|
10557
11809
|
const start = () => {
|
|
10558
11810
|
if (started) return;
|
|
@@ -10646,6 +11898,28 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
10646
11898
|
deleteThread,
|
|
10647
11899
|
refreshThread,
|
|
10648
11900
|
loadOlderMessages,
|
|
11901
|
+
uploadAttachment: async ({ data, filename, mimeType }) => {
|
|
11902
|
+
const agentId = state.thread ? state.thread.agentId : live.agentId;
|
|
11903
|
+
const [encoded, options] = await Promise.all([data, requestOptions(false)]);
|
|
11904
|
+
return uploadChatFile({
|
|
11905
|
+
...agentId ? { agentId } : {},
|
|
11906
|
+
type: mimeType.startsWith("image/") ? "image" : "document",
|
|
11907
|
+
source: {
|
|
11908
|
+
type: "data",
|
|
11909
|
+
value: encoded,
|
|
11910
|
+
mimeType
|
|
11911
|
+
},
|
|
11912
|
+
metadata: { filename }
|
|
11913
|
+
}, options);
|
|
11914
|
+
},
|
|
11915
|
+
getFile: async (fileId) => {
|
|
11916
|
+
const thread = state.thread;
|
|
11917
|
+
if (!thread) throw new Error("Open a conversation before downloading files.");
|
|
11918
|
+
return (await getChatFile({
|
|
11919
|
+
threadId: thread.id,
|
|
11920
|
+
fileId
|
|
11921
|
+
}, await requestOptions())).blob();
|
|
11922
|
+
},
|
|
10649
11923
|
getAttachment: async (messageId, partId) => {
|
|
10650
11924
|
const thread = state.thread;
|
|
10651
11925
|
if (!thread) throw new Error("Open a conversation before downloading attachments.");
|