@astralbeam/sdk 0.21.0 → 0.22.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 +6 -2
- package/dist/abort-_ZeHSwUG.js +1 -0
- package/dist/{api-qmAF_i2J.js → api-SpkUzEv3.js} +19 -1
- package/dist/api.d.ts +2 -2
- package/dist/api.js +1 -1
- package/dist/{badge-DEqUq7lR.js → badge-DhXUFnRC.js} +1 -1
- package/dist/client.d.ts +6 -4
- package/dist/client.js +1 -1
- package/dist/{core-BkceDZxh.js → core-CWFT6Db_.js} +1581 -741
- package/dist/core.d.ts +1 -1
- package/dist/core.js +1 -1
- package/dist/{highlighter-DofmUpLd.js → highlighter-DldDI8mb.js} +1 -1
- package/dist/{index-Bc8nJgEh.d.ts → index-D8X2hDGe.d.ts} +32 -9
- package/dist/{index-DaTte7o4.d.ts → index-DatxwZpZ.d.ts} +394 -113
- package/dist/{item-CtaQ4LyP.js → item-Cv2zb7Kn.js} +1 -1
- package/dist/listings-CyliP2E5.js +1 -0
- package/dist/{mcp-servers-Bl0jxCiZ.js → mcp-servers-DvCu1KuJ.js} +1 -1
- package/dist/react.d.ts +11 -58
- package/dist/react.js +14 -15
- package/dist/{styles.generated-3vAmuPc7.js → styles.generated-CwyGUg6r.js} +1 -1
- package/dist/{threads-BMixqjfd.js → threads-rrcqQzl8.js} +3 -3
- package/dist/widget-BOdanf0E.js +27 -0
- package/package.json +4 -4
- package/dist/listings-Ce0aH6yf.js +0 -1
- package/dist/widget-Cvh8BS9U.js +0 -26
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Bt as resolveApiUrl, Ct as personalMcpCompleteAuthorization, Dt as personalMcpSetHeaders, Et as personalMcpGetCatalog, Lt as uploadChatFile, O as getCurrentUser, Ot as personalMcpTestConnection, Pt as updateChatThread, Rt as astralBeamChatFetch, S as getChatConfig, St as personalMcpBindBrowser, Tt as personalMcpDisconnectConnection, gt as listChatThreads, lt as getThreadAttachment, mt as listChatMessages, nt as getResolveChatToolResultUrl, rt as getRunChatUrl, v as createChatThread, wt as personalMcpCreateConnection, x as deleteChatThread, xt as personalMcpAuthorizeConnection, zt as isAstralBeamApiError } from "./api-SpkUzEv3.js";
|
|
2
2
|
import { _ as strictDecoder, i as isObject, l as decode, p as JWTInvalid } from "./validate-BOw-BAyv.js";
|
|
3
3
|
//#region \0rolldown/runtime.js
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -36,7 +36,442 @@ function decodeJwt(jwt) {
|
|
|
36
36
|
return result;
|
|
37
37
|
}
|
|
38
38
|
//#endregion
|
|
39
|
-
//#region ../node_modules/.bun/@tanstack+
|
|
39
|
+
//#region ../node_modules/.bun/@tanstack+store@0.11.2/node_modules/@tanstack/store/dist/alien.js
|
|
40
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
41
|
+
function createReactiveSystem({ update, notify, unwatched }) {
|
|
42
|
+
return {
|
|
43
|
+
link,
|
|
44
|
+
unlink,
|
|
45
|
+
propagate,
|
|
46
|
+
checkDirty,
|
|
47
|
+
shallowPropagate
|
|
48
|
+
};
|
|
49
|
+
function link(dep, sub, version) {
|
|
50
|
+
const prevDep = sub.depsTail;
|
|
51
|
+
if (prevDep !== void 0 && prevDep.dep === dep) return;
|
|
52
|
+
const nextDep = prevDep !== void 0 ? prevDep.nextDep : sub.deps;
|
|
53
|
+
if (nextDep !== void 0 && nextDep.dep === dep) {
|
|
54
|
+
nextDep.version = version;
|
|
55
|
+
sub.depsTail = nextDep;
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const prevSub = dep.subsTail;
|
|
59
|
+
if (prevSub !== void 0 && prevSub.version === version && prevSub.sub === sub) return;
|
|
60
|
+
const newLink = sub.depsTail = dep.subsTail = {
|
|
61
|
+
version,
|
|
62
|
+
dep,
|
|
63
|
+
sub,
|
|
64
|
+
prevDep,
|
|
65
|
+
nextDep,
|
|
66
|
+
prevSub,
|
|
67
|
+
nextSub: void 0
|
|
68
|
+
};
|
|
69
|
+
if (nextDep !== void 0) nextDep.prevDep = newLink;
|
|
70
|
+
if (prevDep !== void 0) prevDep.nextDep = newLink;
|
|
71
|
+
else sub.deps = newLink;
|
|
72
|
+
if (prevSub !== void 0) prevSub.nextSub = newLink;
|
|
73
|
+
else dep.subs = newLink;
|
|
74
|
+
}
|
|
75
|
+
function unlink(link, sub = link.sub) {
|
|
76
|
+
const dep = link.dep;
|
|
77
|
+
const prevDep = link.prevDep;
|
|
78
|
+
const nextDep = link.nextDep;
|
|
79
|
+
const nextSub = link.nextSub;
|
|
80
|
+
const prevSub = link.prevSub;
|
|
81
|
+
if (nextDep !== void 0) nextDep.prevDep = prevDep;
|
|
82
|
+
else sub.depsTail = prevDep;
|
|
83
|
+
if (prevDep !== void 0) prevDep.nextDep = nextDep;
|
|
84
|
+
else sub.deps = nextDep;
|
|
85
|
+
if (nextSub !== void 0) nextSub.prevSub = prevSub;
|
|
86
|
+
else dep.subsTail = prevSub;
|
|
87
|
+
if (prevSub !== void 0) prevSub.nextSub = nextSub;
|
|
88
|
+
else if ((dep.subs = nextSub) === void 0) unwatched(dep);
|
|
89
|
+
return nextDep;
|
|
90
|
+
}
|
|
91
|
+
function propagate(link) {
|
|
92
|
+
let next = link.nextSub;
|
|
93
|
+
let stack;
|
|
94
|
+
top: do {
|
|
95
|
+
const sub = link.sub;
|
|
96
|
+
let flags = sub.flags;
|
|
97
|
+
if (!(flags & 60)) sub.flags = flags | 32;
|
|
98
|
+
else if (!(flags & 12)) flags = 0;
|
|
99
|
+
else if (!(flags & 4)) sub.flags = flags & -9 | 32;
|
|
100
|
+
else if (!(flags & 48) && isValidLink(link, sub)) {
|
|
101
|
+
sub.flags = flags | 40;
|
|
102
|
+
flags &= 1;
|
|
103
|
+
} else flags = 0;
|
|
104
|
+
if (flags & 2) notify(sub);
|
|
105
|
+
if (flags & 1) {
|
|
106
|
+
const subSubs = sub.subs;
|
|
107
|
+
if (subSubs !== void 0) {
|
|
108
|
+
const nextSub = (link = subSubs).nextSub;
|
|
109
|
+
if (nextSub !== void 0) {
|
|
110
|
+
stack = {
|
|
111
|
+
value: next,
|
|
112
|
+
prev: stack
|
|
113
|
+
};
|
|
114
|
+
next = nextSub;
|
|
115
|
+
}
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if ((link = next) !== void 0) {
|
|
120
|
+
next = link.nextSub;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
while (stack !== void 0) {
|
|
124
|
+
link = stack.value;
|
|
125
|
+
stack = stack.prev;
|
|
126
|
+
if (link !== void 0) {
|
|
127
|
+
next = link.nextSub;
|
|
128
|
+
continue top;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
break;
|
|
132
|
+
} while (true);
|
|
133
|
+
}
|
|
134
|
+
function checkDirty(link, sub) {
|
|
135
|
+
let stack;
|
|
136
|
+
let checkDepth = 0;
|
|
137
|
+
let dirty = false;
|
|
138
|
+
top: do {
|
|
139
|
+
const dep = link.dep;
|
|
140
|
+
const flags = dep.flags;
|
|
141
|
+
if (sub.flags & 16) dirty = true;
|
|
142
|
+
else if ((flags & 17) === 17) {
|
|
143
|
+
if (update(dep)) {
|
|
144
|
+
const subs = dep.subs;
|
|
145
|
+
if (subs.nextSub !== void 0) shallowPropagate(subs);
|
|
146
|
+
dirty = true;
|
|
147
|
+
}
|
|
148
|
+
} else if ((flags & 33) === 33) {
|
|
149
|
+
if (link.nextSub !== void 0 || link.prevSub !== void 0) stack = {
|
|
150
|
+
value: link,
|
|
151
|
+
prev: stack
|
|
152
|
+
};
|
|
153
|
+
link = dep.deps;
|
|
154
|
+
sub = dep;
|
|
155
|
+
++checkDepth;
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (!dirty) {
|
|
159
|
+
const nextDep = link.nextDep;
|
|
160
|
+
if (nextDep !== void 0) {
|
|
161
|
+
link = nextDep;
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
while (checkDepth--) {
|
|
166
|
+
const firstSub = sub.subs;
|
|
167
|
+
const hasMultipleSubs = firstSub.nextSub !== void 0;
|
|
168
|
+
if (hasMultipleSubs) {
|
|
169
|
+
link = stack.value;
|
|
170
|
+
stack = stack.prev;
|
|
171
|
+
} else link = firstSub;
|
|
172
|
+
if (dirty) {
|
|
173
|
+
if (update(sub)) {
|
|
174
|
+
if (hasMultipleSubs) shallowPropagate(firstSub);
|
|
175
|
+
sub = link.sub;
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
dirty = false;
|
|
179
|
+
} else sub.flags &= -33;
|
|
180
|
+
sub = link.sub;
|
|
181
|
+
const nextDep = link.nextDep;
|
|
182
|
+
if (nextDep !== void 0) {
|
|
183
|
+
link = nextDep;
|
|
184
|
+
continue top;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return dirty;
|
|
188
|
+
} while (true);
|
|
189
|
+
}
|
|
190
|
+
function shallowPropagate(link) {
|
|
191
|
+
do {
|
|
192
|
+
const sub = link.sub;
|
|
193
|
+
const flags = sub.flags;
|
|
194
|
+
if ((flags & 48) === 32) {
|
|
195
|
+
sub.flags = flags | 16;
|
|
196
|
+
if ((flags & 6) === 2) notify(sub);
|
|
197
|
+
}
|
|
198
|
+
} while ((link = link.nextSub) !== void 0);
|
|
199
|
+
}
|
|
200
|
+
function isValidLink(checkLink, sub) {
|
|
201
|
+
let link = sub.depsTail;
|
|
202
|
+
while (link !== void 0) {
|
|
203
|
+
if (link === checkLink) return true;
|
|
204
|
+
link = link.prevDep;
|
|
205
|
+
}
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
//#endregion
|
|
210
|
+
//#region ../node_modules/.bun/@tanstack+store@0.11.2/node_modules/@tanstack/store/dist/atom.js
|
|
211
|
+
function toObserver(nextHandler, errorHandler, completionHandler) {
|
|
212
|
+
const isObserver = typeof nextHandler === "object";
|
|
213
|
+
const self = isObserver ? nextHandler : void 0;
|
|
214
|
+
return {
|
|
215
|
+
next: (isObserver ? nextHandler.next : nextHandler)?.bind(self),
|
|
216
|
+
error: (isObserver ? nextHandler.error : errorHandler)?.bind(self),
|
|
217
|
+
complete: (isObserver ? nextHandler.complete : completionHandler)?.bind(self)
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
const queuedEffects = [];
|
|
221
|
+
let cycle = 0;
|
|
222
|
+
const { link, unlink, propagate, checkDirty, shallowPropagate } = /* @__PURE__ */ createReactiveSystem({
|
|
223
|
+
update(atom) {
|
|
224
|
+
return atom._update();
|
|
225
|
+
},
|
|
226
|
+
notify(effect) {
|
|
227
|
+
queuedEffects[queuedEffectsLength++] = effect;
|
|
228
|
+
effect.flags &= -3;
|
|
229
|
+
},
|
|
230
|
+
unwatched(atom) {
|
|
231
|
+
if (atom.depsTail !== void 0) {
|
|
232
|
+
atom.depsTail = void 0;
|
|
233
|
+
atom.flags = 17;
|
|
234
|
+
purgeDeps(atom);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
let notifyIndex = 0;
|
|
239
|
+
let queuedEffectsLength = 0;
|
|
240
|
+
let activeSub;
|
|
241
|
+
function purgeDeps(sub) {
|
|
242
|
+
const depsTail = sub.depsTail;
|
|
243
|
+
let dep = depsTail !== void 0 ? depsTail.nextDep : sub.deps;
|
|
244
|
+
while (dep !== void 0) dep = unlink(dep, sub);
|
|
245
|
+
}
|
|
246
|
+
function flush() {
|
|
247
|
+
while (notifyIndex < queuedEffectsLength) {
|
|
248
|
+
const effect = queuedEffects[notifyIndex];
|
|
249
|
+
queuedEffects[notifyIndex++] = void 0;
|
|
250
|
+
effect.notify();
|
|
251
|
+
}
|
|
252
|
+
notifyIndex = 0;
|
|
253
|
+
queuedEffectsLength = 0;
|
|
254
|
+
}
|
|
255
|
+
function createAtom(valueOrFn, options) {
|
|
256
|
+
const isComputed = typeof valueOrFn === "function";
|
|
257
|
+
const getter = valueOrFn;
|
|
258
|
+
const atom = {
|
|
259
|
+
_snapshot: isComputed ? void 0 : valueOrFn,
|
|
260
|
+
subs: void 0,
|
|
261
|
+
subsTail: void 0,
|
|
262
|
+
deps: void 0,
|
|
263
|
+
depsTail: void 0,
|
|
264
|
+
flags: isComputed ? 0 : 1,
|
|
265
|
+
get() {
|
|
266
|
+
if (activeSub !== void 0) link(atom, activeSub, cycle);
|
|
267
|
+
return atom._snapshot;
|
|
268
|
+
},
|
|
269
|
+
subscribe(observerOrFn) {
|
|
270
|
+
const obs = toObserver(observerOrFn);
|
|
271
|
+
const observed = { current: false };
|
|
272
|
+
const e = effect(() => {
|
|
273
|
+
atom.get();
|
|
274
|
+
if (!observed.current) observed.current = true;
|
|
275
|
+
else {
|
|
276
|
+
activeSub = void 0;
|
|
277
|
+
obs.next?.(atom._snapshot);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
return { unsubscribe: () => {
|
|
281
|
+
e.stop();
|
|
282
|
+
} };
|
|
283
|
+
},
|
|
284
|
+
_update(getValue) {
|
|
285
|
+
const prevSub = activeSub;
|
|
286
|
+
const compare = options?.compare ?? Object.is;
|
|
287
|
+
if (isComputed) {
|
|
288
|
+
activeSub = atom;
|
|
289
|
+
++cycle;
|
|
290
|
+
atom.depsTail = void 0;
|
|
291
|
+
} else if (getValue === void 0) return false;
|
|
292
|
+
if (isComputed) atom.flags = 5;
|
|
293
|
+
try {
|
|
294
|
+
const oldValue = atom._snapshot;
|
|
295
|
+
const newValue = typeof getValue === "function" ? getValue(oldValue) : getValue === void 0 && isComputed ? getter(oldValue) : getValue;
|
|
296
|
+
if (oldValue === void 0 || !compare(oldValue, newValue)) {
|
|
297
|
+
atom._snapshot = newValue;
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
return false;
|
|
301
|
+
} finally {
|
|
302
|
+
activeSub = prevSub;
|
|
303
|
+
if (isComputed) atom.flags &= -5;
|
|
304
|
+
purgeDeps(atom);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
if (isComputed) {
|
|
309
|
+
atom.flags = 17;
|
|
310
|
+
atom.get = function() {
|
|
311
|
+
const flags = atom.flags;
|
|
312
|
+
if (flags & 16 || flags & 32 && checkDirty(atom.deps, atom)) {
|
|
313
|
+
if (atom._update()) {
|
|
314
|
+
const subs = atom.subs;
|
|
315
|
+
if (subs !== void 0) shallowPropagate(subs);
|
|
316
|
+
}
|
|
317
|
+
} else if (flags & 32) atom.flags = flags & -33;
|
|
318
|
+
if (activeSub !== void 0) link(atom, activeSub, cycle);
|
|
319
|
+
return atom._snapshot;
|
|
320
|
+
};
|
|
321
|
+
} else atom.set = function(valueOrFn) {
|
|
322
|
+
if (atom._update(valueOrFn)) {
|
|
323
|
+
const subs = atom.subs;
|
|
324
|
+
if (subs !== void 0) {
|
|
325
|
+
propagate(subs);
|
|
326
|
+
shallowPropagate(subs);
|
|
327
|
+
flush();
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
return atom;
|
|
332
|
+
}
|
|
333
|
+
function effect(fn) {
|
|
334
|
+
const run = () => {
|
|
335
|
+
const prevSub = activeSub;
|
|
336
|
+
activeSub = effectObj;
|
|
337
|
+
++cycle;
|
|
338
|
+
effectObj.depsTail = void 0;
|
|
339
|
+
effectObj.flags = 6;
|
|
340
|
+
try {
|
|
341
|
+
return fn();
|
|
342
|
+
} finally {
|
|
343
|
+
activeSub = prevSub;
|
|
344
|
+
effectObj.flags &= -5;
|
|
345
|
+
purgeDeps(effectObj);
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
const effectObj = {
|
|
349
|
+
deps: void 0,
|
|
350
|
+
depsTail: void 0,
|
|
351
|
+
subs: void 0,
|
|
352
|
+
subsTail: void 0,
|
|
353
|
+
flags: 6,
|
|
354
|
+
notify() {
|
|
355
|
+
const flags = this.flags;
|
|
356
|
+
if (flags & 16 || flags & 32 && checkDirty(this.deps, this)) run();
|
|
357
|
+
else this.flags = 2;
|
|
358
|
+
},
|
|
359
|
+
stop() {
|
|
360
|
+
this.flags = 0;
|
|
361
|
+
this.depsTail = void 0;
|
|
362
|
+
purgeDeps(this);
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
run();
|
|
366
|
+
return effectObj;
|
|
367
|
+
}
|
|
368
|
+
//#endregion
|
|
369
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/snapshot-atom.js
|
|
370
|
+
function isPlainObject(value) {
|
|
371
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
372
|
+
const proto = Object.getPrototypeOf(value);
|
|
373
|
+
return proto === Object.prototype || proto === null;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Report an error thrown by a listener without stopping the caller. The
|
|
377
|
+
* browser's `reportError` reaches `window.onerror` and error trackers. Other
|
|
378
|
+
* runtimes log it.
|
|
379
|
+
*/
|
|
380
|
+
function reportListenerError(error) {
|
|
381
|
+
if (typeof globalThis.reportError === "function") globalThis.reportError(error);
|
|
382
|
+
else console.error(error);
|
|
383
|
+
}
|
|
384
|
+
/** Deep-freeze plain JSON. Class instances stay as they are. */
|
|
385
|
+
function freezePlainData(value) {
|
|
386
|
+
if (Array.isArray(value)) return Object.freeze(value.map(freezePlainData));
|
|
387
|
+
if (!isPlainObject(value)) return value;
|
|
388
|
+
const copy = {};
|
|
389
|
+
for (const key of Object.keys(value)) copy[key] = freezePlainData(value[key]);
|
|
390
|
+
return Object.freeze(copy);
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Freeze a copy of one message part. Tool `input` / `output`, `source`,
|
|
394
|
+
* `approval`, tool-result `content`, and subagent transcripts are copies.
|
|
395
|
+
* A subagent `stop` function stays the live function.
|
|
396
|
+
*/
|
|
397
|
+
function freezeSnapshotPart(part, cache = /* @__PURE__ */ new WeakMap()) {
|
|
398
|
+
const record = part;
|
|
399
|
+
const copy = { ...record };
|
|
400
|
+
if (isPlainObject(record.source)) copy.source = Object.freeze({ ...record.source });
|
|
401
|
+
if (record.type === "tool-call" && isPlainObject(record.approval)) copy.approval = Object.freeze({ ...record.approval });
|
|
402
|
+
if (record.type === "tool-result" && Array.isArray(record.content)) copy.content = Object.freeze(record.content.map((contentPart) => typeof contentPart === "object" && contentPart !== null ? freezeSnapshotPart(contentPart, cache) : contentPart));
|
|
403
|
+
if ("input" in record) copy.input = freezePlainData(record.input);
|
|
404
|
+
if ("output" in record) copy.output = freezePlainData(record.output);
|
|
405
|
+
if (record.type === "subagent" && isPlainObject(record.subagent)) {
|
|
406
|
+
const sub = record.subagent;
|
|
407
|
+
copy.subagent = Object.freeze(Array.isArray(sub.messages) ? {
|
|
408
|
+
...sub,
|
|
409
|
+
messages: freezeSnapshotMessages(cache, sub.messages)
|
|
410
|
+
} : { ...sub });
|
|
411
|
+
}
|
|
412
|
+
return Object.freeze(copy);
|
|
413
|
+
}
|
|
414
|
+
function cached(cache, value, freeze) {
|
|
415
|
+
let frozen = cache.get(value);
|
|
416
|
+
if (!frozen) {
|
|
417
|
+
frozen = freeze(value);
|
|
418
|
+
cache.set(value, frozen);
|
|
419
|
+
}
|
|
420
|
+
return frozen;
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Freeze a copy of each message and its parts. The client replaces a message
|
|
424
|
+
* or a part object when it changes, so `cache` gives an unchanged message or
|
|
425
|
+
* part the same frozen copy. UI memo keys on message identity, and a streamed
|
|
426
|
+
* token copies only the part that changed.
|
|
427
|
+
*/
|
|
428
|
+
function freezeSnapshotMessages(cache, messages) {
|
|
429
|
+
return Object.freeze(messages.map((message) => cached(cache, message, () => Object.freeze({
|
|
430
|
+
...message,
|
|
431
|
+
parts: Object.freeze(message.parts.map((part) => cached(cache, part, () => freezeSnapshotPart(part, cache))))
|
|
432
|
+
}))));
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Merge a partial update into an object atom and freeze the result. Skips
|
|
436
|
+
* notify when every provided field is `Object.is`-equal to the current value.
|
|
437
|
+
*/
|
|
438
|
+
function patchAtom(atom, patch) {
|
|
439
|
+
atom.set((prev) => {
|
|
440
|
+
let changed = false;
|
|
441
|
+
const next = { ...prev };
|
|
442
|
+
for (const key of Object.keys(patch)) {
|
|
443
|
+
if (Object.is(prev[key], patch[key])) continue;
|
|
444
|
+
next[key] = patch[key];
|
|
445
|
+
changed = true;
|
|
446
|
+
}
|
|
447
|
+
return changed ? Object.freeze(next) : prev;
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
var MAX_LISTENER_REENTRY = 8;
|
|
451
|
+
/**
|
|
452
|
+
* Subscribe to an atom with the `() => void` unsubscribe that framework
|
|
453
|
+
* stores expect.
|
|
454
|
+
*/
|
|
455
|
+
function subscribeAtom(atom, listener) {
|
|
456
|
+
const { unsubscribe } = atom.subscribe(() => {
|
|
457
|
+
let seen;
|
|
458
|
+
let spins = 0;
|
|
459
|
+
do {
|
|
460
|
+
seen = atom.get();
|
|
461
|
+
try {
|
|
462
|
+
listener();
|
|
463
|
+
} catch (error) {
|
|
464
|
+
reportListenerError(error);
|
|
465
|
+
}
|
|
466
|
+
spins++;
|
|
467
|
+
} while (atom.get() !== seen && spins < MAX_LISTENER_REENTRY);
|
|
468
|
+
});
|
|
469
|
+
return unsubscribe;
|
|
470
|
+
}
|
|
471
|
+
new TextEncoder();
|
|
472
|
+
new TextDecoder();
|
|
473
|
+
//#endregion
|
|
474
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/response-stream.js
|
|
40
475
|
var UnsupportedResponseStreamError = class extends Error {
|
|
41
476
|
missingFeature;
|
|
42
477
|
constructor(missingFeature) {
|
|
@@ -58,14 +493,14 @@ function createResponseStreamTextDecoder() {
|
|
|
58
493
|
return new globalThis.TextDecoder();
|
|
59
494
|
}
|
|
60
495
|
//#endregion
|
|
61
|
-
//#region ../node_modules/.bun/@tanstack+ai-client@0.
|
|
496
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/sse-utils.js
|
|
62
497
|
function parseSseDataLine(line) {
|
|
63
498
|
if (!line.startsWith("data:")) return line;
|
|
64
499
|
const data = line.slice(5);
|
|
65
500
|
return data.startsWith(" ") ? data.slice(1) : data;
|
|
66
501
|
}
|
|
67
502
|
//#endregion
|
|
68
|
-
//#region ../node_modules/.bun/@tanstack+ai-client@0.
|
|
503
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/message-date-normalizer.js
|
|
69
504
|
function validDate(value) {
|
|
70
505
|
if (value instanceof Date) return Number.isNaN(value.getTime()) ? void 0 : value;
|
|
71
506
|
if (typeof value !== "string") return void 0;
|
|
@@ -97,7 +532,7 @@ function normalizeMessagesDates(messages) {
|
|
|
97
532
|
return messages.map(normalizeMessageDates);
|
|
98
533
|
}
|
|
99
534
|
//#endregion
|
|
100
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
535
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/ag-ui-usage.js
|
|
101
536
|
function definedDetails(value) {
|
|
102
537
|
return Object.keys(value).length > 0 ? value : void 0;
|
|
103
538
|
}
|
|
@@ -142,7 +577,7 @@ function fromSpecTokenUsage(usage, leftover) {
|
|
|
142
577
|
};
|
|
143
578
|
}
|
|
144
579
|
//#endregion
|
|
145
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
580
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/merge-metadata.js
|
|
146
581
|
function isPlainRecord$1(value) {
|
|
147
582
|
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
148
583
|
}
|
|
@@ -221,7 +656,172 @@ let EventType = /* @__PURE__ */ function(EventType) {
|
|
|
221
656
|
return EventType;
|
|
222
657
|
}({});
|
|
223
658
|
//#endregion
|
|
224
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
659
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/tool-call-arguments.js
|
|
660
|
+
function sameJsonValue(left, right) {
|
|
661
|
+
if (Object.is(left, right)) return true;
|
|
662
|
+
if (Array.isArray(left) && Array.isArray(right)) return left.length === right.length && left.every((value, index) => sameJsonValue(value, right[index]));
|
|
663
|
+
if (left === null || right === null || typeof left !== "object" || typeof right !== "object" || Array.isArray(left) || Array.isArray(right)) return false;
|
|
664
|
+
const leftKeys = Object.keys(left);
|
|
665
|
+
const rightKeys = Object.keys(right);
|
|
666
|
+
return leftKeys.length === rightKeys.length && leftKeys.every((key) => Object.prototype.hasOwnProperty.call(right, key) && sameJsonValue(Reflect.get(left, key), Reflect.get(right, key)));
|
|
667
|
+
}
|
|
668
|
+
function scanJson(raw, parsed) {
|
|
669
|
+
let cursor = 0;
|
|
670
|
+
const whitespace = () => {
|
|
671
|
+
while (raw[cursor] === " " || raw[cursor] === " " || raw[cursor] === "\r" || raw[cursor] === "\n") cursor++;
|
|
672
|
+
};
|
|
673
|
+
const stringToken = () => {
|
|
674
|
+
const start = cursor++;
|
|
675
|
+
while (cursor < raw.length) if (raw[cursor] === "\\") cursor += 2;
|
|
676
|
+
else if (raw[cursor++] === "\"") break;
|
|
677
|
+
return raw.slice(start, cursor);
|
|
678
|
+
};
|
|
679
|
+
const value = (parsedValue) => {
|
|
680
|
+
whitespace();
|
|
681
|
+
const start = cursor;
|
|
682
|
+
if (raw[cursor] === "{") {
|
|
683
|
+
cursor++;
|
|
684
|
+
whitespace();
|
|
685
|
+
const properties = /* @__PURE__ */ new Map();
|
|
686
|
+
while (raw[cursor] !== "}") {
|
|
687
|
+
const keyToken = stringToken();
|
|
688
|
+
const key = JSON.parse(keyToken);
|
|
689
|
+
whitespace();
|
|
690
|
+
cursor++;
|
|
691
|
+
const child = parsedValue !== null && typeof parsedValue === "object" && typeof key === "string" ? Reflect.get(parsedValue, key) : void 0;
|
|
692
|
+
const childNode = value(child);
|
|
693
|
+
if (typeof key === "string") properties.set(key, {
|
|
694
|
+
...childNode,
|
|
695
|
+
keyToken
|
|
696
|
+
});
|
|
697
|
+
whitespace();
|
|
698
|
+
if (raw[cursor] !== ",") break;
|
|
699
|
+
cursor++;
|
|
700
|
+
whitespace();
|
|
701
|
+
}
|
|
702
|
+
cursor++;
|
|
703
|
+
return {
|
|
704
|
+
start,
|
|
705
|
+
end: cursor,
|
|
706
|
+
value: parsedValue,
|
|
707
|
+
properties
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
if (raw[cursor] === "[") {
|
|
711
|
+
cursor++;
|
|
712
|
+
whitespace();
|
|
713
|
+
const items = [];
|
|
714
|
+
while (raw[cursor] !== "]") {
|
|
715
|
+
items.push(value(Array.isArray(parsedValue) ? parsedValue[items.length] : void 0));
|
|
716
|
+
whitespace();
|
|
717
|
+
if (raw[cursor] !== ",") break;
|
|
718
|
+
cursor++;
|
|
719
|
+
}
|
|
720
|
+
cursor++;
|
|
721
|
+
return {
|
|
722
|
+
start,
|
|
723
|
+
end: cursor,
|
|
724
|
+
value: parsedValue,
|
|
725
|
+
items
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
if (raw[cursor] === "\"") stringToken();
|
|
729
|
+
else while (cursor < raw.length && !/[\s,}\]]/.test(raw[cursor] ?? "")) cursor++;
|
|
730
|
+
return {
|
|
731
|
+
start,
|
|
732
|
+
end: cursor,
|
|
733
|
+
value: parsedValue
|
|
734
|
+
};
|
|
735
|
+
};
|
|
736
|
+
return value(parsed);
|
|
737
|
+
}
|
|
738
|
+
function serializeValue(value, raw, node, seen) {
|
|
739
|
+
if (node && sameJsonValue(node.value, value)) return raw.slice(node.start, node.end);
|
|
740
|
+
if (typeof value === "number") {
|
|
741
|
+
if (Object.is(value, -0)) return "-0";
|
|
742
|
+
if (value === Infinity) return "1e999";
|
|
743
|
+
if (value === -Infinity) return "-1e999";
|
|
744
|
+
return JSON.stringify(value);
|
|
745
|
+
}
|
|
746
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
747
|
+
if (seen.has(value)) throw new TypeError("Cannot serialize circular tool input");
|
|
748
|
+
seen.add(value);
|
|
749
|
+
try {
|
|
750
|
+
if (Array.isArray(value)) return "[" + Array.from(value, (item, index) => serializeValue(item, raw, node?.items?.[index], seen) ?? "null").join(",") + "]";
|
|
751
|
+
const properties = [];
|
|
752
|
+
for (const key of Object.keys(value)) {
|
|
753
|
+
const serialized = serializeValue(Reflect.get(value, key), raw, node?.properties?.get(key), seen);
|
|
754
|
+
if (serialized !== void 0) properties.push((node?.properties?.get(key)?.keyToken ?? JSON.stringify(key)) + ":" + serialized);
|
|
755
|
+
}
|
|
756
|
+
return "{" + properties.join(",") + "}";
|
|
757
|
+
} finally {
|
|
758
|
+
seen.delete(value);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
762
|
+
* Keep `raw` when it is the same JSON value as `input`. When they differ,
|
|
763
|
+
* write `input` again and keep the raw tokens of the values that did not
|
|
764
|
+
* change. Empty or missing raw arguments use the input.
|
|
765
|
+
*/
|
|
766
|
+
function reconcileToolCallArguments(raw, input) {
|
|
767
|
+
if (input === void 0) return raw ?? "";
|
|
768
|
+
if (raw === void 0) return serializeValue(input, "", void 0, /* @__PURE__ */ new Set()) ?? "";
|
|
769
|
+
let parsed;
|
|
770
|
+
try {
|
|
771
|
+
parsed = JSON.parse(raw);
|
|
772
|
+
} catch {
|
|
773
|
+
if (raw.trim() === "") return serializeValue(input, "", void 0, /* @__PURE__ */ new Set()) ?? raw;
|
|
774
|
+
return raw;
|
|
775
|
+
}
|
|
776
|
+
if (sameJsonValue(parsed, input)) return raw;
|
|
777
|
+
return serializeValue(input, raw, scanJson(raw, parsed), /* @__PURE__ */ new Set()) ?? raw;
|
|
778
|
+
}
|
|
779
|
+
/**
|
|
780
|
+
* The input of a tool call from its raw arguments: `{}` for an empty string,
|
|
781
|
+
* `undefined` when the arguments are not complete JSON (for example cut off)
|
|
782
|
+
* or are `null`.
|
|
783
|
+
*/
|
|
784
|
+
function parseToolArguments(args) {
|
|
785
|
+
if (args.trim() === "") return {};
|
|
786
|
+
try {
|
|
787
|
+
return JSON.parse(args) ?? void 0;
|
|
788
|
+
} catch {
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* The final arguments and input of a tool call at TOOL_CALL_END. `streamed`
|
|
794
|
+
* is the text of its TOOL_CALL_ARGS deltas. The END's raw `args` (the
|
|
795
|
+
* provider's own string) win over it, and stay as they are when they are the
|
|
796
|
+
* same JSON value as the END's `input`. Malformed arguments also stay, so the
|
|
797
|
+
* tool reports the error and the model can repair them. `input` is always
|
|
798
|
+
* the parse of `args`.
|
|
799
|
+
*/
|
|
800
|
+
function finishToolCallArguments(streamed, end) {
|
|
801
|
+
const metadata = tanstackMetadata(end);
|
|
802
|
+
const endArgs = end.args ?? metadata?.args;
|
|
803
|
+
const rawArgs = typeof endArgs === "string" ? endArgs : void 0;
|
|
804
|
+
const endInput = end.input ?? metadata?.input;
|
|
805
|
+
const input = endInput !== null && typeof endInput === "object" ? endInput : void 0;
|
|
806
|
+
let raw = rawArgs ?? streamed;
|
|
807
|
+
if (rawArgs === void 0 && input !== void 0) try {
|
|
808
|
+
JSON.parse(raw);
|
|
809
|
+
} catch {
|
|
810
|
+
raw = void 0;
|
|
811
|
+
}
|
|
812
|
+
let args;
|
|
813
|
+
try {
|
|
814
|
+
args = reconcileToolCallArguments(raw, input);
|
|
815
|
+
} catch {
|
|
816
|
+
args = raw ?? streamed;
|
|
817
|
+
}
|
|
818
|
+
return {
|
|
819
|
+
args,
|
|
820
|
+
input: parseToolArguments(args)
|
|
821
|
+
};
|
|
822
|
+
}
|
|
823
|
+
//#endregion
|
|
824
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/reasoning-encrypted-value.js
|
|
225
825
|
/**
|
|
226
826
|
* Id prefix for the reasoning message of a redacted thinking block (Anthropic
|
|
227
827
|
* `redacted_thinking`). AG-UI's `encryptedValue` does not say what kind of
|
|
@@ -233,7 +833,7 @@ function isRedactedThinkingId(id) {
|
|
|
233
833
|
return typeof id === "string" && id.startsWith("redacted_thinking-");
|
|
234
834
|
}
|
|
235
835
|
//#endregion
|
|
236
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
836
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/interrupt-serialization.js
|
|
237
837
|
var SHA256_K = new Uint32Array([
|
|
238
838
|
1116352408,
|
|
239
839
|
1899447441,
|
|
@@ -408,7 +1008,7 @@ function cloneAndDeepFreezeJson(value) {
|
|
|
408
1008
|
return clone;
|
|
409
1009
|
}
|
|
410
1010
|
//#endregion
|
|
411
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
1011
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/interrupts.js
|
|
412
1012
|
function canonicalizeInterruptResolutions(resolutions) {
|
|
413
1013
|
const frozen = cloneAndDeepFreezeJson([...resolutions].sort((left, right) => left.interruptId.localeCompare(right.interruptId)));
|
|
414
1014
|
const canonicalResolutions = canonicalInterruptJson(frozen);
|
|
@@ -419,7 +1019,7 @@ function canonicalizeInterruptResolutions(resolutions) {
|
|
|
419
1019
|
});
|
|
420
1020
|
}
|
|
421
1021
|
//#endregion
|
|
422
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
1022
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/activities/chat/tools/schema-converter.js
|
|
423
1023
|
/**
|
|
424
1024
|
* Build a JSONSchema object from any plain key/value source. The `JSONSchema`
|
|
425
1025
|
* interface's `[key: string]: any` index signature makes every property
|
|
@@ -687,7 +1287,7 @@ async function validateWithStandardSchema(schema, data) {
|
|
|
687
1287
|
};
|
|
688
1288
|
}
|
|
689
1289
|
//#endregion
|
|
690
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
1290
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/activities/chat/tools/approval-schema.js
|
|
691
1291
|
var jsonSchemaKeywords = /* @__PURE__ */ new Set([
|
|
692
1292
|
"$schema",
|
|
693
1293
|
"$id",
|
|
@@ -801,7 +1401,7 @@ function hashSchemaInput(schema) {
|
|
|
801
1401
|
return digestInterruptJson(canonicalInterruptJson(schemaToWire(schema).jsonSchema ?? { standardValidator: "unserialized" }));
|
|
802
1402
|
}
|
|
803
1403
|
//#endregion
|
|
804
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
1404
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/interrupt-resume.js
|
|
805
1405
|
/**
|
|
806
1406
|
* The `Interrupt.metadata` key under which this package's resume binding
|
|
807
1407
|
* travels.
|
|
@@ -922,7 +1522,7 @@ function readInterruptBinding(descriptor) {
|
|
|
922
1522
|
};
|
|
923
1523
|
}
|
|
924
1524
|
//#endregion
|
|
925
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
1525
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/interrupt-definition.js
|
|
926
1526
|
var INTERRUPT_PAYLOAD_METADATA_KEY = "tanstack:interruptPayload";
|
|
927
1527
|
function schemaJson(schema, name) {
|
|
928
1528
|
if (!isStandardJSONSchema(schema)) throw new TypeError(`${name} must be a Standard Schema with a JSON Schema converter.`);
|
|
@@ -947,7 +1547,7 @@ function hashInterruptDefinitionSchema(schema) {
|
|
|
947
1547
|
return digestInterruptJson(schemaJson(schema, "Interrupt schema").canonicalJson);
|
|
948
1548
|
}
|
|
949
1549
|
//#endregion
|
|
950
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
1550
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/generic-interrupt-continuation.js
|
|
951
1551
|
/**
|
|
952
1552
|
* `ResumeEntry.metadata` key for a first-party generic request.
|
|
953
1553
|
*
|
|
@@ -986,100 +1586,19 @@ function genericInterruptContinuationFromDescriptor(interrupt) {
|
|
|
986
1586
|
};
|
|
987
1587
|
}
|
|
988
1588
|
//#endregion
|
|
989
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
* Returns the typed metadata when the call is provider-executed, else `null`.
|
|
993
|
-
*
|
|
994
|
-
* @see ProviderExecutedToolMetadata
|
|
995
|
-
*/
|
|
996
|
-
function getProviderExecutedMetadata(toolCall) {
|
|
997
|
-
const metadata = toolCall?.metadata;
|
|
998
|
-
if (typeof metadata === "object" && metadata !== null && metadata.providerExecuted === true) return metadata;
|
|
999
|
-
return null;
|
|
1000
|
-
}
|
|
1001
|
-
/**
|
|
1002
|
-
* True when a tool call was executed by the provider (e.g. Anthropic
|
|
1003
|
-
* `web_search` / `web_fetch` server tools) rather than the agent loop. Such
|
|
1004
|
-
* calls must not be routed to client-side execution and are already "complete".
|
|
1005
|
-
*/
|
|
1006
|
-
function isProviderExecutedToolCall(toolCall) {
|
|
1007
|
-
return getProviderExecutedMetadata(toolCall) !== null;
|
|
1008
|
-
}
|
|
1009
|
-
/**
|
|
1010
|
-
* True when `id` is a `${parentId}-segment-${n}` message. The wire and the
|
|
1011
|
-
* run loop split one provider turn into segments at thinking that follows a
|
|
1012
|
-
* provider-executed tool call, to keep signed thinking order. Readers fold a
|
|
1013
|
-
* segment back into its parent so the UI still shows one message.
|
|
1014
|
-
*/
|
|
1015
|
-
function isAssistantSegmentOf(id, parentId) {
|
|
1016
|
-
return id?.startsWith(`${parentId}-segment-`) === true;
|
|
1017
|
-
}
|
|
1018
|
-
//#endregion
|
|
1019
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/tool-result.js
|
|
1020
|
-
var CONTENT_PART_TYPES = /* @__PURE__ */ new Set([
|
|
1021
|
-
"text",
|
|
1022
|
-
"image",
|
|
1023
|
-
"audio",
|
|
1024
|
-
"video",
|
|
1025
|
-
"document"
|
|
1026
|
-
]);
|
|
1027
|
-
function isToolResultOutcome(value) {
|
|
1028
|
-
return value === "cancelled" || value === "denied";
|
|
1029
|
-
}
|
|
1030
|
-
/**
|
|
1031
|
-
* Structural check for a single `ContentPart`. A text part must carry a string
|
|
1032
|
-
* `content`. Every other part carries a source with a string `value`; a file
|
|
1033
|
-
* source's `value` is a non-empty opaque handle, and its optional `provider`
|
|
1034
|
-
* is a string.
|
|
1035
|
-
*/
|
|
1036
|
-
function isContentPart$1(value) {
|
|
1037
|
-
if (typeof value !== "object" || value === null) return false;
|
|
1038
|
-
const part = value;
|
|
1039
|
-
if (typeof part.type !== "string" || !CONTENT_PART_TYPES.has(part.type)) return false;
|
|
1040
|
-
if (part.type === "text") return typeof part.content === "string";
|
|
1041
|
-
const source = part.source;
|
|
1042
|
-
if (typeof source !== "object" || source === null) return false;
|
|
1043
|
-
const src = source;
|
|
1044
|
-
if (typeof src.value !== "string") return false;
|
|
1045
|
-
if (src.type === "file") return src.value.length > 0 && (src.provider === void 0 || typeof src.provider === "string");
|
|
1046
|
-
if (src.type === "data") return typeof src.mimeType === "string";
|
|
1047
|
-
return src.type === "url";
|
|
1048
|
-
}
|
|
1049
|
-
/**
|
|
1050
|
-
* True iff `value` is a NON-EMPTY array whose every element is a valid
|
|
1051
|
-
* `ContentPart`. Empty arrays and mixed arrays return false so they continue
|
|
1052
|
-
* to be treated as ordinary (stringified) data — this keeps the auto-detection
|
|
1053
|
-
* footgun narrow.
|
|
1054
|
-
*/
|
|
1055
|
-
function isContentPartArray(value) {
|
|
1056
|
-
return Array.isArray(value) && value.length > 0 && value.every(isContentPart$1);
|
|
1057
|
-
}
|
|
1058
|
-
/**
|
|
1059
|
-
* Error text for a failed tool result: `output.error` when it is a string,
|
|
1060
|
-
* else the output itself when it is a string, else a generic message.
|
|
1061
|
-
* `StreamProcessor` and `chat()` history share it, so a reload shows the
|
|
1062
|
-
* same text as the live stream.
|
|
1063
|
-
*/
|
|
1064
|
-
function toolResultErrorText(output) {
|
|
1065
|
-
if (output && typeof output === "object" && "error" in output && typeof output.error === "string") return output.error;
|
|
1066
|
-
return typeof output === "string" ? output : "Tool execution failed";
|
|
1589
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/subagent-wire.js
|
|
1590
|
+
function isRecord$2(value) {
|
|
1591
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1067
1592
|
}
|
|
1593
|
+
/** Key of a child's checked input in `SUBAGENT_STARTED` metadata (`metadata.tanstack`). */
|
|
1594
|
+
var SUBAGENT_INPUT_KEY = "subagentInput";
|
|
1068
1595
|
/**
|
|
1069
|
-
*
|
|
1070
|
-
*
|
|
1071
|
-
* - ContentPart array → unchanged (multimodal, passed through to the adapter)
|
|
1072
|
-
* - anything else → `JSON.stringify`
|
|
1596
|
+
* The checked input of a child that an agent with `inputSchema` got, read
|
|
1597
|
+
* from the `metadata` of its card or of its `SUBAGENT_STARTED` event.
|
|
1073
1598
|
*/
|
|
1074
|
-
function
|
|
1075
|
-
if (
|
|
1076
|
-
|
|
1077
|
-
return JSON.stringify(result);
|
|
1078
|
-
}
|
|
1079
|
-
//#endregion
|
|
1080
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/subagent-wire.js
|
|
1081
|
-
function isRecord$2(value) {
|
|
1082
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1599
|
+
function subagentInputOf(metadata) {
|
|
1600
|
+
if (!isRecord$2(metadata) || !isRecord$2(metadata.tanstack)) return void 0;
|
|
1601
|
+
return metadata.tanstack[SUBAGENT_INPUT_KEY];
|
|
1083
1602
|
}
|
|
1084
1603
|
function wireSubagentRunId(message) {
|
|
1085
1604
|
if (!isRecord$2(message) || "parts" in message) return void 0;
|
|
@@ -1181,7 +1700,186 @@ function splitSubagentWire(messages) {
|
|
|
1181
1700
|
};
|
|
1182
1701
|
}
|
|
1183
1702
|
//#endregion
|
|
1184
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
1703
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/provider-executed.js
|
|
1704
|
+
/**
|
|
1705
|
+
* Narrow a tool call's opaque `metadata` to the provider-executed convention.
|
|
1706
|
+
* Returns the typed metadata when the call is provider-executed, else `null`.
|
|
1707
|
+
*
|
|
1708
|
+
* @see ProviderExecutedToolMetadata
|
|
1709
|
+
*/
|
|
1710
|
+
function getProviderExecutedMetadata(toolCall) {
|
|
1711
|
+
const metadata = toolCall?.metadata;
|
|
1712
|
+
if (typeof metadata === "object" && metadata !== null && metadata.providerExecuted === true) return metadata;
|
|
1713
|
+
return null;
|
|
1714
|
+
}
|
|
1715
|
+
/**
|
|
1716
|
+
* True when a tool call was executed by the provider (e.g. Anthropic
|
|
1717
|
+
* `web_search` / `web_fetch` server tools) rather than the agent loop. Such
|
|
1718
|
+
* calls must not be routed to client-side execution and are already "complete".
|
|
1719
|
+
*/
|
|
1720
|
+
function isProviderExecutedToolCall(toolCall) {
|
|
1721
|
+
return getProviderExecutedMetadata(toolCall) !== null;
|
|
1722
|
+
}
|
|
1723
|
+
/**
|
|
1724
|
+
* True when `id` is a `${parentId}-segment-${n}` message. The wire and the
|
|
1725
|
+
* run loop split one provider turn into segments at thinking that follows a
|
|
1726
|
+
* provider-executed tool call, to keep signed thinking order. Readers fold a
|
|
1727
|
+
* segment back into its parent so the UI still shows one message.
|
|
1728
|
+
*/
|
|
1729
|
+
function isAssistantSegmentOf(id, parentId) {
|
|
1730
|
+
return id?.startsWith(`${parentId}-segment-`) === true;
|
|
1731
|
+
}
|
|
1732
|
+
//#endregion
|
|
1733
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/tool-result.js
|
|
1734
|
+
var CONTENT_PART_TYPES = /* @__PURE__ */ new Set([
|
|
1735
|
+
"text",
|
|
1736
|
+
"image",
|
|
1737
|
+
"audio",
|
|
1738
|
+
"video",
|
|
1739
|
+
"document"
|
|
1740
|
+
]);
|
|
1741
|
+
function isToolResultOutcome(value) {
|
|
1742
|
+
return value === "cancelled" || value === "denied";
|
|
1743
|
+
}
|
|
1744
|
+
/**
|
|
1745
|
+
* Structural check for a single `ContentPart`. A text part must carry a string
|
|
1746
|
+
* `content`. Every other part carries a source with a string `value`; a file
|
|
1747
|
+
* source's `value` is a non-empty opaque handle, and its optional `provider`
|
|
1748
|
+
* is a string.
|
|
1749
|
+
*/
|
|
1750
|
+
function isContentPart$1(value) {
|
|
1751
|
+
if (typeof value !== "object" || value === null) return false;
|
|
1752
|
+
const part = value;
|
|
1753
|
+
if (typeof part.type !== "string" || !CONTENT_PART_TYPES.has(part.type)) return false;
|
|
1754
|
+
if (part.type === "text") return typeof part.content === "string";
|
|
1755
|
+
const source = part.source;
|
|
1756
|
+
if (typeof source !== "object" || source === null) return false;
|
|
1757
|
+
const src = source;
|
|
1758
|
+
if (typeof src.value !== "string") return false;
|
|
1759
|
+
if (src.type === "file") return src.value.length > 0 && (src.provider === void 0 || typeof src.provider === "string");
|
|
1760
|
+
if (src.type === "data") return typeof src.mimeType === "string";
|
|
1761
|
+
return src.type === "url";
|
|
1762
|
+
}
|
|
1763
|
+
/**
|
|
1764
|
+
* True iff `value` is a NON-EMPTY array whose every element is a valid
|
|
1765
|
+
* `ContentPart`. Empty arrays and mixed arrays return false so they continue
|
|
1766
|
+
* to be treated as ordinary (stringified) data — this keeps the auto-detection
|
|
1767
|
+
* footgun narrow.
|
|
1768
|
+
*/
|
|
1769
|
+
function isContentPartArray(value) {
|
|
1770
|
+
return Array.isArray(value) && value.length > 0 && value.every(isContentPart$1);
|
|
1771
|
+
}
|
|
1772
|
+
/**
|
|
1773
|
+
* Error text for a failed tool result: `output.error` when it is a string,
|
|
1774
|
+
* else the output itself when it is a string, else a generic message.
|
|
1775
|
+
* `StreamProcessor` and `chat()` history share it, so a reload shows the
|
|
1776
|
+
* same text as the live stream.
|
|
1777
|
+
*/
|
|
1778
|
+
function toolResultErrorText(output) {
|
|
1779
|
+
if (output && typeof output === "object" && "error" in output && typeof output.error === "string") return output.error;
|
|
1780
|
+
return typeof output === "string" ? output : "Tool execution failed";
|
|
1781
|
+
}
|
|
1782
|
+
/**
|
|
1783
|
+
* Normalize a tool's return value for transport:
|
|
1784
|
+
* - string → unchanged
|
|
1785
|
+
* - ContentPart array → unchanged (multimodal, passed through to the adapter)
|
|
1786
|
+
* - anything else → `JSON.stringify`
|
|
1787
|
+
*/
|
|
1788
|
+
function normalizeToolResult(result) {
|
|
1789
|
+
if (typeof result === "string") return result;
|
|
1790
|
+
if (isContentPartArray(result)) return result;
|
|
1791
|
+
return JSON.stringify(result);
|
|
1792
|
+
}
|
|
1793
|
+
//#endregion
|
|
1794
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/block-order.js
|
|
1795
|
+
/**
|
|
1796
|
+
* The order map for these entries in produced order, or undefined when they
|
|
1797
|
+
* are in the default order (all thinking, then text, then tool calls).
|
|
1798
|
+
* Adjacent text entries merge into one, and empty text is left out. The n-th
|
|
1799
|
+
* thinking entry gets index n.
|
|
1800
|
+
*/
|
|
1801
|
+
function buildBlockOrder(entries) {
|
|
1802
|
+
const blocks = [];
|
|
1803
|
+
let thinking = 0;
|
|
1804
|
+
let isDefault = true;
|
|
1805
|
+
for (const entry of entries) {
|
|
1806
|
+
const last = blocks.at(-1);
|
|
1807
|
+
if (entry.type === "thinking") {
|
|
1808
|
+
if (last !== void 0 && last.type !== "thinking") isDefault = false;
|
|
1809
|
+
blocks.push({
|
|
1810
|
+
type: "thinking",
|
|
1811
|
+
index: thinking++
|
|
1812
|
+
});
|
|
1813
|
+
} else if (entry.type === "text") {
|
|
1814
|
+
if (entry.text === "") continue;
|
|
1815
|
+
if (last?.type === "text") {
|
|
1816
|
+
last.length += entry.text.length;
|
|
1817
|
+
continue;
|
|
1818
|
+
}
|
|
1819
|
+
if (last?.type === "tool-call") isDefault = false;
|
|
1820
|
+
blocks.push({
|
|
1821
|
+
type: "text",
|
|
1822
|
+
length: entry.text.length
|
|
1823
|
+
});
|
|
1824
|
+
} else blocks.push({
|
|
1825
|
+
type: "tool-call",
|
|
1826
|
+
id: entry.id
|
|
1827
|
+
});
|
|
1828
|
+
}
|
|
1829
|
+
return isDefault ? void 0 : blocks;
|
|
1830
|
+
}
|
|
1831
|
+
/**
|
|
1832
|
+
* The blocks of an assistant message in map order, or undefined when the
|
|
1833
|
+
* message has no map or the map does not match the message. A map matches
|
|
1834
|
+
* when it uses each `thinking` entry and each `toolCalls` entry exactly once,
|
|
1835
|
+
* and its text lengths add up to the length of the text content (`null`
|
|
1836
|
+
* content counts as no text). Readers use the default order when this
|
|
1837
|
+
* returns undefined.
|
|
1838
|
+
*/
|
|
1839
|
+
function orderedAssistantBlocks(message) {
|
|
1840
|
+
const order = message.blockOrder;
|
|
1841
|
+
if (!Array.isArray(order) || order.length === 0) return void 0;
|
|
1842
|
+
const content = message.content ?? "";
|
|
1843
|
+
if (typeof content !== "string") return void 0;
|
|
1844
|
+
const thinking = message.thinking ?? [];
|
|
1845
|
+
const toolCalls = message.toolCalls ?? [];
|
|
1846
|
+
const usedThinking = /* @__PURE__ */ new Set();
|
|
1847
|
+
const usedCalls = /* @__PURE__ */ new Set();
|
|
1848
|
+
const blocks = [];
|
|
1849
|
+
let offset = 0;
|
|
1850
|
+
for (const block of order) {
|
|
1851
|
+
if (typeof block !== "object" || block === null) return void 0;
|
|
1852
|
+
if (block.type === "thinking") {
|
|
1853
|
+
const entry = Number.isInteger(block.index) ? thinking[block.index] : void 0;
|
|
1854
|
+
if (entry === void 0 || usedThinking.has(block.index)) return;
|
|
1855
|
+
usedThinking.add(block.index);
|
|
1856
|
+
blocks.push({
|
|
1857
|
+
type: "thinking",
|
|
1858
|
+
thinking: entry
|
|
1859
|
+
});
|
|
1860
|
+
} else if (block.type === "text") {
|
|
1861
|
+
const end = offset + block.length;
|
|
1862
|
+
if (!Number.isInteger(block.length) || block.length <= 0 || end > content.length) return;
|
|
1863
|
+
blocks.push({
|
|
1864
|
+
type: "text",
|
|
1865
|
+
text: content.slice(offset, end)
|
|
1866
|
+
});
|
|
1867
|
+
offset = end;
|
|
1868
|
+
} else if (block.type === "tool-call") {
|
|
1869
|
+
const toolCall = toolCalls.find((candidate) => candidate.id === block.id);
|
|
1870
|
+
if (toolCall === void 0 || usedCalls.has(block.id)) return void 0;
|
|
1871
|
+
usedCalls.add(block.id);
|
|
1872
|
+
blocks.push({
|
|
1873
|
+
type: "tool-call",
|
|
1874
|
+
toolCall
|
|
1875
|
+
});
|
|
1876
|
+
} else return;
|
|
1877
|
+
}
|
|
1878
|
+
if (offset !== content.length || usedThinking.size !== thinking.length || usedCalls.size !== toolCalls.length) return;
|
|
1879
|
+
return blocks;
|
|
1880
|
+
}
|
|
1881
|
+
//#endregion
|
|
1882
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/activities/chat/messages.js
|
|
1185
1883
|
function isRecord$1(value) {
|
|
1186
1884
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1187
1885
|
}
|
|
@@ -1341,12 +2039,19 @@ function appendUiResources(ui, resources) {
|
|
|
1341
2039
|
function assistantMetadata(uiMessage) {
|
|
1342
2040
|
const fromParts = uiMessage.parts.filter(isUiResourcePart);
|
|
1343
2041
|
const current = uiMessage.metadata ?? {};
|
|
1344
|
-
const
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
2042
|
+
const tanstack = { ...tanstackMetadata(uiMessage) };
|
|
2043
|
+
if (tanstack.run) {
|
|
2044
|
+
tanstack.run = { ...tanstack.run };
|
|
2045
|
+
delete tanstack.run.startedAt;
|
|
2046
|
+
delete tanstack.run.finishedAt;
|
|
2047
|
+
}
|
|
2048
|
+
delete tanstack.createdAt;
|
|
2049
|
+
delete tanstack.continues;
|
|
2050
|
+
delete tanstack.structuredOutput;
|
|
2051
|
+
delete tanstack.toolCallMetadata;
|
|
2052
|
+
delete tanstack.toolResult;
|
|
2053
|
+
delete tanstack.toolResultOutcome;
|
|
2054
|
+
delete tanstack.uiResources;
|
|
1350
2055
|
if (fromParts.length > 0) tanstack.uiResources = fromParts;
|
|
1351
2056
|
const result = { ...current };
|
|
1352
2057
|
if (Object.keys(tanstack).length > 0) result.tanstack = tanstack;
|
|
@@ -1397,7 +2102,8 @@ function buildUserOrToolMessage(uiMessage) {
|
|
|
1397
2102
|
function createSegment() {
|
|
1398
2103
|
return {
|
|
1399
2104
|
contentParts: [],
|
|
1400
|
-
toolCalls: []
|
|
2105
|
+
toolCalls: [],
|
|
2106
|
+
order: []
|
|
1401
2107
|
};
|
|
1402
2108
|
}
|
|
1403
2109
|
function isToolCallIncluded(part) {
|
|
@@ -1432,6 +2138,7 @@ function buildAssistantMessages(uiMessage) {
|
|
|
1432
2138
|
const hasContent = content !== null;
|
|
1433
2139
|
const hasToolCalls = current.toolCalls.length > 0;
|
|
1434
2140
|
const hasThinking = pendingThinking.length > 0;
|
|
2141
|
+
const blockOrder = Array.isArray(content) ? void 0 : buildBlockOrder(current.order);
|
|
1435
2142
|
if (force || hasContent || hasToolCalls || hasThinking) {
|
|
1436
2143
|
messageList.push({
|
|
1437
2144
|
...assistantFields,
|
|
@@ -1439,7 +2146,8 @@ function buildAssistantMessages(uiMessage) {
|
|
|
1439
2146
|
content,
|
|
1440
2147
|
...hasToolCalls && { toolCalls: current.toolCalls },
|
|
1441
2148
|
...hasThinking && { thinking: pendingThinking },
|
|
1442
|
-
...current.structuredOutput && { structuredOutput: current.structuredOutput }
|
|
2149
|
+
...current.structuredOutput && { structuredOutput: current.structuredOutput },
|
|
2150
|
+
...blockOrder && { blockOrder }
|
|
1443
2151
|
});
|
|
1444
2152
|
pendingThinking = [];
|
|
1445
2153
|
}
|
|
@@ -1447,6 +2155,12 @@ function buildAssistantMessages(uiMessage) {
|
|
|
1447
2155
|
}
|
|
1448
2156
|
for (const part of uiMessage.parts) switch (part.type) {
|
|
1449
2157
|
case "text":
|
|
2158
|
+
current.contentParts.push(part);
|
|
2159
|
+
current.order.push({
|
|
2160
|
+
type: "text",
|
|
2161
|
+
text: part.content
|
|
2162
|
+
});
|
|
2163
|
+
break;
|
|
1450
2164
|
case "image":
|
|
1451
2165
|
case "audio":
|
|
1452
2166
|
case "video":
|
|
@@ -1454,15 +2168,21 @@ function buildAssistantMessages(uiMessage) {
|
|
|
1454
2168
|
current.contentParts.push(part);
|
|
1455
2169
|
break;
|
|
1456
2170
|
case "tool-call":
|
|
1457
|
-
if (isToolCallIncluded(part))
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
2171
|
+
if (isToolCallIncluded(part)) {
|
|
2172
|
+
current.toolCalls.push({
|
|
2173
|
+
id: part.id,
|
|
2174
|
+
type: "function",
|
|
2175
|
+
function: {
|
|
2176
|
+
name: part.name,
|
|
2177
|
+
arguments: part.arguments
|
|
2178
|
+
},
|
|
2179
|
+
...part.metadata !== void 0 && { metadata: part.metadata }
|
|
2180
|
+
});
|
|
2181
|
+
current.order.push({
|
|
2182
|
+
type: "tool-call",
|
|
2183
|
+
id: part.id
|
|
2184
|
+
});
|
|
2185
|
+
}
|
|
1466
2186
|
break;
|
|
1467
2187
|
case "tool-result":
|
|
1468
2188
|
flushSegment(messageList.length === 0);
|
|
@@ -1489,6 +2209,7 @@ function buildAssistantMessages(uiMessage) {
|
|
|
1489
2209
|
...part.signature && { signature: part.signature },
|
|
1490
2210
|
...part.redacted && { redacted: true }
|
|
1491
2211
|
});
|
|
2212
|
+
current.order.push({ type: "thinking" });
|
|
1492
2213
|
}
|
|
1493
2214
|
break;
|
|
1494
2215
|
case "structured-output":
|
|
@@ -1499,6 +2220,10 @@ function buildAssistantMessages(uiMessage) {
|
|
|
1499
2220
|
type: "text",
|
|
1500
2221
|
content: serialized
|
|
1501
2222
|
});
|
|
2223
|
+
current.order.push({
|
|
2224
|
+
type: "text",
|
|
2225
|
+
text: serialized
|
|
2226
|
+
});
|
|
1502
2227
|
current.structuredOutput = part;
|
|
1503
2228
|
}
|
|
1504
2229
|
}
|
|
@@ -1508,10 +2233,14 @@ function buildAssistantMessages(uiMessage) {
|
|
|
1508
2233
|
case "subagent": {
|
|
1509
2234
|
const block = part.subagent.parentToolCallId === void 0 ? subagentHistoryText(part) : "";
|
|
1510
2235
|
if (block !== "") {
|
|
1511
|
-
const
|
|
2236
|
+
const text = `${current.contentParts.length > 0 ? "\n\n" : ""}${block}`;
|
|
1512
2237
|
current.contentParts.push({
|
|
1513
2238
|
type: "text",
|
|
1514
|
-
content:
|
|
2239
|
+
content: text
|
|
2240
|
+
});
|
|
2241
|
+
current.order.push({
|
|
2242
|
+
type: "text",
|
|
2243
|
+
text
|
|
1515
2244
|
});
|
|
1516
2245
|
}
|
|
1517
2246
|
break;
|
|
@@ -1550,6 +2279,31 @@ function buildAssistantMessages(uiMessage) {
|
|
|
1550
2279
|
});
|
|
1551
2280
|
return messageList;
|
|
1552
2281
|
}
|
|
2282
|
+
function thinkingToPart(thinking) {
|
|
2283
|
+
return {
|
|
2284
|
+
type: "thinking",
|
|
2285
|
+
content: thinking.content,
|
|
2286
|
+
...thinking.signature && { signature: thinking.signature },
|
|
2287
|
+
...thinking.redacted && { redacted: true }
|
|
2288
|
+
};
|
|
2289
|
+
}
|
|
2290
|
+
function toolCallToPart(toolCall) {
|
|
2291
|
+
let input;
|
|
2292
|
+
try {
|
|
2293
|
+
input = JSON.parse(toolCall.function.arguments);
|
|
2294
|
+
} catch {
|
|
2295
|
+
input = void 0;
|
|
2296
|
+
}
|
|
2297
|
+
return {
|
|
2298
|
+
type: "tool-call",
|
|
2299
|
+
id: toolCall.id,
|
|
2300
|
+
name: toolCall.function.name,
|
|
2301
|
+
arguments: toolCall.function.arguments,
|
|
2302
|
+
state: "input-complete",
|
|
2303
|
+
...input !== void 0 && { input },
|
|
2304
|
+
...toolCall.metadata !== void 0 && { metadata: toolCall.metadata }
|
|
2305
|
+
};
|
|
2306
|
+
}
|
|
1553
2307
|
/**
|
|
1554
2308
|
* Convert a ModelMessage to UIMessage
|
|
1555
2309
|
*
|
|
@@ -1567,12 +2321,7 @@ function modelMessageToUIMessage(modelMessage, id) {
|
|
|
1567
2321
|
const createdAt = coerceCreatedAt(modelMessage.createdAt);
|
|
1568
2322
|
if (modelMessage.role === "assistant" && modelMessage.thinking?.length) for (const thinking of modelMessage.thinking) {
|
|
1569
2323
|
if (!thinking.content && !thinking.signature) continue;
|
|
1570
|
-
parts.push(
|
|
1571
|
-
type: "thinking",
|
|
1572
|
-
content: thinking.content,
|
|
1573
|
-
...thinking.signature && { signature: thinking.signature },
|
|
1574
|
-
...thinking.redacted && { redacted: true }
|
|
1575
|
-
});
|
|
2324
|
+
parts.push(thinkingToPart(thinking));
|
|
1576
2325
|
}
|
|
1577
2326
|
const structuredOutput = modelMessage.structuredOutput ?? snapshotStructuredOutput(tanstackMetadata(modelMessage)?.structuredOutput);
|
|
1578
2327
|
if (modelMessage.role === "assistant" && structuredOutput) {
|
|
@@ -1609,23 +2358,16 @@ function modelMessageToUIMessage(modelMessage, id) {
|
|
|
1609
2358
|
content: textContent
|
|
1610
2359
|
});
|
|
1611
2360
|
}
|
|
1612
|
-
if (modelMessage.toolCalls && modelMessage.toolCalls.length > 0) for (const toolCall of modelMessage.toolCalls)
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
}
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
name: toolCall.function.name,
|
|
1623
|
-
arguments: toolCall.function.arguments,
|
|
1624
|
-
state: "input-complete",
|
|
1625
|
-
...input !== void 0 && { input },
|
|
1626
|
-
...toolCall.metadata !== void 0 && { metadata: toolCall.metadata }
|
|
1627
|
-
});
|
|
1628
|
-
}
|
|
2361
|
+
if (modelMessage.toolCalls && modelMessage.toolCalls.length > 0) for (const toolCall of modelMessage.toolCalls) parts.push(toolCallToPart(toolCall));
|
|
2362
|
+
const ordered = modelMessage.role === "assistant" && structuredOutput === void 0 ? orderedAssistantBlocks(modelMessage) : void 0;
|
|
2363
|
+
if (ordered) parts.splice(0, parts.length, ...ordered.flatMap((block) => {
|
|
2364
|
+
if (block.type === "text") return [{
|
|
2365
|
+
type: "text",
|
|
2366
|
+
content: block.text
|
|
2367
|
+
}];
|
|
2368
|
+
if (block.type === "tool-call") return [toolCallToPart(block.toolCall)];
|
|
2369
|
+
return block.thinking.content || block.thinking.signature ? [thinkingToPart(block.thinking)] : [];
|
|
2370
|
+
}));
|
|
1629
2371
|
const ui = {
|
|
1630
2372
|
id: id || generateMessageId(),
|
|
1631
2373
|
role: modelMessage.role === "tool" ? "assistant" : modelMessage.role,
|
|
@@ -1849,7 +2591,7 @@ function generateMessageId() {
|
|
|
1849
2591
|
return `msg-${Date.now()}-${Math.random().toString(36).substring(7)}`;
|
|
1850
2592
|
}
|
|
1851
2593
|
//#endregion
|
|
1852
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
2594
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/ag-ui-wire.js
|
|
1853
2595
|
function isRecord(value) {
|
|
1854
2596
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1855
2597
|
}
|
|
@@ -1882,7 +2624,10 @@ function rebuiltToolMetadata(metadata, createdAt, id, content, anchorOwnsUiResou
|
|
|
1882
2624
|
* server consumers. Set `includeSnapshotStructuredOutput` to retain complete
|
|
1883
2625
|
* structured-output metadata for UI snapshots. Set `includeActivity` to emit
|
|
1884
2626
|
* AG-UI `ActivityMessage` rows (MESSAGES_SNAPSHOT only — default omit so
|
|
1885
|
-
* RunAgentInput never carries activity).
|
|
2627
|
+
* RunAgentInput never carries activity). An assistant message whose
|
|
2628
|
+
* parts leave the default block order goes out as several rows in the real
|
|
2629
|
+
* order (see `TanStackMessageMetadata.continues`). A tool result also ends a
|
|
2630
|
+
* row, and its tool row follows that row.
|
|
1886
2631
|
*/
|
|
1887
2632
|
function uiMessagesToWire(messages, options) {
|
|
1888
2633
|
const wire = [];
|
|
@@ -1934,20 +2679,72 @@ function uiMessagesToWire(messages, options) {
|
|
|
1934
2679
|
wire.push(toAnchor(uiMessage, "user", { content: parts.length > 0 ? collectUserContent(parts) : msg.content ?? "" }, parts, includeSnapshotStructuredOutput));
|
|
1935
2680
|
continue;
|
|
1936
2681
|
}
|
|
1937
|
-
|
|
2682
|
+
const newSegment = (continues) => ({
|
|
1938
2683
|
thinking: [],
|
|
1939
|
-
parts: []
|
|
1940
|
-
|
|
2684
|
+
parts: [],
|
|
2685
|
+
continues,
|
|
2686
|
+
closed: false
|
|
2687
|
+
});
|
|
2688
|
+
let current = newSegment(false);
|
|
1941
2689
|
const segments = [current];
|
|
1942
|
-
for (const part of parts)
|
|
1943
|
-
if (current.
|
|
1944
|
-
current =
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
2690
|
+
for (const part of parts) {
|
|
2691
|
+
if (current.closed && (part.type === "thinking" || part.type === "text" || part.type === "tool-call")) {
|
|
2692
|
+
current = newSegment(false);
|
|
2693
|
+
segments.push(current);
|
|
2694
|
+
}
|
|
2695
|
+
const afterCall = current.parts.some((p) => p.type === "tool-call");
|
|
2696
|
+
if (part.type === "thinking") {
|
|
2697
|
+
if (current.parts.some((p) => p.type === "tool-call" && isProviderExecutedToolCall(p))) {
|
|
2698
|
+
current = newSegment(false);
|
|
2699
|
+
segments.push(current);
|
|
2700
|
+
} else if (afterCall || current.parts.some((p) => p.type === "text")) {
|
|
2701
|
+
current = newSegment(true);
|
|
2702
|
+
segments.push(current);
|
|
2703
|
+
}
|
|
2704
|
+
current.thinking.push(part);
|
|
2705
|
+
} else if (part.type === "text" && afterCall) {
|
|
2706
|
+
current = newSegment(true);
|
|
1948
2707
|
segments.push(current);
|
|
1949
|
-
|
|
1950
|
-
|
|
2708
|
+
current.parts.push(part);
|
|
2709
|
+
} else {
|
|
2710
|
+
current.parts.push(part);
|
|
2711
|
+
if (part.type === "tool-result") current.closed = true;
|
|
2712
|
+
}
|
|
2713
|
+
}
|
|
2714
|
+
const explicitToolResults = new Set(parts.flatMap((part) => part.type === "tool-result" ? [part.toolCallId] : []));
|
|
2715
|
+
const pushToolRows = (rowParts) => {
|
|
2716
|
+
for (const part of rowParts) if (part.type === "tool-result") {
|
|
2717
|
+
const id = uniqueToolWireId(part.id ?? deriveToolMessageId(part.toolCallId), usedWireIds);
|
|
2718
|
+
const metadata = rebuiltToolMetadata(part.metadata, part.createdAt, part.id, part.content, true, part.outcome);
|
|
2719
|
+
wire.push({
|
|
2720
|
+
role: "tool",
|
|
2721
|
+
id,
|
|
2722
|
+
toolCallId: part.toolCallId,
|
|
2723
|
+
...part.name !== void 0 && { name: part.name },
|
|
2724
|
+
content: typeof part.content === "string" ? part.content : JSON.stringify(part.content),
|
|
2725
|
+
...part.error !== void 0 && { error: part.error },
|
|
2726
|
+
...metadata !== void 0 && { metadata }
|
|
2727
|
+
});
|
|
2728
|
+
} else if (part.type === "tool-call") {
|
|
2729
|
+
const approved = part.approval?.approved;
|
|
2730
|
+
if (explicitToolResults.has(part.id) || part.output === void 0 && (part.state !== "approval-responded" || approved === void 0)) continue;
|
|
2731
|
+
const result = part.output !== void 0 ? normalizeToolResult(part.output) : JSON.stringify({
|
|
2732
|
+
approved,
|
|
2733
|
+
...approved && { pendingExecution: true },
|
|
2734
|
+
message: approved ? "User approved this action" : "User denied this action"
|
|
2735
|
+
});
|
|
2736
|
+
const content = typeof result === "string" ? result : JSON.stringify(result);
|
|
2737
|
+
wire.push({
|
|
2738
|
+
role: "tool",
|
|
2739
|
+
id: uniqueToolWireId(deriveToolMessageId(part.id), usedWireIds),
|
|
2740
|
+
toolCallId: part.id,
|
|
2741
|
+
content,
|
|
2742
|
+
metadata: rebuiltToolMetadata(void 0, void 0, void 0, result, false, part.approval?.approved === false ? "denied" : void 0)
|
|
2743
|
+
});
|
|
2744
|
+
}
|
|
2745
|
+
};
|
|
2746
|
+
let previousAnchorId = uiMessage.id;
|
|
2747
|
+
let toolParts = [];
|
|
1951
2748
|
segments.forEach((segment, index) => {
|
|
1952
2749
|
for (const part of segment.thinking) {
|
|
1953
2750
|
const reasoning = {
|
|
@@ -1960,45 +2757,31 @@ function uiMessagesToWire(messages, options) {
|
|
|
1960
2757
|
}
|
|
1961
2758
|
const text = collectText(segment.parts);
|
|
1962
2759
|
const toolCalls = collectToolCalls(segment.parts);
|
|
1963
|
-
const
|
|
2760
|
+
const anchor = toAnchor(index === 0 ? uiMessage : {
|
|
1964
2761
|
...uiMessage,
|
|
1965
2762
|
id: uniqueWireId(`${uiMessage.id}-segment-${index}`, usedWireIds)
|
|
1966
|
-
}
|
|
1967
|
-
wire.push(toAnchor(anchorMessage, "assistant", {
|
|
2763
|
+
}, "assistant", {
|
|
1968
2764
|
...text !== "" && { content: text },
|
|
1969
2765
|
...toolCalls && { toolCalls }
|
|
1970
|
-
}, segment.parts, includeSnapshotStructuredOutput)
|
|
2766
|
+
}, segment.parts, includeSnapshotStructuredOutput);
|
|
2767
|
+
if (segment.continues) {
|
|
2768
|
+
const metadata = anchor.metadata ?? {};
|
|
2769
|
+
anchor.metadata = {
|
|
2770
|
+
...metadata,
|
|
2771
|
+
tanstack: {
|
|
2772
|
+
...isRecord(metadata.tanstack) ? metadata.tanstack : {},
|
|
2773
|
+
continues: previousAnchorId
|
|
2774
|
+
}
|
|
2775
|
+
};
|
|
2776
|
+
}
|
|
2777
|
+
wire.push(anchor);
|
|
2778
|
+
previousAnchorId = anchor.id;
|
|
2779
|
+
toolParts.push(...segment.parts);
|
|
2780
|
+
if (segment.closed || index === segments.length - 1) {
|
|
2781
|
+
pushToolRows(toolParts);
|
|
2782
|
+
toolParts = [];
|
|
2783
|
+
}
|
|
1971
2784
|
});
|
|
1972
|
-
const explicitToolResults = new Set(parts.flatMap((part) => part.type === "tool-result" ? [part.toolCallId] : []));
|
|
1973
|
-
for (const part of parts) if (part.type === "tool-result") {
|
|
1974
|
-
const id = uniqueToolWireId(part.id ?? deriveToolMessageId(part.toolCallId), usedWireIds);
|
|
1975
|
-
const metadata = rebuiltToolMetadata(part.metadata, part.createdAt, part.id, part.content, true, part.outcome);
|
|
1976
|
-
wire.push({
|
|
1977
|
-
role: "tool",
|
|
1978
|
-
id,
|
|
1979
|
-
toolCallId: part.toolCallId,
|
|
1980
|
-
...part.name !== void 0 && { name: part.name },
|
|
1981
|
-
content: typeof part.content === "string" ? part.content : JSON.stringify(part.content),
|
|
1982
|
-
...part.error !== void 0 && { error: part.error },
|
|
1983
|
-
...metadata !== void 0 && { metadata }
|
|
1984
|
-
});
|
|
1985
|
-
} else if (part.type === "tool-call") {
|
|
1986
|
-
const approved = part.approval?.approved;
|
|
1987
|
-
if (explicitToolResults.has(part.id) || part.output === void 0 && (part.state !== "approval-responded" || approved === void 0)) continue;
|
|
1988
|
-
const result = part.output !== void 0 ? normalizeToolResult(part.output) : JSON.stringify({
|
|
1989
|
-
approved,
|
|
1990
|
-
...approved && { pendingExecution: true },
|
|
1991
|
-
message: approved ? "User approved this action" : "User denied this action"
|
|
1992
|
-
});
|
|
1993
|
-
const content = typeof result === "string" ? result : JSON.stringify(result);
|
|
1994
|
-
wire.push({
|
|
1995
|
-
role: "tool",
|
|
1996
|
-
id: uniqueToolWireId(deriveToolMessageId(part.id), usedWireIds),
|
|
1997
|
-
toolCallId: part.id,
|
|
1998
|
-
content,
|
|
1999
|
-
metadata: rebuiltToolMetadata(void 0, void 0, void 0, result, false, part.approval?.approved === false ? "denied" : void 0)
|
|
2000
|
-
});
|
|
2001
|
-
}
|
|
2002
2785
|
for (const part of parts) if (part.type === "subagent") wire.push(...subagentToWire(part, options));
|
|
2003
2786
|
}
|
|
2004
2787
|
return wire;
|
|
@@ -2029,12 +2812,19 @@ function toAnchor(msg, role, extras, parts, includeSnapshotStructuredOutput) {
|
|
|
2029
2812
|
}
|
|
2030
2813
|
function messageMetadata(msg, parts, includeSnapshotStructuredOutput) {
|
|
2031
2814
|
const base = { ...msg.metadata ?? {} };
|
|
2032
|
-
const
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2815
|
+
const tanstack = { ...tanstackMetadata(msg) };
|
|
2816
|
+
if (tanstack.run) {
|
|
2817
|
+
tanstack.run = { ...tanstack.run };
|
|
2818
|
+
delete tanstack.run.startedAt;
|
|
2819
|
+
delete tanstack.run.finishedAt;
|
|
2820
|
+
}
|
|
2821
|
+
delete tanstack.createdAt;
|
|
2822
|
+
delete tanstack.continues;
|
|
2823
|
+
delete tanstack.structuredOutput;
|
|
2824
|
+
delete tanstack.toolCallMetadata;
|
|
2825
|
+
delete tanstack.toolResult;
|
|
2826
|
+
delete tanstack.toolResultOutcome;
|
|
2827
|
+
delete tanstack.uiResources;
|
|
2038
2828
|
const createdAt = coerceCreatedAt(msg.createdAt);
|
|
2039
2829
|
if (createdAt !== void 0) tanstack.createdAt = createdAt.toISOString();
|
|
2040
2830
|
const structuredOutput = serializedStructuredOutput(parts, includeSnapshotStructuredOutput);
|
|
@@ -2184,11 +2974,11 @@ function hashContent(s) {
|
|
|
2184
2974
|
return Math.abs(h).toString(36);
|
|
2185
2975
|
}
|
|
2186
2976
|
//#endregion
|
|
2187
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
2977
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/restore-inbound-chunk.js
|
|
2188
2978
|
/**
|
|
2189
2979
|
* Rebuild TanStack `TokenUsage` (`promptTokens`) from spec `usage[]` plus
|
|
2190
|
-
* leftover fields in `metadata.tanstack.usage`. Restore in-process
|
|
2191
|
-
* that the wire does not keep (`
|
|
2980
|
+
* leftover fields in `metadata.tanstack.usage`. Restore the in-process field
|
|
2981
|
+
* that the wire does not keep (`TOOL_CALL_END.input`). Mutates
|
|
2192
2982
|
* in place so WeakMap run-id stamps stay attached.
|
|
2193
2983
|
*/
|
|
2194
2984
|
function restorePublicUsage(chunk) {
|
|
@@ -2196,9 +2986,9 @@ function restorePublicUsage(chunk) {
|
|
|
2196
2986
|
const rebuilt = rebuildTokenUsage(chunk.usage, tanstackMetadata(chunk)?.usage);
|
|
2197
2987
|
if (rebuilt !== void 0) chunk.usage = rebuilt;
|
|
2198
2988
|
}
|
|
2199
|
-
if (chunk.type === EventType.TOOL_CALL_START && chunk.toolName === void 0 && chunk.toolCallName) chunk.toolName = chunk.toolCallName;
|
|
2200
2989
|
if (chunk.type === EventType.TOOL_CALL_END && chunk.input === void 0) {
|
|
2201
|
-
const
|
|
2990
|
+
const tanstack = tanstackMetadata(chunk);
|
|
2991
|
+
const input = tanstack?.input ?? (typeof tanstack?.args === "string" ? parseToolArguments(tanstack.args) : void 0);
|
|
2202
2992
|
if (input !== void 0) chunk.input = input;
|
|
2203
2993
|
}
|
|
2204
2994
|
return chunk;
|
|
@@ -2221,7 +3011,7 @@ function restoreInboundChunk(chunk) {
|
|
|
2221
3011
|
return next;
|
|
2222
3012
|
}
|
|
2223
3013
|
//#endregion
|
|
2224
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
3014
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/activities/chat/tools/tool-definition.js
|
|
2225
3015
|
/**
|
|
2226
3016
|
* Create an isomorphic tool definition that can be used directly or instantiated for server/client
|
|
2227
3017
|
*
|
|
@@ -2319,7 +3109,7 @@ function toolDefinition(config) {
|
|
|
2319
3109
|
};
|
|
2320
3110
|
}
|
|
2321
3111
|
//#endregion
|
|
2322
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
3112
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/chunk-ids.js
|
|
2323
3113
|
function stringField(value) {
|
|
2324
3114
|
return typeof value === "string" && value !== "" ? value : void 0;
|
|
2325
3115
|
}
|
|
@@ -2422,7 +3212,7 @@ var require_options = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
2422
3212
|
exports.default = exports.Allow;
|
|
2423
3213
|
}));
|
|
2424
3214
|
//#endregion
|
|
2425
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
3215
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/activities/chat/stream/json-parser.js
|
|
2426
3216
|
var import_dist = (/* @__PURE__ */ __commonJSMin(((exports, module, this$1) => {
|
|
2427
3217
|
var __createBinding = this$1 && this$1.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
2428
3218
|
if (k2 === void 0) k2 = k;
|
|
@@ -2644,7 +3434,7 @@ function parsePartialJSON(jsonString) {
|
|
|
2644
3434
|
return defaultJSONParser.parse(jsonString);
|
|
2645
3435
|
}
|
|
2646
3436
|
//#endregion
|
|
2647
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
3437
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/activities/chat/stream/strategies.js
|
|
2648
3438
|
/**
|
|
2649
3439
|
* Immediate Strategy - emit on every chunk (default behavior)
|
|
2650
3440
|
*/
|
|
@@ -2654,16 +3444,14 @@ var ImmediateStrategy = class {
|
|
|
2654
3444
|
}
|
|
2655
3445
|
};
|
|
2656
3446
|
//#endregion
|
|
2657
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
3447
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/utilities/errors.js
|
|
2658
3448
|
/**
|
|
2659
3449
|
* Convert an AG-UI RUN_ERROR event to the Error shape exposed to consumers.
|
|
2660
|
-
* Preserves the provider code and sanitized raw event when available
|
|
2661
|
-
* accepting the deprecated nested error payload for backward compatibility.
|
|
3450
|
+
* Preserves the provider code and sanitized raw event when available.
|
|
2662
3451
|
*/
|
|
2663
3452
|
function runErrorEventToError(chunk) {
|
|
2664
|
-
const error = new Error(chunk.message ||
|
|
2665
|
-
|
|
2666
|
-
if (code !== void 0) Object.assign(error, { code });
|
|
3453
|
+
const error = new Error(chunk.message || "An error occurred");
|
|
3454
|
+
if (chunk.code !== void 0) Object.assign(error, { code: chunk.code });
|
|
2667
3455
|
if (chunk.rawEvent !== void 0) Object.assign(error, { rawEvent: chunk.rawEvent });
|
|
2668
3456
|
return error;
|
|
2669
3457
|
}
|
|
@@ -3317,7 +4105,7 @@ var fast_json_patch_default = Object.assign({}, core_exports, duplex_exports, {
|
|
|
3317
4105
|
unescapePathComponent
|
|
3318
4106
|
});
|
|
3319
4107
|
//#endregion
|
|
3320
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
4108
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/activities/chat/activity-records.js
|
|
3321
4109
|
function isActivityPart(part) {
|
|
3322
4110
|
return part.type === "activity";
|
|
3323
4111
|
}
|
|
@@ -3393,7 +4181,7 @@ function applyActivityDeltaToUIMessages(messages, chunk) {
|
|
|
3393
4181
|
}
|
|
3394
4182
|
}
|
|
3395
4183
|
//#endregion
|
|
3396
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
4184
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/activities/chat/stream/message-updaters.js
|
|
3397
4185
|
/**
|
|
3398
4186
|
* Message Updaters (Internal)
|
|
3399
4187
|
*
|
|
@@ -3695,7 +4483,7 @@ function updateThinkingPart(messages, messageId, stepId, content, signature) {
|
|
|
3695
4483
|
});
|
|
3696
4484
|
}
|
|
3697
4485
|
//#endregion
|
|
3698
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
4486
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/activities/chat/stream/processor.js
|
|
3699
4487
|
/**
|
|
3700
4488
|
* Unified Stream Processor
|
|
3701
4489
|
*
|
|
@@ -3747,35 +4535,6 @@ function interruptBatchHasGeneric(interrupts) {
|
|
|
3747
4535
|
});
|
|
3748
4536
|
}
|
|
3749
4537
|
/**
|
|
3750
|
-
* The canonical arguments string for a `TOOL_CALL_END.input`, or `undefined`
|
|
3751
|
-
* when JSON cannot carry it: `JSON.stringify` returns `undefined` (despite
|
|
3752
|
-
* its declared type) for a top-level function or symbol and throws on BigInt
|
|
3753
|
-
* and circular references. `null` is not tool arguments either, so it also
|
|
3754
|
-
* keeps the streamed value instead of writing `arguments = "null"`.
|
|
3755
|
-
*/
|
|
3756
|
-
function serializeToolInput(input) {
|
|
3757
|
-
if (input === void 0 || input === null) return void 0;
|
|
3758
|
-
try {
|
|
3759
|
-
const serialized = JSON.stringify(input);
|
|
3760
|
-
return typeof serialized === "string" ? serialized : void 0;
|
|
3761
|
-
} catch {
|
|
3762
|
-
return;
|
|
3763
|
-
}
|
|
3764
|
-
}
|
|
3765
|
-
/**
|
|
3766
|
-
* The input of a tool call from its raw arguments: `{}` for an empty string,
|
|
3767
|
-
* `undefined` when the arguments are not complete JSON (for example cut off)
|
|
3768
|
-
* or are `null`.
|
|
3769
|
-
*/
|
|
3770
|
-
function parseToolArguments(args) {
|
|
3771
|
-
if (args.trim() === "") return {};
|
|
3772
|
-
try {
|
|
3773
|
-
return JSON.parse(args) ?? void 0;
|
|
3774
|
-
} catch {
|
|
3775
|
-
return;
|
|
3776
|
-
}
|
|
3777
|
-
}
|
|
3778
|
-
/**
|
|
3779
4538
|
* StreamProcessor - State machine for processing AI response streams
|
|
3780
4539
|
*
|
|
3781
4540
|
* Manages the full UIMessage[] conversation and emits events on changes.
|
|
@@ -3801,11 +4560,14 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3801
4560
|
activeMessageIds = /* @__PURE__ */ new Set();
|
|
3802
4561
|
toolCallToMessage = /* @__PURE__ */ new Map();
|
|
3803
4562
|
pendingManualMessageId = null;
|
|
3804
|
-
pendingThinkingStepId = null;
|
|
3805
4563
|
openChunk = null;
|
|
3806
4564
|
structuredMessageIds = /* @__PURE__ */ new Set();
|
|
3807
4565
|
structuredOutputUpdateBatches = /* @__PURE__ */ new Map();
|
|
3808
4566
|
activeRuns = /* @__PURE__ */ new Set();
|
|
4567
|
+
callMessageIds = /* @__PURE__ */ new Map();
|
|
4568
|
+
unassignedCallMessageIds = /* @__PURE__ */ new Set();
|
|
4569
|
+
sealedMessageIds = /* @__PURE__ */ new Set();
|
|
4570
|
+
thinkingOwners = /* @__PURE__ */ new Map();
|
|
3809
4571
|
runToolCallIds = [];
|
|
3810
4572
|
toolCallsSentToClient = /* @__PURE__ */ new Set();
|
|
3811
4573
|
childProcessors = /* @__PURE__ */ new Map();
|
|
@@ -3912,16 +4674,6 @@ var StreamProcessor = class StreamProcessor {
|
|
|
3912
4674
|
this.resetStreamState();
|
|
3913
4675
|
}
|
|
3914
4676
|
/**
|
|
3915
|
-
* @deprecated Use prepareAssistantMessage() instead. This eagerly creates
|
|
3916
|
-
* an assistant message which can cause empty message flicker.
|
|
3917
|
-
*/
|
|
3918
|
-
startAssistantMessage(messageId) {
|
|
3919
|
-
this.prepareAssistantMessage();
|
|
3920
|
-
const { messageId: id } = this.ensureAssistantMessage(messageId);
|
|
3921
|
-
this.pendingManualMessageId = id;
|
|
3922
|
-
return id;
|
|
3923
|
-
}
|
|
3924
|
-
/**
|
|
3925
4677
|
* Get the current assistant message ID (if one has been created).
|
|
3926
4678
|
* Returns null if prepareAssistantMessage() was called but no content
|
|
3927
4679
|
* has arrived yet.
|
|
@@ -4000,6 +4752,11 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4000
4752
|
for (const id of this.messageStates.keys()) if (!keptIds.has(id)) this.messageStates.delete(id);
|
|
4001
4753
|
for (const [toolCallId, msgId] of this.toolCallToMessage) if (!keptIds.has(msgId)) this.toolCallToMessage.delete(toolCallId);
|
|
4002
4754
|
for (const id of this.activeMessageIds) if (!keptIds.has(id)) this.activeMessageIds.delete(id);
|
|
4755
|
+
if (this.pendingManualMessageId && !keptIds.has(this.pendingManualMessageId)) this.pendingManualMessageId = null;
|
|
4756
|
+
for (const ids of this.callMessageIds.values()) for (const id of ids) if (!keptIds.has(id)) ids.delete(id);
|
|
4757
|
+
for (const id of this.unassignedCallMessageIds) if (!keptIds.has(id)) this.unassignedCallMessageIds.delete(id);
|
|
4758
|
+
for (const id of this.sealedMessageIds) if (!keptIds.has(id)) this.sealedMessageIds.delete(id);
|
|
4759
|
+
for (const [key, owner] of this.thinkingOwners) if (!keptIds.has(owner.messageId)) this.thinkingOwners.delete(key);
|
|
4003
4760
|
this.messages = this.messages.slice(0, index + 1);
|
|
4004
4761
|
this.emitMessagesChange();
|
|
4005
4762
|
}
|
|
@@ -4007,6 +4764,8 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4007
4764
|
* Clear all messages
|
|
4008
4765
|
*/
|
|
4009
4766
|
clearMessages() {
|
|
4767
|
+
for (const ids of this.callMessageIds.values()) ids.clear();
|
|
4768
|
+
this.unassignedCallMessageIds.clear();
|
|
4010
4769
|
this.messages = [];
|
|
4011
4770
|
this.messageStates.clear();
|
|
4012
4771
|
this.activeMessageIds.clear();
|
|
@@ -4014,6 +4773,8 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4014
4773
|
this.structuredMessageIds.clear();
|
|
4015
4774
|
this.structuredOutputUpdateBatches.clear();
|
|
4016
4775
|
this.pendingManualMessageId = null;
|
|
4776
|
+
this.sealedMessageIds.clear();
|
|
4777
|
+
this.thinkingOwners.clear();
|
|
4017
4778
|
this.openChunk = null;
|
|
4018
4779
|
this.childProcessors.clear();
|
|
4019
4780
|
this.childToolCalls.clear();
|
|
@@ -4084,9 +4845,6 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4084
4845
|
case "RUN_ERROR":
|
|
4085
4846
|
this.handleRunErrorEvent(chunk);
|
|
4086
4847
|
break;
|
|
4087
|
-
case "STEP_FINISHED":
|
|
4088
|
-
this.handleStepFinishedEvent(chunk);
|
|
4089
|
-
break;
|
|
4090
4848
|
case "MESSAGES_SNAPSHOT":
|
|
4091
4849
|
this.handleMessagesSnapshotEvent(chunk);
|
|
4092
4850
|
break;
|
|
@@ -4097,9 +4855,18 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4097
4855
|
this.handleRunStartedEvent(chunk);
|
|
4098
4856
|
break;
|
|
4099
4857
|
case "REASONING_START":
|
|
4100
|
-
case "REASONING_MESSAGE_START":
|
|
4101
4858
|
case "REASONING_MESSAGE_END":
|
|
4102
4859
|
case "REASONING_END": break;
|
|
4860
|
+
case "REASONING_MESSAGE_START": {
|
|
4861
|
+
const start = chunk;
|
|
4862
|
+
const target = this.unscopedAssistant(start);
|
|
4863
|
+
const current = target.id ? this.getMessageState(target.id) : void 0;
|
|
4864
|
+
if (current) current.currentThinkingStepId = null;
|
|
4865
|
+
if (start.metadata == null) break;
|
|
4866
|
+
const { messageId } = this.ensureAssistantMessage(target.id ?? void 0, !target.create);
|
|
4867
|
+
this.mergeMessageMetadata(messageId, start.metadata);
|
|
4868
|
+
break;
|
|
4869
|
+
}
|
|
4103
4870
|
case "REASONING_MESSAGE_CONTENT":
|
|
4104
4871
|
this.handleReasoningMessageContentEvent(chunk);
|
|
4105
4872
|
break;
|
|
@@ -4109,9 +4876,6 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4109
4876
|
case "TOOL_CALL_RESULT":
|
|
4110
4877
|
this.handleToolCallResultEvent(chunk);
|
|
4111
4878
|
break;
|
|
4112
|
-
case "STEP_STARTED":
|
|
4113
|
-
this.handleStepStartedEvent(chunk);
|
|
4114
|
-
break;
|
|
4115
4879
|
case "ACTIVITY_SNAPSHOT":
|
|
4116
4880
|
this.handleActivitySnapshotEvent(chunk);
|
|
4117
4881
|
break;
|
|
@@ -4293,7 +5057,6 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4293
5057
|
totalTextContent: "",
|
|
4294
5058
|
currentSegmentText: "",
|
|
4295
5059
|
lastEmittedText: "",
|
|
4296
|
-
hasSeenReasoningEvents: false,
|
|
4297
5060
|
thinkingSteps: /* @__PURE__ */ new Map(),
|
|
4298
5061
|
thinkingStepSignatures: /* @__PURE__ */ new Map(),
|
|
4299
5062
|
thinkingStepOrder: [],
|
|
@@ -4309,38 +5072,95 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4309
5072
|
/**
|
|
4310
5073
|
* Get the MessageStreamState for a message
|
|
4311
5074
|
*/
|
|
4312
|
-
getMessageState(messageId) {
|
|
4313
|
-
return this.messageStates.get(messageId);
|
|
4314
|
-
}
|
|
4315
|
-
/**
|
|
4316
|
-
* Promote a pending stepId from a STEP_STARTED that fired before the
|
|
4317
|
-
* assistant message existed onto the given message state, so the next
|
|
4318
|
-
* thinking event (STEP_FINISHED or REASONING_MESSAGE_CONTENT) attributes
|
|
4319
|
-
* to the correct step.
|
|
4320
|
-
*/
|
|
4321
|
-
consumePendingThinkingStep(state) {
|
|
4322
|
-
if (!this.pendingThinkingStepId) return;
|
|
4323
|
-
const stepId = this.pendingThinkingStepId;
|
|
4324
|
-
state.currentThinkingStepId = stepId;
|
|
4325
|
-
if (!state.thinkingSteps.has(stepId)) {
|
|
4326
|
-
state.thinkingSteps.set(stepId, "");
|
|
4327
|
-
state.thinkingStepOrder.push(stepId);
|
|
4328
|
-
}
|
|
4329
|
-
this.pendingThinkingStepId = null;
|
|
5075
|
+
getMessageState(messageId) {
|
|
5076
|
+
return this.messageStates.get(messageId);
|
|
4330
5077
|
}
|
|
4331
5078
|
/**
|
|
4332
5079
|
* Get the most recent active assistant message ID.
|
|
4333
5080
|
* Used as fallback for events that don't include a messageId.
|
|
4334
5081
|
*/
|
|
4335
5082
|
getActiveAssistantMessageId() {
|
|
5083
|
+
const belongsToCurrentCall = (id) => this.activeRuns.size === 0 || [...this.activeRuns].some((runId) => this.callMessageIds.get(runId)?.has(id)) || this.pendingManualMessageId === id && !this.messageStates.get(id)?.isComplete && !this.isDone;
|
|
4336
5084
|
const ids = Array.from(this.activeMessageIds).reverse();
|
|
4337
5085
|
for (const id of ids) {
|
|
5086
|
+
if (this.sealedMessageIds.has(id)) continue;
|
|
4338
5087
|
const state = this.messageStates.get(id);
|
|
4339
|
-
if (state && state.role === "assistant") return id;
|
|
5088
|
+
if (state && state.role === "assistant" && belongsToCurrentCall(id)) return id;
|
|
5089
|
+
}
|
|
5090
|
+
for (const [id, state] of [...this.messageStates].reverse()) {
|
|
5091
|
+
if (this.sealedMessageIds.has(id)) continue;
|
|
5092
|
+
if (state.role === "assistant" && belongsToCurrentCall(id)) return id;
|
|
5093
|
+
}
|
|
5094
|
+
return null;
|
|
5095
|
+
}
|
|
5096
|
+
/** The run that currently owns `messageId`, if one was recorded. */
|
|
5097
|
+
runOfMessage(messageId) {
|
|
5098
|
+
for (const [runId, ids] of this.callMessageIds) if (ids.has(messageId)) return runId;
|
|
5099
|
+
}
|
|
5100
|
+
/** Latest unsealed assistant message written by `runId`. */
|
|
5101
|
+
openMessageOfRun(runId) {
|
|
5102
|
+
const ids = this.callMessageIds.get(runId);
|
|
5103
|
+
if (!ids) return null;
|
|
5104
|
+
for (const id of [...ids].reverse()) {
|
|
5105
|
+
if (this.sealedMessageIds.has(id)) continue;
|
|
5106
|
+
if (this.messageStates.get(id)?.role === "assistant") return id;
|
|
4340
5107
|
}
|
|
4341
|
-
for (const [id, state] of [...this.messageStates].reverse()) if (state.role === "assistant") return id;
|
|
4342
5108
|
return null;
|
|
4343
5109
|
}
|
|
5110
|
+
/**
|
|
5111
|
+
* Where an event with no assistant message id belongs.
|
|
5112
|
+
* `create` means open a new message. Do not borrow another run's.
|
|
5113
|
+
*/
|
|
5114
|
+
unscopedAssistant(chunk) {
|
|
5115
|
+
const explicit = getChunkRunId(chunk);
|
|
5116
|
+
const onlyRun = this.activeRuns.size === 1 ? [...this.activeRuns][0] : void 0;
|
|
5117
|
+
const runId = explicit ?? onlyRun;
|
|
5118
|
+
if (runId !== void 0) {
|
|
5119
|
+
const open = this.openMessageOfRun(runId);
|
|
5120
|
+
if (open) return {
|
|
5121
|
+
id: open,
|
|
5122
|
+
create: false
|
|
5123
|
+
};
|
|
5124
|
+
if (explicit !== void 0 || this.activeRuns.has(runId)) return {
|
|
5125
|
+
id: null,
|
|
5126
|
+
create: true
|
|
5127
|
+
};
|
|
5128
|
+
}
|
|
5129
|
+
const active = this.getActiveAssistantMessageId();
|
|
5130
|
+
if (active) return {
|
|
5131
|
+
id: active,
|
|
5132
|
+
create: false
|
|
5133
|
+
};
|
|
5134
|
+
return {
|
|
5135
|
+
id: null,
|
|
5136
|
+
create: true
|
|
5137
|
+
};
|
|
5138
|
+
}
|
|
5139
|
+
rememberThinking(messageId, stepId, reasoningMessageId) {
|
|
5140
|
+
const owner = {
|
|
5141
|
+
messageId,
|
|
5142
|
+
stepId
|
|
5143
|
+
};
|
|
5144
|
+
this.thinkingOwners.set(stepId, owner);
|
|
5145
|
+
if (reasoningMessageId !== void 0 && reasoningMessageId !== stepId) this.thinkingOwners.set(reasoningMessageId, owner);
|
|
5146
|
+
}
|
|
5147
|
+
/** Put `signature` on the thinking step `namedId` already belongs to. */
|
|
5148
|
+
applyKnownSignature(namedId, signature) {
|
|
5149
|
+
if (!namedId) return false;
|
|
5150
|
+
const owner = this.thinkingOwners.get(namedId);
|
|
5151
|
+
if (!owner) return false;
|
|
5152
|
+
const state = this.getMessageState(owner.messageId);
|
|
5153
|
+
if (!state) return false;
|
|
5154
|
+
state.thinkingStepSignatures.set(owner.stepId, signature);
|
|
5155
|
+
const content = state.thinkingSteps.get(owner.stepId) ?? "";
|
|
5156
|
+
if (!state.thinkingSteps.has(owner.stepId)) {
|
|
5157
|
+
state.thinkingSteps.set(owner.stepId, content);
|
|
5158
|
+
state.thinkingStepOrder.push(owner.stepId);
|
|
5159
|
+
}
|
|
5160
|
+
this.messages = updateThinkingPart(this.messages, owner.messageId, owner.stepId, content, signature);
|
|
5161
|
+
this.emitMessagesChange();
|
|
5162
|
+
return true;
|
|
5163
|
+
}
|
|
4344
5164
|
resumeAssistantState(id, state) {
|
|
4345
5165
|
this.activeMessageIds.add(id);
|
|
4346
5166
|
if (state.isComplete || this.isDone) {
|
|
@@ -4350,7 +5170,8 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4350
5170
|
}
|
|
4351
5171
|
/**
|
|
4352
5172
|
* Ensure an active assistant message exists, creating one if needed.
|
|
4353
|
-
* Used
|
|
5173
|
+
* Used when content (reasoning, tool calls, errors) arrives without a
|
|
5174
|
+
* prior TEXT_MESSAGE_START.
|
|
4354
5175
|
*
|
|
4355
5176
|
* On reconnect/resume, a TEXT_MESSAGE_CONTENT may arrive for a message that
|
|
4356
5177
|
* already exists in this.messages (e.g. from initialMessages or a prior
|
|
@@ -4359,6 +5180,11 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4359
5180
|
*/
|
|
4360
5181
|
ensureAssistantMessage(preferredId, fallbackToActive = true) {
|
|
4361
5182
|
if (preferredId) {
|
|
5183
|
+
const pendingId = this.pendingManualMessageId;
|
|
5184
|
+
if (pendingId && pendingId !== preferredId && this.messageStates.get(pendingId)?.isComplete === false && !this.messages.some((message) => message.id === preferredId)) {
|
|
5185
|
+
this.renameMessage(pendingId, preferredId);
|
|
5186
|
+
this.pendingManualMessageId = preferredId;
|
|
5187
|
+
}
|
|
4362
5188
|
const state = this.getMessageState(preferredId);
|
|
4363
5189
|
if (state) {
|
|
4364
5190
|
this.resumeAssistantState(preferredId, state);
|
|
@@ -4368,7 +5194,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4368
5194
|
};
|
|
4369
5195
|
}
|
|
4370
5196
|
}
|
|
4371
|
-
const activeId = fallbackToActive ? this.getActiveAssistantMessageId() : null;
|
|
5197
|
+
const activeId = fallbackToActive && preferredId === void 0 ? this.getActiveAssistantMessageId() : null;
|
|
4372
5198
|
if (activeId) {
|
|
4373
5199
|
const state = this.getMessageState(activeId);
|
|
4374
5200
|
if (state) {
|
|
@@ -4422,6 +5248,12 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4422
5248
|
* Rebuilds `createdAt` when `tanstack.createdAt` is an ISO string.
|
|
4423
5249
|
*/
|
|
4424
5250
|
mergeMessageMetadata(messageId, incoming) {
|
|
5251
|
+
const runId = tanstackMetadata({ metadata: incoming !== null && typeof incoming === "object" ? { ...incoming } : void 0 })?.runId ?? (this.activeRuns.size === 1 ? [...this.activeRuns][0] : void 0);
|
|
5252
|
+
if (runId !== void 0) {
|
|
5253
|
+
const ids = this.callMessageIds.get(runId) ?? /* @__PURE__ */ new Set();
|
|
5254
|
+
ids.add(messageId);
|
|
5255
|
+
this.callMessageIds.set(runId, ids);
|
|
5256
|
+
} else this.unassignedCallMessageIds.add(messageId);
|
|
4425
5257
|
if (incoming == null || typeof incoming !== "object" || Array.isArray(incoming)) return;
|
|
4426
5258
|
const message = this.messages.find((msg) => msg.id === messageId);
|
|
4427
5259
|
if (!message) return;
|
|
@@ -4622,6 +5454,13 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4622
5454
|
this.structuredOutputUpdateBatches.delete(fromId);
|
|
4623
5455
|
this.structuredOutputUpdateBatches.set(toId, batch);
|
|
4624
5456
|
}
|
|
5457
|
+
for (const ids of this.callMessageIds.values()) if (ids.delete(fromId)) ids.add(toId);
|
|
5458
|
+
if (this.unassignedCallMessageIds.delete(fromId)) this.unassignedCallMessageIds.add(toId);
|
|
5459
|
+
if (this.sealedMessageIds.delete(fromId)) this.sealedMessageIds.add(toId);
|
|
5460
|
+
for (const [key, owner] of this.thinkingOwners) if (owner.messageId === fromId) this.thinkingOwners.set(key, {
|
|
5461
|
+
messageId: toId,
|
|
5462
|
+
stepId: owner.stepId
|
|
5463
|
+
});
|
|
4625
5464
|
}
|
|
4626
5465
|
/**
|
|
4627
5466
|
* Handle TEXT_MESSAGE_START event
|
|
@@ -4633,8 +5472,10 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4633
5472
|
return;
|
|
4634
5473
|
}
|
|
4635
5474
|
const uiRole = role === "user" || role === "system" ? role : "assistant";
|
|
4636
|
-
|
|
4637
|
-
|
|
5475
|
+
const pendingId = this.pendingManualMessageId;
|
|
5476
|
+
const pendingRun = pendingId ? this.runOfMessage(pendingId) : void 0;
|
|
5477
|
+
const targetRun = this.runOfMessage(messageId);
|
|
5478
|
+
if (pendingId && !(pendingRun !== void 0 && targetRun !== void 0 && pendingRun !== targetRun)) {
|
|
4638
5479
|
this.pendingManualMessageId = null;
|
|
4639
5480
|
if (pendingId !== messageId) this.renameMessage(pendingId, messageId);
|
|
4640
5481
|
let pendingState = this.messageStates.get(messageId);
|
|
@@ -4835,6 +5676,8 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4835
5676
|
* message. Fold leading thinking-only messages into the next real
|
|
4836
5677
|
* assistant. Do not fold into a tool-result-only message (`role: 'tool'`
|
|
4837
5678
|
* on the wire). `reconcileSnapshotToolCalls` anchors those results.
|
|
5679
|
+
* A `<id>-segment-<n>` row folds into its message, together with the
|
|
5680
|
+
* tool-result rows between them (a tool result ends a wire segment).
|
|
4838
5681
|
*/
|
|
4839
5682
|
mergeReasoningFanOut(messages) {
|
|
4840
5683
|
const out = [];
|
|
@@ -4859,12 +5702,19 @@ var StreamProcessor = class StreamProcessor {
|
|
|
4859
5702
|
};
|
|
4860
5703
|
pending = [];
|
|
4861
5704
|
} else flushPending();
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
|
|
5705
|
+
let parentIndex = out.length - 1;
|
|
5706
|
+
while (parentIndex >= 0) {
|
|
5707
|
+
const candidate = out[parentIndex];
|
|
5708
|
+
if (!candidate || !isToolResultOnly(candidate)) break;
|
|
5709
|
+
parentIndex--;
|
|
5710
|
+
}
|
|
5711
|
+
const parent = out[parentIndex];
|
|
5712
|
+
if (parent?.role === "assistant" && next.role === "assistant" && isAssistantSegmentOf(next.id, parent.id)) {
|
|
5713
|
+
const folded = out.slice(parentIndex).flatMap((message) => message.parts);
|
|
5714
|
+
out.splice(parentIndex, out.length - parentIndex, {
|
|
5715
|
+
...parent,
|
|
5716
|
+
parts: [...folded, ...next.parts]
|
|
5717
|
+
});
|
|
4868
5718
|
continue;
|
|
4869
5719
|
}
|
|
4870
5720
|
out.push(next);
|
|
@@ -5012,10 +5862,13 @@ var StreamProcessor = class StreamProcessor {
|
|
|
5012
5862
|
if (pendingId && parentId && parentId !== pendingId) {
|
|
5013
5863
|
const parent = this.messages.find((m) => m.id === parentId);
|
|
5014
5864
|
const placeholder = this.messages.find((m) => m.id === pendingId);
|
|
5865
|
+
const pendingRun = this.runOfMessage(pendingId);
|
|
5866
|
+
const parentRun = parent ? this.runOfMessage(parent.id) : void 0;
|
|
5867
|
+
const separateRuns = pendingRun !== void 0 && parentRun !== void 0 && pendingRun !== parentRun;
|
|
5015
5868
|
if (!parent) {
|
|
5016
5869
|
this.pendingManualMessageId = null;
|
|
5017
5870
|
this.renameMessage(pendingId, parentId);
|
|
5018
|
-
} else if (parent.role === "assistant" && placeholder) {
|
|
5871
|
+
} else if (!separateRuns && parent.role === "assistant" && placeholder) {
|
|
5019
5872
|
this.pendingManualMessageId = null;
|
|
5020
5873
|
this.messages = this.messages.filter((m) => m.id !== pendingId).map((m) => m.id === parentId ? {
|
|
5021
5874
|
...m,
|
|
@@ -5026,6 +5879,8 @@ var StreamProcessor = class StreamProcessor {
|
|
|
5026
5879
|
}
|
|
5027
5880
|
const targetMessageId = chunk.parentMessageId ?? this.getActiveAssistantMessageId();
|
|
5028
5881
|
const { messageId, state } = this.ensureAssistantMessage(targetMessageId ?? void 0, chunk.parentMessageId === void 0);
|
|
5882
|
+
const tanstack = tanstackMetadata(chunk);
|
|
5883
|
+
this.mergeMessageMetadata(messageId, tanstack === void 0 ? void 0 : { tanstack });
|
|
5029
5884
|
state.hasToolCallsSinceTextStart = true;
|
|
5030
5885
|
const toolCallId = chunk.toolCallId;
|
|
5031
5886
|
if (!state.toolCalls.get(toolCallId)) {
|
|
@@ -5095,9 +5950,9 @@ var StreamProcessor = class StreamProcessor {
|
|
|
5095
5950
|
* Handle TOOL_CALL_END event — arguments are finalized (input-complete).
|
|
5096
5951
|
* Tool output arrives on TOOL_CALL_RESULT, not on this event.
|
|
5097
5952
|
*
|
|
5098
|
-
*
|
|
5099
|
-
*
|
|
5100
|
-
*
|
|
5953
|
+
* The END's raw `args` and parsed `input` replace the streamed arguments
|
|
5954
|
+
* (see `finishToolCallArguments`), and the part's `input` is parsed from
|
|
5955
|
+
* the result. That covers adapters that deliver the whole input on END
|
|
5101
5956
|
* (e.g. Anthropic server_tool_use / web_search — issue #839) and adapters
|
|
5102
5957
|
* that stream the wire arguments and then normalize them (OpenAI strict-mode
|
|
5103
5958
|
* null widening, undone by the adapter after #939), so `arguments` and
|
|
@@ -5110,25 +5965,11 @@ var StreamProcessor = class StreamProcessor {
|
|
|
5110
5965
|
if (!messageId) return;
|
|
5111
5966
|
const msgState = this.getMessageState(messageId);
|
|
5112
5967
|
if (!msgState) return;
|
|
5113
|
-
const input = chunk.input !== void 0 ? chunk.input : tanstackMetadata(chunk)?.input;
|
|
5114
5968
|
const existingToolCall = msgState.toolCalls.get(chunk.toolCallId);
|
|
5115
5969
|
if (existingToolCall && existingToolCall.state !== "input-complete") {
|
|
5116
|
-
|
|
5117
|
-
if (serializedInput !== void 0) existingToolCall.arguments = serializedInput;
|
|
5970
|
+
existingToolCall.arguments = finishToolCallArguments(existingToolCall.arguments, chunk).args;
|
|
5118
5971
|
const index = msgState.toolCallOrder.indexOf(chunk.toolCallId);
|
|
5119
5972
|
this.completeToolCall(messageId, index, existingToolCall);
|
|
5120
|
-
if (serializedInput !== void 0) {
|
|
5121
|
-
existingToolCall.parsedArguments = input;
|
|
5122
|
-
this.messages = updateToolCallPart(this.messages, messageId, {
|
|
5123
|
-
id: existingToolCall.id,
|
|
5124
|
-
name: existingToolCall.name,
|
|
5125
|
-
arguments: existingToolCall.arguments,
|
|
5126
|
-
state: "input-complete",
|
|
5127
|
-
input,
|
|
5128
|
-
...existingToolCall.metadata !== void 0 && { metadata: existingToolCall.metadata }
|
|
5129
|
-
});
|
|
5130
|
-
this.emitMessagesChange();
|
|
5131
|
-
}
|
|
5132
5973
|
}
|
|
5133
5974
|
}
|
|
5134
5975
|
/**
|
|
@@ -5166,6 +6007,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
5166
6007
|
if (this.activeRuns.size === 0) {
|
|
5167
6008
|
this.runToolCallIds = [];
|
|
5168
6009
|
this.toolCallsSentToClient.clear();
|
|
6010
|
+
this.streamEndEmitted = false;
|
|
5169
6011
|
}
|
|
5170
6012
|
this.activeRuns.add(chunk.runId);
|
|
5171
6013
|
}
|
|
@@ -5181,12 +6023,26 @@ var StreamProcessor = class StreamProcessor {
|
|
|
5181
6023
|
*/
|
|
5182
6024
|
handleRunFinishedEvent(chunk) {
|
|
5183
6025
|
const extra = chunk;
|
|
6026
|
+
const incoming = tanstackMetadata(chunk);
|
|
6027
|
+
const model = chunk.model ?? incoming?.model;
|
|
6028
|
+
const responseId = chunk.responseId ?? incoming?.responseId;
|
|
6029
|
+
const ids = this.callMessageIds.get(chunk.runId) ?? (this.activeRuns.has(chunk.runId) ? /* @__PURE__ */ new Set() : new Set(this.unassignedCallMessageIds));
|
|
6030
|
+
for (const messageId of ids) this.mergeMessageMetadata(messageId, withTanstackMetadata(chunk, {
|
|
6031
|
+
...model !== void 0 ? { model } : {},
|
|
6032
|
+
...responseId !== void 0 ? { responseId } : {}
|
|
6033
|
+
}).metadata);
|
|
6034
|
+
if (this.pendingManualMessageId && ids.has(this.pendingManualMessageId)) this.pendingManualMessageId = null;
|
|
6035
|
+
this.callMessageIds.delete(chunk.runId);
|
|
6036
|
+
for (const id of ids) this.unassignedCallMessageIds.delete(id);
|
|
5184
6037
|
this.finishReason = extra.finishReason !== void 0 ? extra.finishReason : tanstackMetadata(chunk)?.finishReason ?? null;
|
|
5185
6038
|
this.activeRuns.delete(chunk.runId);
|
|
5186
6039
|
if (chunk.outcome?.type === "interrupt") this.handleInterrupts(chunk.outcome.interrupts);
|
|
5187
6040
|
if (this.activeRuns.size === 0) {
|
|
5188
6041
|
this.completeAllToolCalls();
|
|
5189
|
-
if (this.finishReason === "tool_calls" && chunk.outcome?.type !== "interrupt")
|
|
6042
|
+
if (this.finishReason === "tool_calls" && chunk.outcome?.type !== "interrupt") {
|
|
6043
|
+
for (const id of ids) this.sealedMessageIds.add(id);
|
|
6044
|
+
return;
|
|
6045
|
+
}
|
|
5190
6046
|
if (!chunk.outcome || chunk.outcome.type === "success") this.handlePendingToolCalls(chunk.outcome?.pendingToolCallIds);
|
|
5191
6047
|
this.isDone = true;
|
|
5192
6048
|
this.finalizeStream();
|
|
@@ -5206,6 +6062,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
5206
6062
|
if (this.toolCallsSentToClient.has(toolCallId)) continue;
|
|
5207
6063
|
const part = parts.find((p) => p.type === "tool-call" && p.id === toolCallId);
|
|
5208
6064
|
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;
|
|
6065
|
+
if (this.finishReason === "length") continue;
|
|
5209
6066
|
const input = part.input ?? parseToolArguments(part.arguments);
|
|
5210
6067
|
if (input === void 0) {
|
|
5211
6068
|
console.warn(`[StreamProcessor] Did not run tool call ${toolCallId}: the arguments of ${part.name} are not complete JSON`);
|
|
@@ -5235,7 +6092,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
5235
6092
|
if (owner !== void 0) this.updateChild(owner, (child) => child.handleInterrupts([interrupt], false));
|
|
5236
6093
|
const toolName = typeof metadata.toolName === "string" ? metadata.toolName : this.findToolCallName(toolCallId);
|
|
5237
6094
|
const input = Object.hasOwn(metadata, "input") ? metadata.input : {};
|
|
5238
|
-
if (kind === "approval"
|
|
6095
|
+
if (kind === "approval") {
|
|
5239
6096
|
if (owner !== void 0) {
|
|
5240
6097
|
if (emit) this.events.onApprovalRequest?.({
|
|
5241
6098
|
toolCallId,
|
|
@@ -5259,7 +6116,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
5259
6116
|
});
|
|
5260
6117
|
continue;
|
|
5261
6118
|
}
|
|
5262
|
-
if (kind === "client_tool"
|
|
6119
|
+
if (kind === "client_tool") {
|
|
5263
6120
|
if (hasGeneric || !emit) continue;
|
|
5264
6121
|
this.toolCallsSentToClient.add(toolCallId);
|
|
5265
6122
|
this.events.onToolCall?.({
|
|
@@ -5282,13 +6139,20 @@ var StreamProcessor = class StreamProcessor {
|
|
|
5282
6139
|
*/
|
|
5283
6140
|
handleRunErrorEvent(chunk) {
|
|
5284
6141
|
this.hasError = true;
|
|
5285
|
-
const runId = getChunkRunId(chunk);
|
|
6142
|
+
const runId = getChunkRunId(chunk) ?? (this.activeRuns.size === 1 ? [...this.activeRuns][0] : void 0);
|
|
6143
|
+
const currentIds = runId !== void 0 ? this.callMessageIds.get(runId) ?? this.unassignedCallMessageIds : this.unassignedCallMessageIds;
|
|
5286
6144
|
if (runId) this.activeRuns.delete(runId);
|
|
5287
6145
|
else this.activeRuns.clear();
|
|
5288
|
-
const
|
|
6146
|
+
const messageId = runId !== void 0 && this.callMessageIds.has(runId) && currentIds.size === 0 ? void 0 : this.ensureAssistantMessage([...currentIds].at(-1) ?? generateMessageId(), false).messageId;
|
|
6147
|
+
const ids = new Set(currentIds);
|
|
6148
|
+
if (messageId !== void 0) ids.add(messageId);
|
|
6149
|
+
for (const id of ids) this.mergeMessageMetadata(id, withTanstackMetadata(chunk, { stopReason: tanstackMetadata(chunk)?.stopReason ?? "error" }).metadata);
|
|
6150
|
+
if (this.pendingManualMessageId && ids.has(this.pendingManualMessageId)) this.pendingManualMessageId = null;
|
|
6151
|
+
if (runId !== void 0) this.callMessageIds.delete(runId);
|
|
6152
|
+
for (const id of ids) this.unassignedCallMessageIds.delete(id);
|
|
5289
6153
|
const errorMessage = chunk.message || "An error occurred";
|
|
5290
6154
|
if (!chunk.message) console.error("[StreamProcessor] RUN_ERROR with no message; original chunk:", chunk);
|
|
5291
|
-
if (this.structuredMessageIds.has(messageId)) {
|
|
6155
|
+
if (messageId !== void 0 && this.structuredMessageIds.has(messageId)) {
|
|
5292
6156
|
this.flushStructuredOutputUpdate(messageId);
|
|
5293
6157
|
this.messages = errorStructuredOutputPart(this.messages, messageId, errorMessage);
|
|
5294
6158
|
this.structuredMessageIds.delete(messageId);
|
|
@@ -5298,30 +6162,6 @@ var StreamProcessor = class StreamProcessor {
|
|
|
5298
6162
|
this.events.onError?.(runErrorEventToError(chunk));
|
|
5299
6163
|
}
|
|
5300
6164
|
/**
|
|
5301
|
-
* Handle STEP_STARTED event (for thinking/reasoning content).
|
|
5302
|
-
*
|
|
5303
|
-
* Records the stepId so later REASONING_MESSAGE_CONTENT deltas accumulate
|
|
5304
|
-
* into their own ThinkingPart. Does not create a message — the message
|
|
5305
|
-
* is lazily created when the first REASONING_MESSAGE_CONTENT arrives.
|
|
5306
|
-
*/
|
|
5307
|
-
handleStepStartedEvent(chunk) {
|
|
5308
|
-
const stepId = chunk.stepName || generateMessageId();
|
|
5309
|
-
const activeId = this.getActiveAssistantMessageId();
|
|
5310
|
-
if (activeId) {
|
|
5311
|
-
const state = this.getMessageState(activeId);
|
|
5312
|
-
if (state) {
|
|
5313
|
-
state.currentThinkingStepId = stepId;
|
|
5314
|
-
if (!state.thinkingSteps.has(stepId)) {
|
|
5315
|
-
state.thinkingSteps.set(stepId, "");
|
|
5316
|
-
state.thinkingStepOrder.push(stepId);
|
|
5317
|
-
}
|
|
5318
|
-
this.pendingThinkingStepId = null;
|
|
5319
|
-
return;
|
|
5320
|
-
}
|
|
5321
|
-
}
|
|
5322
|
-
this.pendingThinkingStepId = stepId;
|
|
5323
|
-
}
|
|
5324
|
-
/**
|
|
5325
6165
|
* Handle ACTIVITY_SNAPSHOT. Creates or replaces a frontend-only activity
|
|
5326
6166
|
* message. Does not create MessageStreamState (that path feeds
|
|
5327
6167
|
* ProcessorResult.content).
|
|
@@ -5340,44 +6180,23 @@ var StreamProcessor = class StreamProcessor {
|
|
|
5340
6180
|
this.emitMessagesChange();
|
|
5341
6181
|
}
|
|
5342
6182
|
/**
|
|
5343
|
-
* Handle STEP_FINISHED event.
|
|
5344
|
-
*
|
|
5345
|
-
* Thinking *content* comes from REASONING_MESSAGE_CONTENT, not STEP_FINISHED.
|
|
5346
|
-
* But some adapters (e.g. BytePlus thinking-summary) carry the provider
|
|
5347
|
-
* signature blob ONLY on the STEP_FINISHED event, so still extract that here
|
|
5348
|
-
* and attach it to the thinking step the reasoning events already built.
|
|
5349
|
-
*/
|
|
5350
|
-
handleStepFinishedEvent(chunk) {
|
|
5351
|
-
const extra = chunk;
|
|
5352
|
-
const signature = extra.signature;
|
|
5353
|
-
if (!signature) return;
|
|
5354
|
-
const { messageId, state } = this.ensureAssistantMessage(this.getActiveAssistantMessageId() ?? void 0);
|
|
5355
|
-
const stepId = state.currentThinkingStepId ?? extra.stepId;
|
|
5356
|
-
if (!stepId) return;
|
|
5357
|
-
const thinking = state.thinkingSteps.get(stepId);
|
|
5358
|
-
if (thinking === void 0) return;
|
|
5359
|
-
state.thinkingStepSignatures.set(stepId, signature);
|
|
5360
|
-
this.messages = updateThinkingPart(this.messages, messageId, stepId, thinking, signature);
|
|
5361
|
-
this.emitMessagesChange();
|
|
5362
|
-
}
|
|
5363
|
-
/**
|
|
5364
6183
|
* Handle REASONING_MESSAGE_CONTENT event (AG-UI reasoning protocol).
|
|
5365
6184
|
*
|
|
5366
6185
|
* Accumulates reasoning delta into thinking content and updates the
|
|
5367
6186
|
* corresponding ThinkingPart in the UIMessage.
|
|
5368
6187
|
*/
|
|
5369
6188
|
handleReasoningMessageContentEvent(chunk) {
|
|
5370
|
-
const
|
|
6189
|
+
const target = this.unscopedAssistant(chunk);
|
|
6190
|
+
const { messageId, state } = this.ensureAssistantMessage(target.id ?? void 0, !target.create);
|
|
5371
6191
|
this.mergeMessageMetadata(messageId, chunk.metadata);
|
|
5372
|
-
state.hasSeenReasoningEvents = true;
|
|
5373
6192
|
const delta = chunk.delta || "";
|
|
5374
|
-
this.consumePendingThinkingStep(state);
|
|
5375
6193
|
const stepId = state.currentThinkingStepId ?? chunk.messageId;
|
|
5376
6194
|
if (!state.thinkingSteps.has(stepId)) {
|
|
5377
6195
|
state.thinkingSteps.set(stepId, "");
|
|
5378
6196
|
state.thinkingStepOrder.push(stepId);
|
|
5379
6197
|
state.currentThinkingStepId = stepId;
|
|
5380
6198
|
}
|
|
6199
|
+
this.rememberThinking(messageId, stepId, chunk.messageId);
|
|
5381
6200
|
const nextThinking = (state.thinkingSteps.get(stepId) ?? "") + delta;
|
|
5382
6201
|
state.thinkingSteps.set(stepId, nextThinking);
|
|
5383
6202
|
this.messages = updateThinkingPart(this.messages, messageId, stepId, nextThinking, state.thinkingStepSignatures.get(stepId));
|
|
@@ -5396,8 +6215,12 @@ var StreamProcessor = class StreamProcessor {
|
|
|
5396
6215
|
this.attachToolCallSignature(chunk.entityId, encryptedValue);
|
|
5397
6216
|
return;
|
|
5398
6217
|
}
|
|
5399
|
-
|
|
6218
|
+
if (this.applyKnownSignature(chunk.entityId, encryptedValue)) return;
|
|
6219
|
+
const target = this.unscopedAssistant(chunk);
|
|
6220
|
+
const { messageId, state } = this.ensureAssistantMessage(target.id ?? void 0, !target.create);
|
|
5400
6221
|
const stepId = state.currentThinkingStepId ?? chunk.entityId;
|
|
6222
|
+
this.rememberThinking(messageId, stepId, chunk.entityId);
|
|
6223
|
+
this.mergeMessageMetadata(messageId, chunk.metadata);
|
|
5401
6224
|
state.thinkingStepSignatures.set(stepId, encryptedValue);
|
|
5402
6225
|
const content = state.thinkingSteps.get(stepId) ?? "";
|
|
5403
6226
|
if (!state.thinkingSteps.has(stepId)) {
|
|
@@ -5439,23 +6262,15 @@ var StreamProcessor = class StreamProcessor {
|
|
|
5439
6262
|
/**
|
|
5440
6263
|
* Handle CUSTOM event.
|
|
5441
6264
|
*
|
|
5442
|
-
* Handles
|
|
5443
|
-
*
|
|
5444
|
-
*
|
|
5445
|
-
* - 'approval-requested': Legacy/replay-compatible input for tool approval.
|
|
5446
|
-
* Updates tool-call part state and fires onApprovalRequest.
|
|
5447
|
-
*
|
|
5448
|
-
* Current core streams represent user-actionable waits through
|
|
5449
|
-
* RUN_FINISHED.outcome.type === 'interrupt'; these custom events are not the
|
|
5450
|
-
* source of truth for new emissions.
|
|
5451
|
-
*
|
|
5452
|
-
* @see docs/chat-architecture.md#client-tools-and-approval-flows — Full flow details
|
|
6265
|
+
* Handles structured-output and ui-resource events, and forwards the rest
|
|
6266
|
+
* to onCustomEvent. Client tools and approvals arrive as RUN_FINISHED
|
|
6267
|
+
* interrupt outcomes, not as custom events.
|
|
5453
6268
|
*/
|
|
5454
6269
|
handleCustomEvent(chunk) {
|
|
5455
6270
|
const messageId = this.getActiveAssistantMessageId();
|
|
5456
6271
|
if (chunk.name === "structured-output.start" && chunk.value) {
|
|
5457
6272
|
const v = chunk.value;
|
|
5458
|
-
const { messageId: targetId } = this.ensureAssistantMessage(v.messageId
|
|
6273
|
+
const { messageId: targetId } = this.ensureAssistantMessage(v.messageId && this.getMessageState(v.messageId) ? v.messageId : messageId ?? v.messageId);
|
|
5459
6274
|
if (targetId) {
|
|
5460
6275
|
this.structuredMessageIds.add(targetId);
|
|
5461
6276
|
this.structuredOutputUpdateBatches.delete(targetId);
|
|
@@ -5470,7 +6285,7 @@ var StreamProcessor = class StreamProcessor {
|
|
|
5470
6285
|
}
|
|
5471
6286
|
if (chunk.name === "structured-output.complete" && chunk.value) {
|
|
5472
6287
|
const v = chunk.value;
|
|
5473
|
-
const { messageId: targetId } = this.ensureAssistantMessage(v.messageId
|
|
6288
|
+
const { messageId: targetId } = this.ensureAssistantMessage(v.messageId && this.getMessageState(v.messageId) ? v.messageId : messageId ?? v.messageId);
|
|
5474
6289
|
if (targetId) {
|
|
5475
6290
|
this.flushStructuredOutputUpdate(targetId);
|
|
5476
6291
|
this.messages = completeStructuredOutputPart(this.messages, targetId, v.object, v.raw ?? "", v.reasoning);
|
|
@@ -5479,31 +6294,6 @@ var StreamProcessor = class StreamProcessor {
|
|
|
5479
6294
|
this.emitMessagesChange();
|
|
5480
6295
|
}
|
|
5481
6296
|
}
|
|
5482
|
-
if (chunk.name === "tool-input-available" && chunk.value) {
|
|
5483
|
-
const { toolCallId, toolName, input } = chunk.value;
|
|
5484
|
-
this.toolCallsSentToClient.add(toolCallId);
|
|
5485
|
-
this.events.onToolCall?.({
|
|
5486
|
-
toolCallId,
|
|
5487
|
-
toolName,
|
|
5488
|
-
input
|
|
5489
|
-
});
|
|
5490
|
-
return;
|
|
5491
|
-
}
|
|
5492
|
-
if (chunk.name === "approval-requested" && chunk.value) {
|
|
5493
|
-
const { toolCallId, toolName, input, approval } = chunk.value;
|
|
5494
|
-
const resolvedMessageId = messageId ?? this.toolCallToMessage.get(toolCallId);
|
|
5495
|
-
if (resolvedMessageId) {
|
|
5496
|
-
this.messages = updateToolCallApproval(this.messages, resolvedMessageId, toolCallId, approval.id);
|
|
5497
|
-
this.emitMessagesChange();
|
|
5498
|
-
}
|
|
5499
|
-
this.events.onApprovalRequest?.({
|
|
5500
|
-
toolCallId,
|
|
5501
|
-
toolName,
|
|
5502
|
-
input,
|
|
5503
|
-
approvalId: approval.id
|
|
5504
|
-
});
|
|
5505
|
-
return;
|
|
5506
|
-
}
|
|
5507
6297
|
if (chunk.name === "ui-resource" && chunk.value) {
|
|
5508
6298
|
const v = chunk.value;
|
|
5509
6299
|
const resolvedMessageId = this.toolCallToMessage.get(v.toolCallId) ?? messageId;
|
|
@@ -5772,13 +6562,16 @@ var StreamProcessor = class StreamProcessor {
|
|
|
5772
6562
|
*/
|
|
5773
6563
|
resetStreamState() {
|
|
5774
6564
|
this.messageStates.clear();
|
|
6565
|
+
this.callMessageIds.clear();
|
|
6566
|
+
this.unassignedCallMessageIds.clear();
|
|
5775
6567
|
this.activeMessageIds.clear();
|
|
5776
6568
|
this.activeRuns.clear();
|
|
5777
6569
|
this.toolCallToMessage.clear();
|
|
5778
6570
|
this.structuredMessageIds.clear();
|
|
5779
6571
|
this.structuredOutputUpdateBatches.clear();
|
|
5780
6572
|
this.pendingManualMessageId = null;
|
|
5781
|
-
this.
|
|
6573
|
+
this.sealedMessageIds.clear();
|
|
6574
|
+
this.thinkingOwners.clear();
|
|
5782
6575
|
this.openChunk = null;
|
|
5783
6576
|
this.finishReason = null;
|
|
5784
6577
|
this.hasError = false;
|
|
@@ -5819,27 +6612,7 @@ function createReplayStream(recording) {
|
|
|
5819
6612
|
} };
|
|
5820
6613
|
}
|
|
5821
6614
|
//#endregion
|
|
5822
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.
|
|
5823
|
-
/** `[a-z][a-z0-9-]{0,63}` — lowercase, no underscores, max 64 chars. */
|
|
5824
|
-
var BYOK_PROVIDER_ID_PATTERN = /^[a-z][a-z0-9-]{0,63}$/;
|
|
5825
|
-
function isProviderId(value) {
|
|
5826
|
-
return typeof value === "string" && BYOK_PROVIDER_ID_PATTERN.test(value);
|
|
5827
|
-
}
|
|
5828
|
-
//#endregion
|
|
5829
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/byok/missing.js
|
|
5830
|
-
function isByokMissingBody(value) {
|
|
5831
|
-
if (typeof value !== "object" || value === null) return false;
|
|
5832
|
-
if (!("error" in value)) return false;
|
|
5833
|
-
const error = value.error;
|
|
5834
|
-
if (typeof error !== "object" || error === null) return false;
|
|
5835
|
-
if (!("type" in error) || error.type !== "byok_missing") return false;
|
|
5836
|
-
if (!("provider" in error) || typeof error.provider !== "string") return false;
|
|
5837
|
-
if (!isProviderId(error.provider)) return false;
|
|
5838
|
-
if (!("message" in error) || typeof error.message !== "string") return false;
|
|
5839
|
-
return true;
|
|
5840
|
-
}
|
|
5841
|
-
//#endregion
|
|
5842
|
-
//#region ../node_modules/.bun/@tanstack+ai@0.68.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/byok/errors.js
|
|
6615
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/byok/errors.js
|
|
5843
6616
|
var ByokMissingError = class extends Error {
|
|
5844
6617
|
provider;
|
|
5845
6618
|
constructor(provider) {
|
|
@@ -5865,7 +6638,27 @@ var ByokUnresolvedProviderError = class extends Error {
|
|
|
5865
6638
|
}
|
|
5866
6639
|
};
|
|
5867
6640
|
//#endregion
|
|
5868
|
-
//#region ../node_modules/.bun/@tanstack+ai
|
|
6641
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/byok/providers.js
|
|
6642
|
+
/** `[a-z][a-z0-9-]{0,63}` — lowercase, no underscores, max 64 chars. */
|
|
6643
|
+
var BYOK_PROVIDER_ID_PATTERN = /^[a-z][a-z0-9-]{0,63}$/;
|
|
6644
|
+
function isProviderId(value) {
|
|
6645
|
+
return typeof value === "string" && BYOK_PROVIDER_ID_PATTERN.test(value);
|
|
6646
|
+
}
|
|
6647
|
+
//#endregion
|
|
6648
|
+
//#region ../node_modules/.bun/@tanstack+ai@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai/dist/esm/byok/missing.js
|
|
6649
|
+
function isByokMissingBody(value) {
|
|
6650
|
+
if (typeof value !== "object" || value === null) return false;
|
|
6651
|
+
if (!("error" in value)) return false;
|
|
6652
|
+
const error = value.error;
|
|
6653
|
+
if (typeof error !== "object" || error === null) return false;
|
|
6654
|
+
if (!("type" in error) || error.type !== "byok_missing") return false;
|
|
6655
|
+
if (!("provider" in error) || typeof error.provider !== "string") return false;
|
|
6656
|
+
if (!isProviderId(error.provider)) return false;
|
|
6657
|
+
if (!("message" in error) || typeof error.message !== "string") return false;
|
|
6658
|
+
return true;
|
|
6659
|
+
}
|
|
6660
|
+
//#endregion
|
|
6661
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/connection-adapters.js
|
|
5869
6662
|
/**
|
|
5870
6663
|
* Associates connect-wrapped chunks with the run they were produced under.
|
|
5871
6664
|
* Content events (TEXT_MESSAGE_CONTENT, TOOL_CALL_*, …) carry no `runId` of
|
|
@@ -5917,19 +6710,59 @@ var DurableStreamIncompleteError = class extends Error {
|
|
|
5917
6710
|
* reconnecting without end.
|
|
5918
6711
|
*/
|
|
5919
6712
|
var StreamReconnectLimitError = class extends Error {
|
|
5920
|
-
constructor(attempts) {
|
|
5921
|
-
super(`Durable run exceeded its reconnect ceiling of ${attempts} attempts — giving up.`);
|
|
6713
|
+
constructor(attempts, budgetMs) {
|
|
6714
|
+
super(budgetMs === void 0 ? `Durable run exceeded its reconnect ceiling of ${attempts} attempts — giving up.` : `Durable run did not reconnect within its budget of ${budgetMs} ms (${attempts} attempts) — giving up.`);
|
|
5922
6715
|
this.name = "StreamReconnectLimitError";
|
|
5923
6716
|
}
|
|
5924
6717
|
};
|
|
6718
|
+
/** HTTP statuses that a proxy or server sends while it restarts or sheds load. */
|
|
6719
|
+
var TEMPORARY_HTTP_STATUSES = /* @__PURE__ */ new Set([
|
|
6720
|
+
408,
|
|
6721
|
+
429,
|
|
6722
|
+
502,
|
|
6723
|
+
503,
|
|
6724
|
+
504
|
|
6725
|
+
]);
|
|
6726
|
+
/**
|
|
6727
|
+
* A non-2xx response. A reconnect retries it when the status is temporary
|
|
6728
|
+
* (408, 429, 502, 503, 504), and waits for its `Retry-After` when present.
|
|
6729
|
+
*/
|
|
6730
|
+
var StreamHttpError = class extends Error {
|
|
6731
|
+
status;
|
|
6732
|
+
retryAfterMs;
|
|
6733
|
+
constructor(message, status, retryAfter) {
|
|
6734
|
+
super(message);
|
|
6735
|
+
this.status = status;
|
|
6736
|
+
this.name = "StreamHttpError";
|
|
6737
|
+
this.retryAfterMs = parseRetryAfterMs(retryAfter);
|
|
6738
|
+
}
|
|
6739
|
+
};
|
|
6740
|
+
/** `Retry-After` in seconds or as an HTTP date, in ms. */
|
|
6741
|
+
function parseRetryAfterMs(value) {
|
|
6742
|
+
if (!value) return void 0;
|
|
6743
|
+
const seconds = Number(value);
|
|
6744
|
+
if (Number.isFinite(seconds)) return seconds >= 0 ? seconds * 1e3 : void 0;
|
|
6745
|
+
const date = Date.parse(value);
|
|
6746
|
+
return Number.isNaN(date) ? void 0 : Math.max(0, date - Date.now());
|
|
6747
|
+
}
|
|
6748
|
+
function isTemporaryHttpError(error) {
|
|
6749
|
+
return error instanceof StreamHttpError && TEMPORARY_HTTP_STATUSES.has(error.status);
|
|
6750
|
+
}
|
|
5925
6751
|
function resolveReconnectOptions(options) {
|
|
5926
|
-
const
|
|
5927
|
-
const
|
|
5928
|
-
|
|
5929
|
-
|
|
6752
|
+
const budgetMs = options?.budgetMs;
|
|
6753
|
+
const maxAttempts = options?.maxAttempts ?? (budgetMs === void 0 ? 5 : Infinity);
|
|
6754
|
+
const initialDelayMs = options?.initialDelayMs ?? options?.delayMs ?? 250;
|
|
6755
|
+
const maxDelayMs = options?.maxDelayMs ?? Math.max(5e3, initialDelayMs);
|
|
6756
|
+
if (options?.maxAttempts !== void 0) {
|
|
6757
|
+
if (!Number.isInteger(maxAttempts) || maxAttempts < 0) throw new Error(`Invalid reconnect.maxAttempts: ${maxAttempts}. Must be a non-negative integer.`);
|
|
6758
|
+
}
|
|
6759
|
+
for (const [name, value] of [["initialDelayMs", initialDelayMs], ["maxDelayMs", maxDelayMs]]) if (!Number.isFinite(value) || value < 0) throw new Error(`Invalid reconnect.${name}: ${value}. Must be a non-negative finite number.`);
|
|
6760
|
+
if (budgetMs !== void 0 && (!Number.isFinite(budgetMs) || budgetMs <= 0)) throw new Error(`Invalid reconnect.budgetMs: ${budgetMs}. Must be a positive finite number.`);
|
|
5930
6761
|
return {
|
|
5931
6762
|
maxAttempts,
|
|
5932
|
-
|
|
6763
|
+
initialDelayMs,
|
|
6764
|
+
maxDelayMs,
|
|
6765
|
+
budgetMs
|
|
5933
6766
|
};
|
|
5934
6767
|
}
|
|
5935
6768
|
/** Create a {@link ReconnectTracker} bound to the given reconnect bounds. */
|
|
@@ -5938,6 +6771,7 @@ function createReconnectTracker(options) {
|
|
|
5938
6771
|
const seen = /* @__PURE__ */ new Set();
|
|
5939
6772
|
let lastEventId;
|
|
5940
6773
|
let reconnectAttempts = 0;
|
|
6774
|
+
let failingSince;
|
|
5941
6775
|
return {
|
|
5942
6776
|
get lastEventId() {
|
|
5943
6777
|
return lastEventId;
|
|
@@ -5954,13 +6788,19 @@ function createReconnectTracker(options) {
|
|
|
5954
6788
|
lastEventId = id;
|
|
5955
6789
|
return "new";
|
|
5956
6790
|
},
|
|
5957
|
-
async waitBeforeReconnect(madeProgress, signal) {
|
|
5958
|
-
if (madeProgress)
|
|
5959
|
-
|
|
6791
|
+
async waitBeforeReconnect(madeProgress, signal, retryAfterMs) {
|
|
6792
|
+
if (madeProgress) {
|
|
6793
|
+
reconnectAttempts = 0;
|
|
6794
|
+
failingSince = void 0;
|
|
6795
|
+
} else {
|
|
5960
6796
|
reconnectAttempts += 1;
|
|
6797
|
+
failingSince ??= Date.now();
|
|
5961
6798
|
if (reconnectAttempts > reconnect.maxAttempts) throw new StreamReconnectLimitError(reconnect.maxAttempts);
|
|
5962
6799
|
}
|
|
5963
|
-
|
|
6800
|
+
const backoff = reconnect.initialDelayMs === 0 ? 0 : Math.min(reconnect.maxDelayMs, reconnect.initialDelayMs * 2 ** Math.max(0, reconnectAttempts - 1));
|
|
6801
|
+
const delayMs = retryAfterMs === void 0 ? backoff * (.5 + Math.random() / 2) : Math.min(retryAfterMs, reconnect.maxDelayMs);
|
|
6802
|
+
if (reconnect.budgetMs !== void 0 && failingSince !== void 0 && Date.now() - failingSince + delayMs > reconnect.budgetMs) throw new StreamReconnectLimitError(reconnectAttempts - 1, reconnect.budgetMs);
|
|
6803
|
+
await abortableDelay(delayMs, signal);
|
|
5964
6804
|
}
|
|
5965
6805
|
};
|
|
5966
6806
|
}
|
|
@@ -5979,19 +6819,6 @@ function abortableDelay(ms, signal) {
|
|
|
5979
6819
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
5980
6820
|
});
|
|
5981
6821
|
}
|
|
5982
|
-
function generateRunId(prefix) {
|
|
5983
|
-
return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
5984
|
-
}
|
|
5985
|
-
/**
|
|
5986
|
-
* Asserts an id is present when synthesizing a terminal event. The chat
|
|
5987
|
-
* client always supplies `runContext.threadId` / `runContext.runId`, so an
|
|
5988
|
-
* absent id at this layer indicates the adapter was wired up by a caller
|
|
5989
|
-
* that bypassed that contract — surface it rather than fabricating one.
|
|
5990
|
-
*/
|
|
5991
|
-
function requireSyntheticId(value, field) {
|
|
5992
|
-
if (!value) throw new Error(`Cannot synthesize terminal event: ${field} not supplied via runContext and not observed in the upstream stream.`);
|
|
5993
|
-
return value;
|
|
5994
|
-
}
|
|
5995
6822
|
/**
|
|
5996
6823
|
* Merge custom headers into request headers
|
|
5997
6824
|
*/
|
|
@@ -6017,7 +6844,7 @@ function mergeHeaders(customHeaders) {
|
|
|
6017
6844
|
*/
|
|
6018
6845
|
var RUN_ID_HEADER = "X-Run-Id";
|
|
6019
6846
|
function runIdHeader(runId) {
|
|
6020
|
-
return
|
|
6847
|
+
return { [RUN_ID_HEADER]: runId };
|
|
6021
6848
|
}
|
|
6022
6849
|
function withSearchParams(url, values) {
|
|
6023
6850
|
const hashIndex = url.indexOf("#");
|
|
@@ -6064,19 +6891,6 @@ async function* readStreamLines(reader, abortSignal) {
|
|
|
6064
6891
|
reader.releaseLock();
|
|
6065
6892
|
}
|
|
6066
6893
|
}
|
|
6067
|
-
/** Rebuild pre-wire extras after SSE/NDJSON ingest. */
|
|
6068
|
-
function restoreInboundUsage(chunk) {
|
|
6069
|
-
return restoreInboundChunk(chunk);
|
|
6070
|
-
}
|
|
6071
|
-
function sseChunkModel(chunk) {
|
|
6072
|
-
const tanstackModel = tanstackMetadata(chunk)?.model;
|
|
6073
|
-
if (typeof tanstackModel === "string") return tanstackModel;
|
|
6074
|
-
const usage = "usage" in chunk ? chunk.usage : void 0;
|
|
6075
|
-
if (Array.isArray(usage)) {
|
|
6076
|
-
const model = usage[0]?.model;
|
|
6077
|
-
if (typeof model === "string") return model;
|
|
6078
|
-
}
|
|
6079
|
-
}
|
|
6080
6894
|
/**
|
|
6081
6895
|
* Parse SSE-format lines into stream events, pairing each chunk with the `id:`
|
|
6082
6896
|
* offset of the event it arrived on. Shared by the fetch- and XHR-backed SSE
|
|
@@ -6084,17 +6898,11 @@ function sseChunkModel(chunk) {
|
|
|
6084
6898
|
*
|
|
6085
6899
|
* Accepts either `data: {...}` lines or bare JSON lines. Skips comments
|
|
6086
6900
|
* starting with `:` (proxies and CDNs inject these as keepalives) and the
|
|
6087
|
-
* `event:` / `retry:` SSE control fields.
|
|
6088
|
-
* terminal event: a synthesized RUN_FINISHED is yielded using the most recent
|
|
6089
|
-
* upstream `threadId` / `runId` (falling back to `fallbackIds`), so the
|
|
6090
|
-
* consumer sees a clean terminal event with real correlation ids.
|
|
6901
|
+
* `event:` / `retry:` SSE control fields.
|
|
6091
6902
|
*
|
|
6092
6903
|
* A JSON parse failure throws — the consumer surfaces it as an error.
|
|
6093
6904
|
*/
|
|
6094
|
-
async function* linesToSSEEvents(lines
|
|
6095
|
-
let lastThreadId;
|
|
6096
|
-
let lastRunId;
|
|
6097
|
-
let lastModel;
|
|
6905
|
+
async function* linesToSSEEvents(lines) {
|
|
6098
6906
|
let pendingId;
|
|
6099
6907
|
for await (const line of lines) {
|
|
6100
6908
|
if (line === "id" || line.startsWith("id:")) {
|
|
@@ -6104,23 +6912,7 @@ async function* linesToSSEEvents(lines, fallbackIds) {
|
|
|
6104
6912
|
}
|
|
6105
6913
|
if (line.startsWith(":") || line.startsWith("event:") || line.startsWith("retry:")) continue;
|
|
6106
6914
|
const data = parseSseDataLine(line);
|
|
6107
|
-
|
|
6108
|
-
yield { chunk: withTanstackMetadata({
|
|
6109
|
-
type: EventType.RUN_FINISHED,
|
|
6110
|
-
threadId: lastThreadId ?? fallbackIds?.threadId ?? "",
|
|
6111
|
-
runId: lastRunId ?? fallbackIds?.runId ?? "",
|
|
6112
|
-
timestamp: Date.now()
|
|
6113
|
-
}, {
|
|
6114
|
-
finishReason: "stop",
|
|
6115
|
-
...lastModel !== void 0 ? { model: lastModel } : {}
|
|
6116
|
-
}) };
|
|
6117
|
-
return;
|
|
6118
|
-
}
|
|
6119
|
-
const chunk = restoreInboundUsage(JSON.parse(data));
|
|
6120
|
-
if ("threadId" in chunk && typeof chunk.threadId === "string") lastThreadId = chunk.threadId;
|
|
6121
|
-
if ("runId" in chunk && typeof chunk.runId === "string") lastRunId = chunk.runId;
|
|
6122
|
-
const model = sseChunkModel(chunk);
|
|
6123
|
-
if (model !== void 0) lastModel = model;
|
|
6915
|
+
const chunk = restoreInboundChunk(JSON.parse(data));
|
|
6124
6916
|
const id = pendingId;
|
|
6125
6917
|
pendingId = void 0;
|
|
6126
6918
|
yield {
|
|
@@ -6135,7 +6927,7 @@ async function assertResponseOk(response) {
|
|
|
6135
6927
|
const body = await response.clone().json().catch(() => null);
|
|
6136
6928
|
if (isByokMissingBody(body)) throw new ByokMissingError(body.error.provider);
|
|
6137
6929
|
}
|
|
6138
|
-
throw new
|
|
6930
|
+
throw new StreamHttpError(`HTTP error! status: ${response.status} ${response.statusText}`, response.status, response.headers.get("retry-after"));
|
|
6139
6931
|
}
|
|
6140
6932
|
function chatHydrationSearchParams(threadId, options) {
|
|
6141
6933
|
const values = { threadId };
|
|
@@ -6216,9 +7008,9 @@ async function fetchGenerationHydration(fetchClient, url, headers, credentials,
|
|
|
6216
7008
|
};
|
|
6217
7009
|
}
|
|
6218
7010
|
/** Yield SSE stream events (chunk + offset) from a fetch Response body. */
|
|
6219
|
-
async function* responseToSSEEvents(response, abortSignal
|
|
7011
|
+
async function* responseToSSEEvents(response, abortSignal) {
|
|
6220
7012
|
await assertResponseOk(response);
|
|
6221
|
-
yield* linesToSSEEvents(readStreamLines(getResponseStreamReader(response), abortSignal)
|
|
7013
|
+
yield* linesToSSEEvents(readStreamLines(getResponseStreamReader(response), abortSignal));
|
|
6222
7014
|
}
|
|
6223
7015
|
async function* responseToSSEChunks(response, abortSignal) {
|
|
6224
7016
|
for await (const { chunk } of responseToSSEEvents(response, abortSignal)) yield chunk;
|
|
@@ -6273,8 +7065,8 @@ async function* resumableStream(openEventSource, abortSignal, reconnectOptions)
|
|
|
6273
7065
|
}
|
|
6274
7066
|
} catch (error) {
|
|
6275
7067
|
if (abortSignal?.aborted) return;
|
|
6276
|
-
if ((error instanceof StreamTruncatedError || error instanceof StreamReadError) && tracker.lastEventId !== void 0) {
|
|
6277
|
-
await tracker.waitBeforeReconnect(progressed, abortSignal);
|
|
7068
|
+
if ((error instanceof StreamTruncatedError || error instanceof StreamReadError || isTemporaryHttpError(error)) && tracker.lastEventId !== void 0) {
|
|
7069
|
+
await tracker.waitBeforeReconnect(progressed, abortSignal, isTemporaryHttpError(error) ? error.retryAfterMs : void 0);
|
|
6278
7070
|
continue;
|
|
6279
7071
|
}
|
|
6280
7072
|
throw error;
|
|
@@ -6372,28 +7164,28 @@ function normalizeConnectionAdapter(connection) {
|
|
|
6372
7164
|
if ("threadId" in chunk && typeof chunk.threadId === "string") upstreamThreadId = chunk.threadId;
|
|
6373
7165
|
if ("runId" in chunk && typeof chunk.runId === "string") upstreamRunId = chunk.runId;
|
|
6374
7166
|
if (chunk.type === "RUN_FINISHED" || chunk.type === "RUN_ERROR") hasTerminalEvent = true;
|
|
6375
|
-
push(chunk, runContext
|
|
7167
|
+
push(chunk, runContext.runId);
|
|
6376
7168
|
}
|
|
6377
7169
|
if (!abortSignal?.aborted && !hasTerminalEvent) push(withTanstackMetadata({
|
|
6378
7170
|
type: EventType.RUN_FINISHED,
|
|
6379
|
-
threadId:
|
|
6380
|
-
runId:
|
|
7171
|
+
threadId: upstreamThreadId ?? runContext.threadId,
|
|
7172
|
+
runId: upstreamRunId ?? runContext.runId,
|
|
6381
7173
|
timestamp: Date.now()
|
|
6382
7174
|
}, {
|
|
6383
7175
|
finishReason: "stop",
|
|
6384
7176
|
model: "connect-wrapper"
|
|
6385
|
-
}), runContext
|
|
7177
|
+
}), runContext.runId);
|
|
6386
7178
|
} catch (err) {
|
|
6387
|
-
if (!abortSignal?.aborted && !hasTerminalEvent)
|
|
7179
|
+
if (!abortSignal?.aborted && !hasTerminalEvent) {
|
|
6388
7180
|
const message = err instanceof Error ? err.message : "Unknown error in connect()";
|
|
6389
7181
|
push({
|
|
6390
7182
|
type: EventType.RUN_ERROR,
|
|
6391
|
-
threadId:
|
|
6392
|
-
runId:
|
|
7183
|
+
threadId: upstreamThreadId ?? runContext.threadId,
|
|
7184
|
+
runId: upstreamRunId ?? runContext.runId,
|
|
6393
7185
|
timestamp: Date.now(),
|
|
6394
7186
|
message
|
|
6395
|
-
}, runContext
|
|
6396
|
-
}
|
|
7187
|
+
}, runContext.runId);
|
|
7188
|
+
}
|
|
6397
7189
|
throw err;
|
|
6398
7190
|
}
|
|
6399
7191
|
await waitUntilSubscriberIdle(abortSignal);
|
|
@@ -6406,23 +7198,23 @@ function normalizeConnectionAdapter(connection) {
|
|
|
6406
7198
|
};
|
|
6407
7199
|
}
|
|
6408
7200
|
function buildRunAgentInputBody(messages, data, runContext, options) {
|
|
7201
|
+
if (!runContext) throw new Error("Connection adapter: connect() and send() need a run context with a threadId. ChatClient and the generation clients pass one. Pass it when you call the adapter yourself.");
|
|
6409
7202
|
const wireMessages = uiMessagesToWire(messages);
|
|
6410
7203
|
const forwardedProps = {
|
|
6411
7204
|
...options.body,
|
|
6412
|
-
...runContext
|
|
7205
|
+
...runContext.forwardedProps,
|
|
6413
7206
|
...data
|
|
6414
7207
|
};
|
|
6415
7208
|
return {
|
|
6416
|
-
threadId: runContext
|
|
6417
|
-
runId: runContext
|
|
6418
|
-
...runContext
|
|
6419
|
-
...runContext
|
|
7209
|
+
threadId: runContext.threadId,
|
|
7210
|
+
runId: runContext.runId,
|
|
7211
|
+
...runContext.parentRunId !== void 0 && { parentRunId: runContext.parentRunId },
|
|
7212
|
+
...runContext.resume !== void 0 && { resume: runContext.resume },
|
|
6420
7213
|
state: {},
|
|
6421
7214
|
messages: wireMessages,
|
|
6422
|
-
tools: runContext
|
|
7215
|
+
tools: runContext.clientTools ?? [],
|
|
6423
7216
|
context: [],
|
|
6424
|
-
forwardedProps
|
|
6425
|
-
data: { ...forwardedProps }
|
|
7217
|
+
forwardedProps
|
|
6426
7218
|
};
|
|
6427
7219
|
}
|
|
6428
7220
|
/**
|
|
@@ -6467,8 +7259,8 @@ function fetchServerSentEvents(url, options = {}) {
|
|
|
6467
7259
|
const requestHeaders = {
|
|
6468
7260
|
"Content-Type": "application/json",
|
|
6469
7261
|
...mergeHeaders(resolvedOptions.headers),
|
|
6470
|
-
...mergeHeaders(runContext
|
|
6471
|
-
...runIdHeader(runContext
|
|
7262
|
+
...mergeHeaders(runContext.headers),
|
|
7263
|
+
...runIdHeader(runContext.runId)
|
|
6472
7264
|
};
|
|
6473
7265
|
const requestBody = buildRunAgentInputBody(messages, data, runContext, resolvedOptions);
|
|
6474
7266
|
const fetchClient = resolvedOptions.fetchClient ?? fetch;
|
|
@@ -6478,10 +7270,7 @@ function fetchServerSentEvents(url, options = {}) {
|
|
|
6478
7270
|
headers: requestHeaders,
|
|
6479
7271
|
body: JSON.stringify(requestBody),
|
|
6480
7272
|
credentials: resolvedOptions.credentials || "same-origin"
|
|
6481
|
-
},
|
|
6482
|
-
...runContext?.threadId !== void 0 ? { threadId: runContext.threadId } : {},
|
|
6483
|
-
...runContext?.runId !== void 0 ? { runId: runContext.runId } : {}
|
|
6484
|
-
})), signal, resolvedOptions.reconnect);
|
|
7273
|
+
}, responseToSSEEvents), signal, resolvedOptions.reconnect);
|
|
6485
7274
|
},
|
|
6486
7275
|
async *joinRun(runId, abortSignal) {
|
|
6487
7276
|
const resolvedUrl = typeof url === "function" ? url() : url;
|
|
@@ -6497,7 +7286,7 @@ function fetchServerSentEvents(url, options = {}) {
|
|
|
6497
7286
|
method: "GET",
|
|
6498
7287
|
headers: requestHeaders,
|
|
6499
7288
|
credentials: resolvedOptions.credentials || "same-origin"
|
|
6500
|
-
},
|
|
7289
|
+
}, responseToSSEEvents), signal, resolvedOptions.reconnect);
|
|
6501
7290
|
},
|
|
6502
7291
|
async hydrate(threadId, hydrateOptions) {
|
|
6503
7292
|
const resolvedUrl = typeof url === "function" ? url() : url;
|
|
@@ -6563,7 +7352,7 @@ async function* abortableIterable(iterable, signal) {
|
|
|
6563
7352
|
}
|
|
6564
7353
|
}
|
|
6565
7354
|
//#endregion
|
|
6566
|
-
//#region ../node_modules/.bun/@tanstack+ai-client@0.
|
|
7355
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/interrupt-manager.js
|
|
6567
7356
|
function isClientOwnedInterrupt(item) {
|
|
6568
7357
|
return item.resumable;
|
|
6569
7358
|
}
|
|
@@ -6586,8 +7375,7 @@ var itemErrorCodes = /* @__PURE__ */ new Set([
|
|
|
6586
7375
|
"unknown-interrupt",
|
|
6587
7376
|
"expired",
|
|
6588
7377
|
"stale",
|
|
6589
|
-
"conflict"
|
|
6590
|
-
"legacy-unsupported"
|
|
7378
|
+
"conflict"
|
|
6591
7379
|
]);
|
|
6592
7380
|
var batchErrorCodes = /* @__PURE__ */ new Set([
|
|
6593
7381
|
"incomplete-batch",
|
|
@@ -6602,27 +7390,11 @@ var batchErrorCodes = /* @__PURE__ */ new Set([
|
|
|
6602
7390
|
"invalid-response-schema",
|
|
6603
7391
|
"expired",
|
|
6604
7392
|
"stale",
|
|
6605
|
-
"conflict"
|
|
6606
|
-
"legacy-submit-failed"
|
|
7393
|
+
"conflict"
|
|
6607
7394
|
]);
|
|
6608
7395
|
function isUnknownObject(value) {
|
|
6609
7396
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6610
7397
|
}
|
|
6611
|
-
function isLegacyApprovalMetadata(value) {
|
|
6612
|
-
return isUnknownObject(value) && value["kind"] === "approval" && typeof value["toolName"] === "string" && "input" in value;
|
|
6613
|
-
}
|
|
6614
|
-
function isLegacyClientToolMetadata(value) {
|
|
6615
|
-
return isUnknownObject(value) && value["kind"] === "client_tool" && typeof value["toolName"] === "string" && "input" in value;
|
|
6616
|
-
}
|
|
6617
|
-
/**
|
|
6618
|
-
* Does this descriptor carry the pre-binding TanStack metadata marker?
|
|
6619
|
-
*
|
|
6620
|
-
* Descriptors emitted before the resume binding existed are still ours to
|
|
6621
|
-
* resume, so they must not be mistaken for another producer's interrupt.
|
|
6622
|
-
*/
|
|
6623
|
-
function isLegacyInterruptMetadata(interrupt) {
|
|
6624
|
-
return isLegacyApprovalMetadata(interrupt.metadata) || isLegacyClientToolMetadata(interrupt.metadata);
|
|
6625
|
-
}
|
|
6626
7398
|
function getDescriptorBinding(interrupt) {
|
|
6627
7399
|
return readInterruptBinding(interrupt);
|
|
6628
7400
|
}
|
|
@@ -6642,13 +7414,6 @@ function hasFirstPartyGenericMarker(interrupt) {
|
|
|
6642
7414
|
function getInterruptPayload(interrupt) {
|
|
6643
7415
|
return interrupt.metadata?.["tanstack:interruptPayload"];
|
|
6644
7416
|
}
|
|
6645
|
-
/**
|
|
6646
|
-
* Only used to route *legacy* (pre-binding) descriptors, which have no binding
|
|
6647
|
-
* to classify off. Current descriptors are classified by their binding alone.
|
|
6648
|
-
*/
|
|
6649
|
-
function isClientToolExecutionReason(reason) {
|
|
6650
|
-
return reason === "tanstack:client_tool_execution" || reason === "client_tool_input";
|
|
6651
|
-
}
|
|
6652
7417
|
function responseSchemaHash(interrupt) {
|
|
6653
7418
|
if (interrupt.responseSchema === void 0) return void 0;
|
|
6654
7419
|
try {
|
|
@@ -6752,7 +7517,6 @@ function genericBinding(interrupt, hydration, candidate) {
|
|
|
6752
7517
|
function baseSnapshot(item, hydration) {
|
|
6753
7518
|
const descriptor = cloneAndDeepFreezeJson(item.descriptor);
|
|
6754
7519
|
const errors = item.error === void 0 ? Object.freeze([]) : Object.freeze([cloneAndDeepFreezeJson(item.error)]);
|
|
6755
|
-
const error = errors[0];
|
|
6756
7520
|
return {
|
|
6757
7521
|
id: descriptor.id,
|
|
6758
7522
|
interruptId: descriptor.id,
|
|
@@ -6766,7 +7530,6 @@ function baseSnapshot(item, hydration) {
|
|
|
6766
7530
|
generation: hydration.generation,
|
|
6767
7531
|
status: item.status,
|
|
6768
7532
|
errors,
|
|
6769
|
-
...error !== void 0 ? { error } : {},
|
|
6770
7533
|
canResolve: item.canResolve
|
|
6771
7534
|
};
|
|
6772
7535
|
}
|
|
@@ -6779,7 +7542,6 @@ var InterruptManager = class {
|
|
|
6779
7542
|
submissionRootErrors = Object.freeze([]);
|
|
6780
7543
|
state = Object.freeze({
|
|
6781
7544
|
interrupts: this.snapshot,
|
|
6782
|
-
pendingInterrupts: this.snapshot,
|
|
6783
7545
|
interruptErrors: this.rootErrors,
|
|
6784
7546
|
resuming: false
|
|
6785
7547
|
});
|
|
@@ -6787,6 +7549,7 @@ var InterruptManager = class {
|
|
|
6787
7549
|
activeSubmissionOperation;
|
|
6788
7550
|
retrySubmission;
|
|
6789
7551
|
resuming = false;
|
|
7552
|
+
warnedSchemaMismatches = /* @__PURE__ */ new Set();
|
|
6790
7553
|
tools;
|
|
6791
7554
|
interruptDefinitions;
|
|
6792
7555
|
constructor(options) {
|
|
@@ -6847,7 +7610,6 @@ var InterruptManager = class {
|
|
|
6847
7610
|
this.resuming = false;
|
|
6848
7611
|
this.state = Object.freeze({
|
|
6849
7612
|
interrupts: this.snapshot,
|
|
6850
|
-
pendingInterrupts: this.snapshot,
|
|
6851
7613
|
interruptErrors: this.rootErrors,
|
|
6852
7614
|
resuming: false
|
|
6853
7615
|
});
|
|
@@ -6905,12 +7667,8 @@ var InterruptManager = class {
|
|
|
6905
7667
|
});
|
|
6906
7668
|
}
|
|
6907
7669
|
resolveClientToolResult(toolCallId, result) {
|
|
6908
|
-
const item = this.items.find((candidate) => candidate.kind === "client-tool-execution" && candidate.binding?.kind === "client-tool-execution" && candidate.binding.toolCallId === toolCallId
|
|
7670
|
+
const item = this.items.find((candidate) => candidate.kind === "client-tool-execution" && candidate.binding?.kind === "client-tool-execution" && candidate.binding.toolCallId === toolCallId) ?? this.items.find((candidate) => candidate.kind === "generic" && candidate.canResolve && candidate.descriptor.toolCallId === toolCallId);
|
|
6909
7671
|
if (!item) return false;
|
|
6910
|
-
if (item.kind !== "client-tool-execution") {
|
|
6911
|
-
this.resolveItem(item.descriptor.id, result.state === "output-error" ? { error: result.errorText } : result.output);
|
|
6912
|
-
return true;
|
|
6913
|
-
}
|
|
6914
7672
|
if (result.state === "output-available") {
|
|
6915
7673
|
this.resolveItem(item.descriptor.id, result.output);
|
|
6916
7674
|
return true;
|
|
@@ -6938,17 +7696,20 @@ var InterruptManager = class {
|
|
|
6938
7696
|
this.publish();
|
|
6939
7697
|
this.maybeSubmit();
|
|
6940
7698
|
}
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
7699
|
+
/**
|
|
7700
|
+
* The local tool exists, but its schemas differ from the hashes the server
|
|
7701
|
+
* put in the binding, so the interrupt falls back to generic. Warn once per
|
|
7702
|
+
* interrupt so the fallback is not silent.
|
|
7703
|
+
*/
|
|
7704
|
+
warnSchemaMismatch(interruptId, toolName, error) {
|
|
7705
|
+
if (this.warnedSchemaMismatches.has(interruptId)) return;
|
|
7706
|
+
this.warnedSchemaMismatches.add(interruptId);
|
|
7707
|
+
console.warn(`[TanStack AI] Interrupt "${interruptId}" for tool "${toolName}": the server and client tool schemas differ, so it is handled as a generic interrupt. Use the same tool definition on the server and the client.`, ...error === void 0 ? [] : [error]);
|
|
6946
7708
|
}
|
|
6947
7709
|
hydrateInterrupt(descriptor, hydration, firstPartyIndexes) {
|
|
6948
7710
|
const interrupt = cloneAndDeepFreezeJson(descriptor);
|
|
6949
7711
|
const candidate = getDescriptorBinding(interrupt);
|
|
6950
|
-
|
|
6951
|
-
if (candidate === void 0 && !legacyResumable) {
|
|
7712
|
+
if (candidate === void 0) {
|
|
6952
7713
|
if (hasReservedFirstPartyBindingMarker(interrupt)) return {
|
|
6953
7714
|
descriptor: interrupt,
|
|
6954
7715
|
binding: genericBinding(interrupt, hydration, void 0),
|
|
@@ -6969,9 +7730,9 @@ var InterruptManager = class {
|
|
|
6969
7730
|
validationGeneration: 0
|
|
6970
7731
|
};
|
|
6971
7732
|
}
|
|
6972
|
-
const correlated = candidate
|
|
6973
|
-
const structurallyCorrelated = candidate
|
|
6974
|
-
if (
|
|
7733
|
+
const correlated = candidate.interruptId === interrupt.id && candidate.interruptedRunId === hydration.interruptedRunId && candidate.generation === hydration.generation && responseSchemaHash(interrupt) === candidate.responseSchemaHash;
|
|
7734
|
+
const structurallyCorrelated = candidate.interruptId === interrupt.id && candidate.interruptedRunId === hydration.interruptedRunId && candidate.generation === hydration.generation && candidate.responseSchemaHash === (responseSchemaHash(interrupt) ?? candidate.responseSchemaHash);
|
|
7735
|
+
if (hasFirstPartyGenericMarker(interrupt) && (!structurallyCorrelated || candidate.kind !== "generic" || candidate.definitionId === void 0 || candidate.key === void 0 || candidate.batchIndex === void 0)) return {
|
|
6975
7736
|
descriptor: interrupt,
|
|
6976
7737
|
binding: genericBinding(interrupt, hydration, candidate),
|
|
6977
7738
|
kind: "generic",
|
|
@@ -6995,22 +7756,28 @@ var InterruptManager = class {
|
|
|
6995
7756
|
tool,
|
|
6996
7757
|
validationGeneration: 0
|
|
6997
7758
|
};
|
|
6998
|
-
|
|
7759
|
+
this.warnSchemaMismatch(interrupt.id, candidate.toolName);
|
|
7760
|
+
} catch (error) {
|
|
7761
|
+
this.warnSchemaMismatch(interrupt.id, candidate.toolName, error);
|
|
7762
|
+
}
|
|
6999
7763
|
}
|
|
7000
7764
|
if (structurallyCorrelated && candidate.kind === "client-tool-execution") {
|
|
7001
7765
|
const tool = this.tools?.find((configured) => configured.name === candidate.toolName);
|
|
7002
|
-
if (tool !== void 0 && interrupt.toolCallId === candidate.toolCallId
|
|
7003
|
-
|
|
7004
|
-
|
|
7005
|
-
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
|
|
7009
|
-
|
|
7010
|
-
|
|
7011
|
-
|
|
7766
|
+
if (tool !== void 0 && interrupt.toolCallId === candidate.toolCallId) {
|
|
7767
|
+
if (hashSchemaInput(tool.outputSchema) === candidate.outputSchemaHash) return {
|
|
7768
|
+
descriptor: interrupt,
|
|
7769
|
+
binding: cloneAndDeepFreezeJson(candidate),
|
|
7770
|
+
kind: "client-tool-execution",
|
|
7771
|
+
status: "pending",
|
|
7772
|
+
canResolve: true,
|
|
7773
|
+
resumable: true,
|
|
7774
|
+
tool,
|
|
7775
|
+
validationGeneration: 0
|
|
7776
|
+
};
|
|
7777
|
+
this.warnSchemaMismatch(interrupt.id, candidate.toolName);
|
|
7778
|
+
}
|
|
7012
7779
|
}
|
|
7013
|
-
if (candidate
|
|
7780
|
+
if (candidate.kind === "generic" && candidate.definitionId !== void 0 && candidate.key !== void 0 && candidate.batchIndex !== void 0 && candidate.key.length > 0 && firstPartyIndexes.get(candidate.batchIndex) !== 1) return {
|
|
7014
7781
|
descriptor: interrupt,
|
|
7015
7782
|
binding: cloneAndDeepFreezeJson(candidate),
|
|
7016
7783
|
kind: "generic",
|
|
@@ -7037,7 +7804,7 @@ var InterruptManager = class {
|
|
|
7037
7804
|
};
|
|
7038
7805
|
}
|
|
7039
7806
|
}
|
|
7040
|
-
const resumable =
|
|
7807
|
+
const resumable = candidate.interruptId === interrupt.id && candidate.interruptedRunId === hydration.interruptedRunId && candidate.generation === hydration.generation && (candidate.kind !== "generic" || responseSchemaHash(interrupt) === void 0 || candidate.responseSchemaHash === responseSchemaHash(interrupt));
|
|
7041
7808
|
return {
|
|
7042
7809
|
descriptor: interrupt,
|
|
7043
7810
|
binding: genericBinding(interrupt, hydration, candidate),
|
|
@@ -7121,7 +7888,6 @@ var InterruptManager = class {
|
|
|
7121
7888
|
this.snapshot = Object.freeze([]);
|
|
7122
7889
|
this.state = Object.freeze({
|
|
7123
7890
|
interrupts: this.snapshot,
|
|
7124
|
-
pendingInterrupts: this.snapshot,
|
|
7125
7891
|
interruptErrors: this.rootErrors,
|
|
7126
7892
|
resuming: this.resuming
|
|
7127
7893
|
});
|
|
@@ -7131,7 +7897,6 @@ var InterruptManager = class {
|
|
|
7131
7897
|
this.snapshot = this.buildSnapshot();
|
|
7132
7898
|
this.state = Object.freeze({
|
|
7133
7899
|
interrupts: this.snapshot,
|
|
7134
|
-
pendingInterrupts: this.snapshot,
|
|
7135
7900
|
interruptErrors: this.rootErrors,
|
|
7136
7901
|
resuming: this.resuming
|
|
7137
7902
|
});
|
|
@@ -7505,7 +8270,7 @@ var InterruptManager = class {
|
|
|
7505
8270
|
}
|
|
7506
8271
|
};
|
|
7507
8272
|
//#endregion
|
|
7508
|
-
//#region ../node_modules/.bun/@tanstack+ai-client@0.
|
|
8273
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/byok/client.js
|
|
7509
8274
|
var registeredProviderIds = /* @__PURE__ */ new WeakMap();
|
|
7510
8275
|
/**
|
|
7511
8276
|
* Provider to stamp when the caller did not pass a slug.
|
|
@@ -7518,7 +8283,7 @@ function byokFallbackProviderId(byok) {
|
|
|
7518
8283
|
if (registered.length === 1) return registered[0];
|
|
7519
8284
|
}
|
|
7520
8285
|
//#endregion
|
|
7521
|
-
//#region ../node_modules/.bun/@tanstack+ai-client@0.
|
|
8286
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/byok/resolve.js
|
|
7522
8287
|
function resolveByokProviderId(byokProvider, ...candidates) {
|
|
7523
8288
|
const fromFn = byokProvider?.();
|
|
7524
8289
|
if (isProviderId(fromFn)) return fromFn;
|
|
@@ -7534,7 +8299,7 @@ async function prepareResolvedByokHeaders(byok, provider) {
|
|
|
7534
8299
|
return byok.headers(provider);
|
|
7535
8300
|
}
|
|
7536
8301
|
//#endregion
|
|
7537
|
-
//#region ../node_modules/.bun/@tanstack+ai-client@0.
|
|
8302
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/events.js
|
|
7538
8303
|
/**
|
|
7539
8304
|
* Abstract base class for ChatClient event emission
|
|
7540
8305
|
*/
|
|
@@ -7690,17 +8455,6 @@ var ChatClientEventEmitter = class {
|
|
|
7690
8455
|
});
|
|
7691
8456
|
}
|
|
7692
8457
|
/**
|
|
7693
|
-
* Emit tool approval responded event
|
|
7694
|
-
*/
|
|
7695
|
-
toolApprovalResponded(approvalId, toolCallId, approved, context) {
|
|
7696
|
-
this.emitEvent("tools:approval:responded", {
|
|
7697
|
-
approvalId,
|
|
7698
|
-
toolCallId,
|
|
7699
|
-
approved,
|
|
7700
|
-
...context
|
|
7701
|
-
});
|
|
7702
|
-
}
|
|
7703
|
-
/**
|
|
7704
8458
|
* Emit tool fixture applied event.
|
|
7705
8459
|
*/
|
|
7706
8460
|
toolFixtureApplied(fixture) {
|
|
@@ -7708,7 +8462,7 @@ var ChatClientEventEmitter = class {
|
|
|
7708
8462
|
}
|
|
7709
8463
|
};
|
|
7710
8464
|
//#endregion
|
|
7711
|
-
//#region ../node_modules/.bun/@tanstack+ai-client@0.
|
|
8465
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/devtools-noop.js
|
|
7712
8466
|
var NoOpChatClientEventEmitter = class extends ChatClientEventEmitter {
|
|
7713
8467
|
emitEvent() {}
|
|
7714
8468
|
};
|
|
@@ -7753,12 +8507,7 @@ var NoOpChatDevtoolsBridge = class {
|
|
|
7753
8507
|
};
|
|
7754
8508
|
var createNoOpChatDevtoolsBridge = (options) => new NoOpChatDevtoolsBridge(options);
|
|
7755
8509
|
//#endregion
|
|
7756
|
-
//#region ../node_modules/.bun/@tanstack+ai-client@0.
|
|
7757
|
-
/** Normalize a raw `getItem` result (legacy bare array or combined record). */
|
|
7758
|
-
function normalizePersistedState(raw) {
|
|
7759
|
-
if (Array.isArray(raw)) return { messages: raw };
|
|
7760
|
-
if (raw && Array.isArray(raw.messages)) return raw;
|
|
7761
|
-
}
|
|
8510
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/client-persistor.js
|
|
7762
8511
|
function getChunkToolCallId$1(chunk) {
|
|
7763
8512
|
return "toolCallId" in chunk && typeof chunk.toolCallId === "string" ? chunk.toolCallId : void 0;
|
|
7764
8513
|
}
|
|
@@ -7800,6 +8549,7 @@ var ChatPersistor = class {
|
|
|
7800
8549
|
messagesGeneration = 0;
|
|
7801
8550
|
lastMessages = [];
|
|
7802
8551
|
lastResume = null;
|
|
8552
|
+
legacyStored = false;
|
|
7803
8553
|
clearedMessageIds = /* @__PURE__ */ new Set();
|
|
7804
8554
|
clearedRunIds = /* @__PURE__ */ new Set();
|
|
7805
8555
|
ignoredActiveRunIds = /* @__PURE__ */ new Set();
|
|
@@ -7813,6 +8563,7 @@ var ChatPersistor = class {
|
|
|
7813
8563
|
}
|
|
7814
8564
|
/** Persist the current state as one combined `{ messages, resume? }` record. */
|
|
7815
8565
|
writeState() {
|
|
8566
|
+
if (this.legacyStored) return;
|
|
7816
8567
|
const messages = [...this.lastMessages];
|
|
7817
8568
|
if (messages.length === 0 && !this.lastResume) {
|
|
7818
8569
|
const generation = this.generation;
|
|
@@ -7832,6 +8583,15 @@ var ChatPersistor = class {
|
|
|
7832
8583
|
return this.adapter.setItem(this.id, state);
|
|
7833
8584
|
});
|
|
7834
8585
|
}
|
|
8586
|
+
/** Validate a raw `getItem` result. */
|
|
8587
|
+
normalize(raw) {
|
|
8588
|
+
if (Array.isArray(raw)) {
|
|
8589
|
+
this.legacyStored = true;
|
|
8590
|
+
console.error(`[TanStack AI] The stored chat for threadId "${this.id}" is in the 0.x format (a bare message array). TanStack AI 1.0 does not read this format, so the chat starts empty and the stored value is not overwritten. Clear the chat or the stored value to start saving again.`);
|
|
8591
|
+
return;
|
|
8592
|
+
}
|
|
8593
|
+
if (raw && Array.isArray(raw.messages)) return raw;
|
|
8594
|
+
}
|
|
7835
8595
|
/**
|
|
7836
8596
|
* Synchronously read the persisted state for constructor-time hydration.
|
|
7837
8597
|
* Returns the normalized combined record, or a promise of it for async stores.
|
|
@@ -7839,8 +8599,8 @@ var ChatPersistor = class {
|
|
|
7839
8599
|
readInitial() {
|
|
7840
8600
|
try {
|
|
7841
8601
|
const raw = this.adapter.getItem(this.id);
|
|
7842
|
-
if (raw instanceof Promise) return raw.then(
|
|
7843
|
-
const state =
|
|
8602
|
+
if (raw instanceof Promise) return raw.then((value) => this.normalize(value)).catch(() => void 0);
|
|
8603
|
+
const state = this.normalize(raw);
|
|
7844
8604
|
if (state) {
|
|
7845
8605
|
this.lastMessages = state.messages;
|
|
7846
8606
|
this.lastResume = state.resume ?? null;
|
|
@@ -7892,6 +8652,7 @@ var ChatPersistor = class {
|
|
|
7892
8652
|
}
|
|
7893
8653
|
/** Remove the persisted conversation. Invalidates any queued writes. */
|
|
7894
8654
|
remove() {
|
|
8655
|
+
this.legacyStored = false;
|
|
7895
8656
|
this.lastMessages = [];
|
|
7896
8657
|
this.lastResume = null;
|
|
7897
8658
|
const generation = ++this.generation;
|
|
@@ -8018,7 +8779,7 @@ var ChatPersistor = class {
|
|
|
8018
8779
|
}
|
|
8019
8780
|
};
|
|
8020
8781
|
//#endregion
|
|
8021
|
-
//#region ../node_modules/.bun/@tanstack+ai-client@0.
|
|
8782
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/cleared-stream-tracker.js
|
|
8022
8783
|
function getChunkToolCallId(chunk) {
|
|
8023
8784
|
return "toolCallId" in chunk && typeof chunk.toolCallId === "string" ? chunk.toolCallId : void 0;
|
|
8024
8785
|
}
|
|
@@ -8111,7 +8872,7 @@ var ClearedStreamTracker = class {
|
|
|
8111
8872
|
}
|
|
8112
8873
|
};
|
|
8113
8874
|
//#endregion
|
|
8114
|
-
//#region ../node_modules/.bun/@tanstack+ai-client@0.
|
|
8875
|
+
//#region ../node_modules/.bun/@tanstack+ai-client@1.0.0+367daa2260c029d6/node_modules/@tanstack/ai-client/dist/esm/chat-client.js
|
|
8115
8876
|
var STREAM_PROCESSING_BUDGET_MS = 8;
|
|
8116
8877
|
function yieldToHost() {
|
|
8117
8878
|
const { scheduler } = globalThis;
|
|
@@ -8257,9 +9018,30 @@ var REJOIN_REBUILD_TRIGGERS = /* @__PURE__ */ new Set([
|
|
|
8257
9018
|
]);
|
|
8258
9019
|
function rebuildsAssistantMessage(chunk) {
|
|
8259
9020
|
if (chunk.type === "REASONING_ENCRYPTED_VALUE") return chunk.subtype === "message" && typeof chunk.encryptedValue === "string" && chunk.encryptedValue.length > 0;
|
|
8260
|
-
if (chunk.type === "STEP_FINISHED") return "signature" in chunk && Boolean(chunk.signature);
|
|
8261
9021
|
return REJOIN_REBUILD_TRIGGERS.has(chunk.type);
|
|
8262
9022
|
}
|
|
9023
|
+
/**
|
|
9024
|
+
* Snapshot messages are frozen, and a host can pass them back in
|
|
9025
|
+
* (`setMessagesManually(snapshot.messages)`, `initialMessages`). The client
|
|
9026
|
+
* writes subagent handles into message parts, nested cards included, so copy
|
|
9027
|
+
* each frozen part down through subagent transcripts.
|
|
9028
|
+
*/
|
|
9029
|
+
function thawMessages(messages) {
|
|
9030
|
+
return messages.map((message) => ({
|
|
9031
|
+
...message,
|
|
9032
|
+
parts: message.parts.map((part) => {
|
|
9033
|
+
if (!Object.isFrozen(part)) return part;
|
|
9034
|
+
if (part.type !== "subagent") return { ...part };
|
|
9035
|
+
return {
|
|
9036
|
+
...part,
|
|
9037
|
+
subagent: {
|
|
9038
|
+
...part.subagent,
|
|
9039
|
+
messages: thawMessages(part.subagent.messages)
|
|
9040
|
+
}
|
|
9041
|
+
};
|
|
9042
|
+
})
|
|
9043
|
+
}));
|
|
9044
|
+
}
|
|
8263
9045
|
/** Every subagent card in the messages, nested cards included. */
|
|
8264
9046
|
function collectSubagentParts(messages) {
|
|
8265
9047
|
const cards = [];
|
|
@@ -8287,11 +9069,54 @@ var ChatClient = class {
|
|
|
8287
9069
|
subagentHandles = /* @__PURE__ */ new Map();
|
|
8288
9070
|
stoppedSubagentIds = /* @__PURE__ */ new Set();
|
|
8289
9071
|
connection;
|
|
8290
|
-
uniqueId;
|
|
8291
9072
|
threadId;
|
|
8292
9073
|
persistor;
|
|
8293
9074
|
clearedStreamTracker = new ClearedStreamTracker();
|
|
8294
|
-
|
|
9075
|
+
snapshotAtom = createAtom({
|
|
9076
|
+
messages: [],
|
|
9077
|
+
status: "ready",
|
|
9078
|
+
isLoading: false,
|
|
9079
|
+
error: void 0,
|
|
9080
|
+
isSubscribed: false,
|
|
9081
|
+
connectionStatus: "disconnected",
|
|
9082
|
+
sessionGenerating: false,
|
|
9083
|
+
queue: [],
|
|
9084
|
+
runId: null,
|
|
9085
|
+
hasOlderMessages: false,
|
|
9086
|
+
isHydrating: false,
|
|
9087
|
+
interruptState: {
|
|
9088
|
+
interrupts: Object.freeze([]),
|
|
9089
|
+
interruptErrors: Object.freeze([]),
|
|
9090
|
+
resuming: false
|
|
9091
|
+
}
|
|
9092
|
+
});
|
|
9093
|
+
get status() {
|
|
9094
|
+
return this.snapshotAtom.get().status;
|
|
9095
|
+
}
|
|
9096
|
+
get isLoading() {
|
|
9097
|
+
return this.snapshotAtom.get().isLoading;
|
|
9098
|
+
}
|
|
9099
|
+
get error() {
|
|
9100
|
+
return this.snapshotAtom.get().error;
|
|
9101
|
+
}
|
|
9102
|
+
get isSubscribed() {
|
|
9103
|
+
return this.snapshotAtom.get().isSubscribed;
|
|
9104
|
+
}
|
|
9105
|
+
get connectionStatus() {
|
|
9106
|
+
return this.snapshotAtom.get().connectionStatus;
|
|
9107
|
+
}
|
|
9108
|
+
get sessionGenerating() {
|
|
9109
|
+
return this.snapshotAtom.get().sessionGenerating;
|
|
9110
|
+
}
|
|
9111
|
+
get hasOlderMessages() {
|
|
9112
|
+
return this.snapshotAtom.get().hasOlderMessages;
|
|
9113
|
+
}
|
|
9114
|
+
get isHydrating() {
|
|
9115
|
+
return this.snapshotAtom.get().isHydrating;
|
|
9116
|
+
}
|
|
9117
|
+
get currentRunId() {
|
|
9118
|
+
return this.snapshotAtom.get().runId;
|
|
9119
|
+
}
|
|
8295
9120
|
lastResume = null;
|
|
8296
9121
|
runParents = /* @__PURE__ */ new Map();
|
|
8297
9122
|
supersededInterruptRunIds = /* @__PURE__ */ new Set();
|
|
@@ -8305,7 +9130,6 @@ var ChatClient = class {
|
|
|
8305
9130
|
pendingResumeItems = null;
|
|
8306
9131
|
activeResumeThreadId = null;
|
|
8307
9132
|
activeResumeRunId = null;
|
|
8308
|
-
bodyOption = {};
|
|
8309
9133
|
forwardedPropsOption = {};
|
|
8310
9134
|
byok;
|
|
8311
9135
|
byokProvider;
|
|
@@ -8336,11 +9160,6 @@ var ChatClient = class {
|
|
|
8336
9160
|
* deliverers cannot both append a user message before only one stream runs.
|
|
8337
9161
|
*/
|
|
8338
9162
|
deliverClaim = false;
|
|
8339
|
-
isLoading = false;
|
|
8340
|
-
isSubscribed = false;
|
|
8341
|
-
error = void 0;
|
|
8342
|
-
status = "ready";
|
|
8343
|
-
connectionStatus = "disconnected";
|
|
8344
9163
|
abortController = null;
|
|
8345
9164
|
clientToolsRef;
|
|
8346
9165
|
devtoolsBridge;
|
|
@@ -8373,7 +9192,6 @@ var ChatClient = class {
|
|
|
8373
9192
|
streamContinuationGeneration = 0;
|
|
8374
9193
|
continuationSkipped = false;
|
|
8375
9194
|
draining = false;
|
|
8376
|
-
sessionGenerating = false;
|
|
8377
9195
|
activeRunIds = /* @__PURE__ */ new Set();
|
|
8378
9196
|
/** Latched by `dispose()`; stops any late async callback starting new work. */
|
|
8379
9197
|
disposed = false;
|
|
@@ -8385,8 +9203,6 @@ var ChatClient = class {
|
|
|
8385
9203
|
hydrationInFlight;
|
|
8386
9204
|
/** An async storage adapter is still reading the persisted transcript. */
|
|
8387
9205
|
storeHydrating = false;
|
|
8388
|
-
/** See {@link getIsHydrating}. */
|
|
8389
|
-
isHydrating = false;
|
|
8390
9206
|
/** Constructor inputs `attach()` needs on every re-attach, not just the first. */
|
|
8391
9207
|
rejoinRunId;
|
|
8392
9208
|
cachesMessages;
|
|
@@ -8395,7 +9211,6 @@ var ChatClient = class {
|
|
|
8395
9211
|
* `persistence === true`.
|
|
8396
9212
|
*/
|
|
8397
9213
|
historyPageSize;
|
|
8398
|
-
hasOlderMessages = false;
|
|
8399
9214
|
olderMessagesCursor;
|
|
8400
9215
|
knownServerMessageIds = /* @__PURE__ */ new Set();
|
|
8401
9216
|
loadOlderMessagesInFlight = false;
|
|
@@ -8404,19 +9219,16 @@ var ChatClient = class {
|
|
|
8404
9219
|
callbacksRef;
|
|
8405
9220
|
constructor(options) {
|
|
8406
9221
|
assertUniqueInterruptDefinitions(options.interrupts);
|
|
8407
|
-
|
|
8408
|
-
this.
|
|
9222
|
+
if (typeof options.threadId !== "string" || options.threadId === "") throw new Error("ChatClient: threadId is required (a non-empty string).");
|
|
9223
|
+
this.threadId = options.threadId;
|
|
8409
9224
|
let cachesMessages = true;
|
|
8410
9225
|
if (options.persistence === true) {
|
|
8411
|
-
if (!options.threadId) throw new Error("[TanStack AI] persistence needs a stable `threadId` to key on. Pass a threadId from your app (for example support-42).");
|
|
8412
9226
|
cachesMessages = false;
|
|
8413
9227
|
this.historyPageSize = options.history?.pageSize;
|
|
8414
9228
|
} else if (options.persistence) {
|
|
8415
|
-
if (!options.threadId) throw new Error("[TanStack AI] persistence needs a stable `threadId` to key on. Pass a threadId from your app (for example support-42).");
|
|
8416
9229
|
this.persistor = new ChatPersistor(options.persistence, options.threadId, (messages) => this.processor.setMessages(messages), (snapshot) => this.applyPersistedResume(snapshot));
|
|
8417
9230
|
this.historyPageSize = void 0;
|
|
8418
9231
|
} else this.historyPageSize = void 0;
|
|
8419
|
-
this.bodyOption = options.body || {};
|
|
8420
9232
|
this.forwardedPropsOption = options.forwardedProps || {};
|
|
8421
9233
|
this.byok = options.byok;
|
|
8422
9234
|
this.byokProvider = options.byokProvider;
|
|
@@ -8457,7 +9269,7 @@ var ChatClient = class {
|
|
|
8457
9269
|
if (options.initialResumeSnapshot) this.applyResumeSnapshot(options.initialResumeSnapshot);
|
|
8458
9270
|
const persistedState = this.persistor?.readInitial();
|
|
8459
9271
|
const syncPersistedState = persistedState instanceof Promise ? void 0 : persistedState;
|
|
8460
|
-
const initialMessages = syncPersistedState ? syncPersistedState.messages : options.initialMessages;
|
|
9272
|
+
const initialMessages = syncPersistedState ? syncPersistedState.messages : options.initialMessages && thawMessages(options.initialMessages);
|
|
8461
9273
|
let rejoinRunId = null;
|
|
8462
9274
|
if (syncPersistedState?.resume) {
|
|
8463
9275
|
const snapshot = syncPersistedState.resume;
|
|
@@ -8475,6 +9287,7 @@ var ChatClient = class {
|
|
|
8475
9287
|
onMessagesChange: (messages) => {
|
|
8476
9288
|
this.syncSubagentHandles();
|
|
8477
9289
|
this.persistor?.notifyMessagesChanged(messages);
|
|
9290
|
+
patchAtom(this.snapshotAtom, { messages: freezeSnapshotMessages(this.frozenMessages, messages) });
|
|
8478
9291
|
this.callbacksRef.current.onMessagesChange(messages);
|
|
8479
9292
|
this.queueDevtoolsSnapshot();
|
|
8480
9293
|
},
|
|
@@ -8535,6 +9348,7 @@ var ChatClient = class {
|
|
|
8535
9348
|
const context = this.activeClientTools === null ? this.context : this.activeContext;
|
|
8536
9349
|
const output = await executeFunc(args.input, {
|
|
8537
9350
|
toolCallId: args.toolCallId,
|
|
9351
|
+
threadId: this.threadId,
|
|
8538
9352
|
context,
|
|
8539
9353
|
emitCustomEvent: () => {}
|
|
8540
9354
|
});
|
|
@@ -8583,7 +9397,7 @@ var ChatClient = class {
|
|
|
8583
9397
|
}
|
|
8584
9398
|
this.rejoinRunId = rejoinRunId;
|
|
8585
9399
|
this.cachesMessages = cachesMessages;
|
|
8586
|
-
this.
|
|
9400
|
+
this.snapshotAtom.set(this.readSnapshot(this.storeHydrating || !cachesMessages && !!this.connection.hydrate));
|
|
8587
9401
|
}
|
|
8588
9402
|
/**
|
|
8589
9403
|
* START TAILING: re-attach to an in-flight run so its chunks arrive here.
|
|
@@ -8602,7 +9416,6 @@ var ChatClient = class {
|
|
|
8602
9416
|
*/
|
|
8603
9417
|
attach() {
|
|
8604
9418
|
if (this.disposed || this.tailing) return;
|
|
8605
|
-
this.ensureThreadId();
|
|
8606
9419
|
this.tailing = true;
|
|
8607
9420
|
if (this.rejoinRunId) this.maybeRejoinInFlight(this.rejoinRunId);
|
|
8608
9421
|
if (!this.cachesMessages && this.connection.hydrate) this.hydrateFromServer();
|
|
@@ -8757,16 +9570,10 @@ var ChatClient = class {
|
|
|
8757
9570
|
this.callbacksRef.current.onError(error);
|
|
8758
9571
|
}
|
|
8759
9572
|
mountDevtools() {
|
|
8760
|
-
this.ensureThreadId();
|
|
8761
9573
|
if (this.devtoolsMounted) return;
|
|
8762
9574
|
this.devtoolsMounted = true;
|
|
8763
9575
|
this.devtoolsBridge.mountWithTools(this.processor.getMessages().length);
|
|
8764
9576
|
}
|
|
8765
|
-
ensureThreadId() {
|
|
8766
|
-
if (!this.threadId) this.threadId = this.generateUniqueId("thread");
|
|
8767
|
-
this.uniqueId = this.threadId;
|
|
8768
|
-
return this.threadId;
|
|
8769
|
-
}
|
|
8770
9577
|
/**
|
|
8771
9578
|
* Drain a runId-less RUN_ERROR that belongs to a cleared run the client is
|
|
8772
9579
|
* still tracking. The persistor owns the cleared-run bookkeeping; the client
|
|
@@ -8901,7 +9708,7 @@ var ChatClient = class {
|
|
|
8901
9708
|
}
|
|
8902
9709
|
setCurrentRunId(runId) {
|
|
8903
9710
|
if (this.currentRunId === runId) return;
|
|
8904
|
-
this.
|
|
9711
|
+
patchAtom(this.snapshotAtom, { runId });
|
|
8905
9712
|
this.callbacksRef.current.onRunIdChange(runId);
|
|
8906
9713
|
}
|
|
8907
9714
|
getInterruptState() {
|
|
@@ -8910,10 +9717,6 @@ var ChatClient = class {
|
|
|
8910
9717
|
getInterrupts() {
|
|
8911
9718
|
return this.interruptManager.getInterrupts();
|
|
8912
9719
|
}
|
|
8913
|
-
/** @deprecated Use getInterrupts(). */
|
|
8914
|
-
getPendingInterrupts() {
|
|
8915
|
-
return this.interruptManager.getInterrupts();
|
|
8916
|
-
}
|
|
8917
9720
|
resolveInterrupts(resolution) {
|
|
8918
9721
|
if (typeof resolution === "boolean") {
|
|
8919
9722
|
this.interruptManager.resolve(resolution);
|
|
@@ -8949,10 +9752,6 @@ var ChatClient = class {
|
|
|
8949
9752
|
this.pendingResumeItems = [...resume];
|
|
8950
9753
|
return this.streamResponse();
|
|
8951
9754
|
}
|
|
8952
|
-
/** @deprecated Use bound interrupt methods or resumeInterruptsUnsafe(). */
|
|
8953
|
-
resumeInterrupts(resume, state) {
|
|
8954
|
-
return this.resumeInterruptsUnsafe(resume, state);
|
|
8955
|
-
}
|
|
8956
9755
|
async submitInterruptBatch(submission) {
|
|
8957
9756
|
const continuationGeneration = this.continuationGeneration;
|
|
8958
9757
|
this.activeInterruptSubmission = submission;
|
|
@@ -8996,8 +9795,45 @@ var ChatClient = class {
|
|
|
8996
9795
|
generateUniqueId(prefix) {
|
|
8997
9796
|
return `${prefix}-${Date.now()}-${Math.random().toString(36).substring(7)}`;
|
|
8998
9797
|
}
|
|
9798
|
+
/** Frozen copies of unchanged messages and parts, keyed by the live object. */
|
|
9799
|
+
frozenMessages = /* @__PURE__ */ new WeakMap();
|
|
9800
|
+
freezeSnapshotQueue(queue) {
|
|
9801
|
+
return Object.freeze(queue.map((item) => {
|
|
9802
|
+
if (typeof item.content !== "object") return Object.freeze({ ...item });
|
|
9803
|
+
const content = Array.isArray(item.content.content) ? Object.freeze(item.content.content.map((part) => freezeSnapshotPart(part))) : item.content.content;
|
|
9804
|
+
return Object.freeze({
|
|
9805
|
+
...item,
|
|
9806
|
+
content: Object.freeze({
|
|
9807
|
+
...item.content,
|
|
9808
|
+
content
|
|
9809
|
+
})
|
|
9810
|
+
});
|
|
9811
|
+
}));
|
|
9812
|
+
}
|
|
9813
|
+
/** The atom with messages, queue, and interrupt state read fresh. */
|
|
9814
|
+
readSnapshot(isHydrating) {
|
|
9815
|
+
return Object.freeze({
|
|
9816
|
+
...this.snapshotAtom.get(),
|
|
9817
|
+
messages: freezeSnapshotMessages(this.frozenMessages, this.processor.getMessages()),
|
|
9818
|
+
queue: this.freezeSnapshotQueue(this.getQueue()),
|
|
9819
|
+
isHydrating,
|
|
9820
|
+
interruptState: this.interruptManager.getState()
|
|
9821
|
+
});
|
|
9822
|
+
}
|
|
9823
|
+
/**
|
|
9824
|
+
* Subscribe to UI snapshot changes. Does not fire with the current value;
|
|
9825
|
+
* read {@link getSnapshot} first.
|
|
9826
|
+
*
|
|
9827
|
+
* Named separately from {@link subscribe} (the live connection loop).
|
|
9828
|
+
*/
|
|
9829
|
+
subscribeSnapshot = (listener) => subscribeAtom(this.snapshotAtom, listener);
|
|
9830
|
+
/**
|
|
9831
|
+
* Current UI snapshot. The snapshot, `messages`, `queue`, and their entries
|
|
9832
|
+
* are frozen copies. `interruptState` is the interrupt manager's own state.
|
|
9833
|
+
*/
|
|
9834
|
+
getSnapshot = () => this.snapshotAtom.get();
|
|
8999
9835
|
setIsLoading(isLoading) {
|
|
9000
|
-
this.
|
|
9836
|
+
patchAtom(this.snapshotAtom, { isLoading });
|
|
9001
9837
|
this.callbacksRef.current.onLoadingChange(isLoading);
|
|
9002
9838
|
this.events.loadingChanged(isLoading);
|
|
9003
9839
|
if (isLoading) this.supersedeHydration();
|
|
@@ -9013,35 +9849,36 @@ var ChatClient = class {
|
|
|
9013
9849
|
this.syncIsHydrating();
|
|
9014
9850
|
}
|
|
9015
9851
|
setStatus(status) {
|
|
9016
|
-
this.
|
|
9852
|
+
patchAtom(this.snapshotAtom, { status });
|
|
9017
9853
|
this.callbacksRef.current.onStatusChange(status);
|
|
9018
9854
|
this.devtoolsBridge.emitSnapshot();
|
|
9019
9855
|
}
|
|
9020
9856
|
setIsSubscribed(isSubscribed) {
|
|
9021
|
-
this.
|
|
9857
|
+
patchAtom(this.snapshotAtom, { isSubscribed });
|
|
9022
9858
|
this.callbacksRef.current.onSubscriptionChange(isSubscribed);
|
|
9023
9859
|
this.devtoolsBridge.emitSnapshot();
|
|
9024
9860
|
}
|
|
9025
9861
|
setConnectionStatus(status) {
|
|
9026
|
-
this.connectionStatus
|
|
9862
|
+
patchAtom(this.snapshotAtom, { connectionStatus: status });
|
|
9027
9863
|
this.callbacksRef.current.onConnectionStatusChange(status);
|
|
9028
9864
|
this.devtoolsBridge.emitSnapshot();
|
|
9029
9865
|
}
|
|
9030
9866
|
syncIsHydrating() {
|
|
9031
9867
|
const isHydrating = this.hydrationInFlight !== void 0 || this.storeHydrating;
|
|
9032
9868
|
if (this.isHydrating === isHydrating) return;
|
|
9033
|
-
this.
|
|
9869
|
+
patchAtom(this.snapshotAtom, { isHydrating });
|
|
9034
9870
|
this.callbacksRef.current.onHydratingChange(isHydrating);
|
|
9035
9871
|
}
|
|
9036
9872
|
setSessionGenerating(isGenerating) {
|
|
9037
9873
|
if (this.sessionGenerating === isGenerating) return;
|
|
9038
|
-
this.sessionGenerating
|
|
9874
|
+
patchAtom(this.snapshotAtom, { sessionGenerating: isGenerating });
|
|
9039
9875
|
this.callbacksRef.current.onSessionGeneratingChange(isGenerating);
|
|
9040
9876
|
this.devtoolsBridge.emitSnapshot();
|
|
9041
9877
|
}
|
|
9042
9878
|
notifyResumeStateChange(source) {
|
|
9043
9879
|
const resumeState = this.getResumeState();
|
|
9044
9880
|
const interruptState = this.interruptManager.getState();
|
|
9881
|
+
patchAtom(this.snapshotAtom, { interruptState });
|
|
9045
9882
|
this.persistResumeSnapshot(resumeState);
|
|
9046
9883
|
this.callbacksRef.current.onResumeStateChange(resumeState, interruptState.interrupts);
|
|
9047
9884
|
this.callbacksRef.current.onInterruptStateChange(interruptState, { source });
|
|
@@ -9068,22 +9905,15 @@ var ChatClient = class {
|
|
|
9068
9905
|
this.setSessionGenerating(false);
|
|
9069
9906
|
}
|
|
9070
9907
|
setError(error) {
|
|
9071
|
-
this.
|
|
9908
|
+
patchAtom(this.snapshotAtom, { error });
|
|
9072
9909
|
this.callbacksRef.current.onErrorChange(error);
|
|
9073
9910
|
this.events.errorChanged(error?.message || null);
|
|
9074
9911
|
}
|
|
9075
9912
|
buildDevtoolsBridgeOptions(devtools) {
|
|
9076
|
-
const client = this;
|
|
9077
9913
|
return {
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
|
|
9081
|
-
get clientId() {
|
|
9082
|
-
return client.uniqueId;
|
|
9083
|
-
},
|
|
9084
|
-
get threadId() {
|
|
9085
|
-
return client.threadId;
|
|
9086
|
-
},
|
|
9914
|
+
hookId: this.threadId,
|
|
9915
|
+
clientId: this.threadId,
|
|
9916
|
+
threadId: this.threadId,
|
|
9087
9917
|
metadata: {
|
|
9088
9918
|
hookName: devtools?.hookName ?? "useChat",
|
|
9089
9919
|
outputKind: devtools?.outputKind ?? "chat",
|
|
@@ -9357,12 +10187,13 @@ var ChatClient = class {
|
|
|
9357
10187
|
* @param content - The message content. Can be:
|
|
9358
10188
|
* - A simple string for text-only messages
|
|
9359
10189
|
* - A MultimodalContent object with content array and optional custom ID
|
|
9360
|
-
* @param body - Optional body parameters to merge
|
|
9361
|
-
*
|
|
10190
|
+
* @param body - Optional body parameters to merge into this request's
|
|
10191
|
+
* forwardedProps, over the forwardedProps option. Uses
|
|
10192
|
+
* shallow merge with per-message body taking priority.
|
|
9362
10193
|
* @param sendOptions - Per-call overrides. `{ whenBusy }` overrides the
|
|
9363
10194
|
* queue policy for this one send. `{ body }`
|
|
9364
10195
|
* shallow-merges with `body` and with the chat-level
|
|
9365
|
-
* `
|
|
10196
|
+
* `forwardedProps`. `sendOptions.body` wins
|
|
9366
10197
|
* on key collisions. Framework hooks forward this
|
|
9367
10198
|
* object as their second argument.
|
|
9368
10199
|
*
|
|
@@ -9405,7 +10236,7 @@ var ChatClient = class {
|
|
|
9405
10236
|
async sendMessage(content, body, sendOptions) {
|
|
9406
10237
|
this.mountDevtools();
|
|
9407
10238
|
if (typeof content === "string" && !content.trim()) return;
|
|
9408
|
-
if (this.hasPendingInterrupts()) throw new Error("ChatClient: cannot send normal input while pending interrupts exist.
|
|
10239
|
+
if (this.hasPendingInterrupts()) throw new Error("ChatClient: cannot send normal input while pending interrupts exist. Resolve the interrupts first.");
|
|
9409
10240
|
const resolvedBody = {
|
|
9410
10241
|
...body,
|
|
9411
10242
|
...sendOptions?.body
|
|
@@ -9523,7 +10354,7 @@ var ChatClient = class {
|
|
|
9523
10354
|
*/
|
|
9524
10355
|
async append(message) {
|
|
9525
10356
|
this.mountDevtools();
|
|
9526
|
-
if (this.hasPendingInterrupts()) throw new Error("ChatClient: cannot append normal input while pending interrupts exist.
|
|
10357
|
+
if (this.hasPendingInterrupts()) throw new Error("ChatClient: cannot append normal input while pending interrupts exist. Resolve the interrupts first.");
|
|
9527
10358
|
const normalizedMessage = normalizeToUIMessage(message, generateMessageId);
|
|
9528
10359
|
if (normalizedMessage.role === "system") return;
|
|
9529
10360
|
if (normalizedMessage.role === "activity") {
|
|
@@ -9583,7 +10414,6 @@ var ChatClient = class {
|
|
|
9583
10414
|
await this.callbacksRef.current.onResponse();
|
|
9584
10415
|
if (signal.aborted) return false;
|
|
9585
10416
|
const mergedBody = {
|
|
9586
|
-
...this.bodyOption,
|
|
9587
10417
|
...this.forwardedPropsOption,
|
|
9588
10418
|
...this.pendingMessageBody
|
|
9589
10419
|
};
|
|
@@ -9802,31 +10632,6 @@ var ChatClient = class {
|
|
|
9802
10632
|
return validation.data;
|
|
9803
10633
|
}
|
|
9804
10634
|
/**
|
|
9805
|
-
* Respond to a tool approval request
|
|
9806
|
-
*/
|
|
9807
|
-
async addToolApprovalResponse(response) {
|
|
9808
|
-
this.processor.addToolApprovalResponse(response.id, response.approved);
|
|
9809
|
-
this.devtoolsBridge.emitSnapshot();
|
|
9810
|
-
if (this.interruptManager.resolveToolApprovalDecision(response.id, response.approved)) return;
|
|
9811
|
-
const messages = this.processor.getMessages();
|
|
9812
|
-
let foundToolCallId;
|
|
9813
|
-
for (const msg of messages) {
|
|
9814
|
-
const toolCallPart = msg.parts.find((p) => p.type === "tool-call" && p.approval?.id === response.id);
|
|
9815
|
-
if (toolCallPart) {
|
|
9816
|
-
foundToolCallId = toolCallPart.id;
|
|
9817
|
-
break;
|
|
9818
|
-
}
|
|
9819
|
-
}
|
|
9820
|
-
if (foundToolCallId) this.events.toolApprovalResponded(response.id, foundToolCallId, response.approved);
|
|
9821
|
-
this.processor.addToolApprovalResponse(response.id, response.approved);
|
|
9822
|
-
this.devtoolsBridge.emitSnapshot();
|
|
9823
|
-
if (this.isLoading) {
|
|
9824
|
-
this.queuePostStreamAction(() => this.checkForContinuation());
|
|
9825
|
-
return;
|
|
9826
|
-
}
|
|
9827
|
-
await this.checkForContinuation();
|
|
9828
|
-
}
|
|
9829
|
-
/**
|
|
9830
10635
|
* Queue an action to be executed after the current stream ends
|
|
9831
10636
|
*/
|
|
9832
10637
|
queuePostStreamAction(action) {
|
|
@@ -9908,6 +10713,14 @@ var ChatClient = class {
|
|
|
9908
10713
|
});
|
|
9909
10714
|
}
|
|
9910
10715
|
syncSubagentHandles() {
|
|
10716
|
+
const fieldsOf = (subagent) => {
|
|
10717
|
+
const { input: _old, ...card } = subagent;
|
|
10718
|
+
const input = subagentInputOf(card.metadata);
|
|
10719
|
+
return input === void 0 ? card : {
|
|
10720
|
+
...card,
|
|
10721
|
+
input
|
|
10722
|
+
};
|
|
10723
|
+
};
|
|
9911
10724
|
const cards = collectSubagentParts(this.processor.getMessages());
|
|
9912
10725
|
const present = new Set(cards.map((part) => part.subagent.id));
|
|
9913
10726
|
for (const id of this.subagentHandles.keys()) if (!present.has(id)) this.subagentHandles.delete(id);
|
|
@@ -9918,12 +10731,12 @@ var ChatClient = class {
|
|
|
9918
10731
|
if (part.subagent === existing) continue;
|
|
9919
10732
|
const { stop } = existing;
|
|
9920
10733
|
for (const key of Object.keys(existing)) Reflect.deleteProperty(existing, key);
|
|
9921
|
-
Object.assign(existing, part.subagent, { stop });
|
|
10734
|
+
Object.assign(existing, fieldsOf(part.subagent), { stop });
|
|
9922
10735
|
part.subagent = existing;
|
|
9923
10736
|
continue;
|
|
9924
10737
|
}
|
|
9925
10738
|
const handle = {
|
|
9926
|
-
...part.subagent,
|
|
10739
|
+
...fieldsOf(part.subagent),
|
|
9927
10740
|
stop: () => {
|
|
9928
10741
|
this.stopSubagent(id);
|
|
9929
10742
|
}
|
|
@@ -9985,19 +10798,22 @@ var ChatClient = class {
|
|
|
9985
10798
|
this.loadOlderMessagesInFlight = false;
|
|
9986
10799
|
}
|
|
9987
10800
|
}
|
|
10801
|
+
setHasOlderMessages(hasOlderMessages) {
|
|
10802
|
+
patchAtom(this.snapshotAtom, { hasOlderMessages });
|
|
10803
|
+
}
|
|
9988
10804
|
resetHistoryPaging() {
|
|
9989
|
-
this.
|
|
10805
|
+
this.setHasOlderMessages(false);
|
|
9990
10806
|
this.olderMessagesCursor = void 0;
|
|
9991
10807
|
this.knownServerMessageIds.clear();
|
|
9992
10808
|
this.historyGeneration++;
|
|
9993
10809
|
}
|
|
9994
10810
|
applyHydrationPage(page) {
|
|
9995
10811
|
if (page?.truncated === true) {
|
|
9996
|
-
this.
|
|
10812
|
+
this.setHasOlderMessages(true);
|
|
9997
10813
|
this.olderMessagesCursor = page.cursor;
|
|
9998
10814
|
return;
|
|
9999
10815
|
}
|
|
10000
|
-
this.
|
|
10816
|
+
this.setHasOlderMessages(false);
|
|
10001
10817
|
this.olderMessagesCursor = void 0;
|
|
10002
10818
|
}
|
|
10003
10819
|
rememberServerMessageIds(messages) {
|
|
@@ -10085,7 +10901,9 @@ var ChatClient = class {
|
|
|
10085
10901
|
}));
|
|
10086
10902
|
}
|
|
10087
10903
|
emitQueueChange() {
|
|
10088
|
-
this.
|
|
10904
|
+
const queue = this.getQueue();
|
|
10905
|
+
patchAtom(this.snapshotAtom, { queue: this.freezeSnapshotQueue(queue) });
|
|
10906
|
+
this.callbacksRef.current.onQueueChange(queue);
|
|
10089
10907
|
this.devtoolsBridge.emitSnapshot();
|
|
10090
10908
|
}
|
|
10091
10909
|
/**
|
|
@@ -10159,7 +10977,7 @@ var ChatClient = class {
|
|
|
10159
10977
|
* Manually set messages
|
|
10160
10978
|
*/
|
|
10161
10979
|
setMessagesManually(messages) {
|
|
10162
|
-
this.processor.setMessages(messages);
|
|
10980
|
+
this.processor.setMessages(thawMessages(messages));
|
|
10163
10981
|
this.devtoolsBridge.emitSnapshot();
|
|
10164
10982
|
}
|
|
10165
10983
|
updateOptions(options) {
|
|
@@ -10181,7 +10999,6 @@ var ChatClient = class {
|
|
|
10181
10999
|
this.connection = normalizeConnectionAdapter(transport);
|
|
10182
11000
|
if (wasSubscribed) this.subscribe();
|
|
10183
11001
|
}
|
|
10184
|
-
if (options.body !== void 0) this.bodyOption = options.body;
|
|
10185
11002
|
if (options.forwardedProps !== void 0) this.forwardedPropsOption = options.forwardedProps;
|
|
10186
11003
|
if (options.byok !== void 0) this.byok = options.byok;
|
|
10187
11004
|
if (options.byokProvider !== void 0) this.byokProvider = options.byokProvider;
|
|
@@ -10269,12 +11086,13 @@ async function validateParameters(parameters, input) {
|
|
|
10269
11086
|
}
|
|
10270
11087
|
//#endregion
|
|
10271
11088
|
//#region src/core/agent-tools.ts
|
|
11089
|
+
const HOST_TOOL_NOT_EXECUTED = Symbol("Host tool was not executed");
|
|
10272
11090
|
/** The full tool set declared to the agent; `render_widget` only when widgets are registered. */
|
|
10273
|
-
function buildAgentTools(widgets, hostTools, renderWidget, debug) {
|
|
11091
|
+
function buildAgentTools(widgets, hostTools, renderWidget, debug, guardHostExecution) {
|
|
10274
11092
|
return [
|
|
10275
11093
|
...Object.keys(widgets).length > 0 ? [buildRenderWidgetTool(widgets, renderWidget)] : [],
|
|
10276
11094
|
buildAskQuestionnaireTool(),
|
|
10277
|
-
...buildHostTools(hostTools, debug)
|
|
11095
|
+
...buildHostTools(hostTools, debug, guardHostExecution)
|
|
10278
11096
|
];
|
|
10279
11097
|
}
|
|
10280
11098
|
function buildRenderWidgetTool(widgets, render) {
|
|
@@ -10367,21 +11185,26 @@ function buildAskQuestionnaireTool() {
|
|
|
10367
11185
|
}).client();
|
|
10368
11186
|
}
|
|
10369
11187
|
/** Wraps the host's mount-time tools as client tools the agent can call. */
|
|
10370
|
-
function buildHostTools(tools, debug) {
|
|
11188
|
+
function buildHostTools(tools, debug, guardHostExecution) {
|
|
10371
11189
|
return Object.entries(tools).map(([name, tool]) => toolDefinition({
|
|
10372
11190
|
name,
|
|
10373
11191
|
description: tool.description,
|
|
10374
11192
|
inputSchema: toJsonSchema(tool.parameters),
|
|
10375
11193
|
...tool.metadata ? { metadata: tool.metadata } : {}
|
|
10376
|
-
}).client(async (input) => {
|
|
10377
|
-
|
|
10378
|
-
const validated = await validateParameters(tool.parameters, input ?? {});
|
|
10379
|
-
if (validated == null) {
|
|
10380
|
-
debug?.("error", `input for host tool "${name}" failed schema validation`, { input });
|
|
10381
|
-
throw new Error(`Input for tool "${name}" failed schema validation`);
|
|
10382
|
-
}
|
|
11194
|
+
}).client(async (input, context) => {
|
|
11195
|
+
let started = false;
|
|
10383
11196
|
try {
|
|
10384
|
-
const
|
|
11197
|
+
const resolve = guardHostExecution?.(name, tool, context?.toolCallId);
|
|
11198
|
+
debug?.("tool", `executing host tool "${name}"`, { input });
|
|
11199
|
+
const validated = await validateParameters(tool.parameters, input ?? {});
|
|
11200
|
+
if (validated == null) {
|
|
11201
|
+
debug?.("error", `input for host tool "${name}" failed schema validation`, { input });
|
|
11202
|
+
throw new Error(`Input for tool "${name}" failed schema validation`);
|
|
11203
|
+
}
|
|
11204
|
+
context?.abortSignal?.throwIfAborted();
|
|
11205
|
+
const current = resolve?.() ?? tool;
|
|
11206
|
+
started = true;
|
|
11207
|
+
const output = await current.execute(validated);
|
|
10385
11208
|
try {
|
|
10386
11209
|
canonicalInterruptJson(output);
|
|
10387
11210
|
} catch {
|
|
@@ -10391,6 +11214,7 @@ function buildHostTools(tools, debug) {
|
|
|
10391
11214
|
return output;
|
|
10392
11215
|
} catch (error) {
|
|
10393
11216
|
debug?.("error", `host tool "${name}" threw`, { error });
|
|
11217
|
+
if (!started && error instanceof Error) Object.assign(error, { [HOST_TOOL_NOT_EXECUTED]: true });
|
|
10394
11218
|
throw error;
|
|
10395
11219
|
}
|
|
10396
11220
|
}));
|
|
@@ -11086,6 +11910,7 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
11086
11910
|
let identity;
|
|
11087
11911
|
let started = false;
|
|
11088
11912
|
let selectionGeneration = 0;
|
|
11913
|
+
let toolExecutionGeneration = 0;
|
|
11089
11914
|
let historyGeneration = 0;
|
|
11090
11915
|
let hydration = Promise.resolve();
|
|
11091
11916
|
let requestController = new AbortController();
|
|
@@ -11258,35 +12083,48 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
11258
12083
|
});
|
|
11259
12084
|
}
|
|
11260
12085
|
};
|
|
11261
|
-
const buildTools = () =>
|
|
11262
|
-
|
|
11263
|
-
|
|
11264
|
-
|
|
11265
|
-
|
|
11266
|
-
|
|
11267
|
-
|
|
11268
|
-
|
|
11269
|
-
const
|
|
11270
|
-
|
|
11271
|
-
|
|
11272
|
-
|
|
11273
|
-
|
|
11274
|
-
|
|
11275
|
-
|
|
11276
|
-
|
|
11277
|
-
|
|
11278
|
-
|
|
11279
|
-
|
|
11280
|
-
|
|
11281
|
-
|
|
11282
|
-
|
|
11283
|
-
|
|
11284
|
-
|
|
11285
|
-
|
|
12086
|
+
const buildTools = () => {
|
|
12087
|
+
const selection = selectionGeneration;
|
|
12088
|
+
return buildAgentTools(live.widgets ?? {}, live.tools ?? {}, renderWidget, debug, (name, declaration, toolCallId) => {
|
|
12089
|
+
const execution = toolExecutionGeneration;
|
|
12090
|
+
const executingClient = client;
|
|
12091
|
+
const executingIdentity = identity;
|
|
12092
|
+
const apiUrl = authentication.apiUrl;
|
|
12093
|
+
return () => {
|
|
12094
|
+
const current = live.tools && Object.hasOwn(live.tools, name) ? live.tools[name] : void 0;
|
|
12095
|
+
if (selection !== selectionGeneration || execution !== toolExecutionGeneration || executingClient !== client || executingIdentity !== identity || apiUrl !== authentication.apiUrl || state.thread?.role === "viewer" || !toolCallId || !liveToolCalls.has(toolCallId) || !current || current.parameters !== declaration.parameters) throw new DOMException("Host tool authority changed", "AbortError");
|
|
12096
|
+
return current;
|
|
12097
|
+
};
|
|
12098
|
+
}).map((tool) => {
|
|
12099
|
+
if (!tool.execute) return tool;
|
|
12100
|
+
const execute = tool.execute;
|
|
12101
|
+
return {
|
|
12102
|
+
...tool,
|
|
12103
|
+
execute: async (input, context) => {
|
|
12104
|
+
const toolCallId = context?.toolCallId;
|
|
12105
|
+
if (!toolCallId || !liveToolCalls.has(toolCallId)) throw new Error("A saved tool call cannot execute again. Send a new message to request it.");
|
|
12106
|
+
const results = toolResults;
|
|
12107
|
+
const key = toolResultKey(toolCallId);
|
|
12108
|
+
const resultIdentity = identity;
|
|
12109
|
+
const apiUrl = authentication.apiUrl;
|
|
12110
|
+
try {
|
|
12111
|
+
const output = await execute(input, context);
|
|
12112
|
+
if (identity === resultIdentity && authentication.apiUrl === apiUrl) results.set(key, {
|
|
12113
|
+
outcome: "succeeded",
|
|
12114
|
+
output: output ?? null
|
|
12115
|
+
});
|
|
12116
|
+
return output;
|
|
12117
|
+
} catch (error) {
|
|
12118
|
+
if (!(error instanceof Error && HOST_TOOL_NOT_EXECUTED in error) && identity === resultIdentity && authentication.apiUrl === apiUrl) results.set(key, {
|
|
12119
|
+
outcome: "unknown",
|
|
12120
|
+
output: { error: error instanceof Error ? error.message : String(error) }
|
|
12121
|
+
});
|
|
12122
|
+
throw error;
|
|
12123
|
+
}
|
|
11286
12124
|
}
|
|
11287
|
-
}
|
|
11288
|
-
};
|
|
11289
|
-
}
|
|
12125
|
+
};
|
|
12126
|
+
});
|
|
12127
|
+
};
|
|
11290
12128
|
const declareTools = () => {
|
|
11291
12129
|
const tools = buildTools();
|
|
11292
12130
|
const agentTools = tools.map((tool) => {
|
|
@@ -11907,6 +12745,7 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
11907
12745
|
const start = () => {
|
|
11908
12746
|
if (started) return;
|
|
11909
12747
|
started = true;
|
|
12748
|
+
client.updateOptions({ tools: declareTools() });
|
|
11910
12749
|
client.attach();
|
|
11911
12750
|
if (requestController.signal.aborted) requestController = new AbortController();
|
|
11912
12751
|
unsubscribeAuthentication = subscribeAuthentication(authentication, observeAuthentication);
|
|
@@ -11956,6 +12795,7 @@ function createAstralBeamChat(options, deferStart = false) {
|
|
|
11956
12795
|
retry,
|
|
11957
12796
|
addToolResult,
|
|
11958
12797
|
stop: () => {
|
|
12798
|
+
toolExecutionGeneration++;
|
|
11959
12799
|
if (submission?.phase === "submitting") endUnaccepted(submission);
|
|
11960
12800
|
client.stop();
|
|
11961
12801
|
},
|