@meshagent/meshagent-agents 0.47.1 → 0.49.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.
@@ -1,19 +1,40 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ChatThreadSession = exports.MessagingChatClient = exports.BaseMessagingChatClient = exports.ThreadListSubscribe = exports.ThreadSubscribe = exports.messagingChatThreadListSubscribeType = exports.messagingChatThreadSubscribeType = exports.BaseChatClient = exports.ChatThreadStartResult = exports.ChatThreadSessionLoadState = exports.ChatThreadSessionLoadPhase = exports.PendingAgentInput = exports.AgentMessageEvent = void 0;
6
+ exports.ChatThreadSession = exports.MessagingChatClient = exports.WebSocketChatClient = exports.BaseMessagingChatClient = exports.ThreadListSubscribe = exports.ThreadSubscribe = exports.messagingChatThreadListSubscribeType = exports.messagingChatThreadSubscribeType = exports.BaseChatClient = exports.PendingThreadStartCandidate = exports.ChatThreadStartResult = exports.ChatThreadSessionLoadState = exports.ChatThreadSessionLoadPhase = exports.PendingAgentInput = exports.AgentMessageEvent = void 0;
4
7
  const meshagent_1 = require("@meshagent/meshagent");
8
+ const msgpack_1 = require("@msgpack/msgpack");
9
+ const isomorphic_ws_1 = __importDefault(require("isomorphic-ws"));
5
10
  const uuid_1 = require("uuid");
6
11
  const agent_messages_js_1 = require("./agent-messages.js");
7
12
  const change_emitter_js_1 = require("./change-emitter.js");
8
13
  class AgentMessageEvent {
9
14
  constructor({ message, createdAt, attachment }) {
10
- this.message = message;
11
- this.createdAt = createdAt ?? dateOrNull(message.createdAt) ?? new Date();
15
+ this.listeners = new Set();
16
+ this.messageValue = message;
17
+ this.createdAt = createdAt ?? message.createdAtUtc ?? new Date();
12
18
  this.attachment = attachment;
13
19
  }
20
+ get message() {
21
+ return this.messageValue;
22
+ }
14
23
  get payload() {
15
24
  return { ...this.message.toJson(), created_at: this.createdAt.toISOString() };
16
25
  }
26
+ addEventListener(listener) {
27
+ this.listeners.add(listener);
28
+ }
29
+ removeEventListener(listener) {
30
+ this.listeners.delete(listener);
31
+ }
32
+ replaceMessage(message) {
33
+ this.messageValue = message;
34
+ for (const listener of [...this.listeners]) {
35
+ listener();
36
+ }
37
+ }
17
38
  }
18
39
  exports.AgentMessageEvent = AgentMessageEvent;
19
40
  function agentRoomMessageFromEvent(event) {
@@ -99,6 +120,13 @@ class ChatThreadStartResult {
99
120
  }
100
121
  }
101
122
  exports.ChatThreadStartResult = ChatThreadStartResult;
123
+ class PendingThreadStartCandidate {
124
+ constructor({ messageId, senderName }) {
125
+ this.messageId = messageId;
126
+ this.senderName = senderName;
127
+ }
128
+ }
129
+ exports.PendingThreadStartCandidate = PendingThreadStartCandidate;
102
130
  class EventQueue {
103
131
  constructor() {
104
132
  this.subscribers = new Set();
@@ -151,12 +179,15 @@ class EventQueue {
151
179
  }
152
180
  }
153
181
  class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
154
- constructor() {
155
- super(...arguments);
182
+ constructor({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests = false, } = {}) {
183
+ super();
156
184
  this.sessionsByPath = new Map();
157
185
  this.pendingStartRequests = new Map();
158
186
  this.pendingSessionEventsByPath = new Map();
159
187
  this.eventQueue = new EventQueue();
188
+ this.claimedClientToolRequests = new Set();
189
+ this.threadCreatedPendingStartMatcher = threadCreatedPendingStartMatcher;
190
+ this.deduplicateClientToolRequests = deduplicateClientToolRequests;
160
191
  }
161
192
  get events() {
162
193
  return this.eventQueue.stream;
@@ -178,14 +209,41 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
178
209
  localParticipantId() {
179
210
  return undefined;
180
211
  }
181
- isClientToolCallForLocalParticipant(request) {
182
- const targetParticipantId = request.targetParticipantId?.trim();
183
- return targetParticipantId == null || targetParticipantId === "" || targetParticipantId === this.localParticipantId();
212
+ clientToolRequestKey(threadPath, requestId) {
213
+ const normalizedThreadPath = threadPath.trim();
214
+ const normalizedRequestId = requestId.trim();
215
+ if (normalizedThreadPath === "" || normalizedRequestId === "") {
216
+ return undefined;
217
+ }
218
+ return `${normalizedThreadPath}\n${normalizedRequestId}`;
219
+ }
220
+ claimClientToolRequest(threadPath, requestId) {
221
+ if (!this.deduplicateClientToolRequests) {
222
+ return true;
223
+ }
224
+ const key = this.clientToolRequestKey(threadPath, requestId);
225
+ if (key == null) {
226
+ return true;
227
+ }
228
+ if (this.claimedClientToolRequests.has(key)) {
229
+ return false;
230
+ }
231
+ this.claimedClientToolRequests.add(key);
232
+ return true;
233
+ }
234
+ finishClientToolRequest(threadPath, requestId, { responseSent }) {
235
+ if (!this.deduplicateClientToolRequests || responseSent) {
236
+ return;
237
+ }
238
+ const key = this.clientToolRequestKey(threadPath, requestId);
239
+ if (key != null) {
240
+ this.claimedClientToolRequests.delete(key);
241
+ }
184
242
  }
185
243
  cleanParticipantName(value) {
186
244
  return nonEmptyTrimmed(value);
187
245
  }
188
- openThread(threadPath, { load = true, sinceTurn, reloadIfOpen = false, drainPendingEvents = true, } = {}) {
246
+ openThread(threadPath, { load = true, sinceTurn, reloadIfOpen = false, } = {}) {
189
247
  const normalized = threadPath.trim();
190
248
  if (normalized === "") {
191
249
  throw new TypeError("thread path cannot be empty");
@@ -197,11 +255,8 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
197
255
  }
198
256
  return existing;
199
257
  }
200
- const created = new ChatThreadSession({ client: this, threadPath: normalized });
258
+ const created = ChatThreadSession.create({ client: this, threadPath: normalized });
201
259
  this.sessionsByPath.set(normalized, created);
202
- if (drainPendingEvents) {
203
- this.drainPendingSessionEvents(normalized, created);
204
- }
205
260
  this.openSession(created, { load, sinceTurn });
206
261
  this.notifyListeners();
207
262
  return created;
@@ -211,7 +266,7 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
211
266
  this.notifyListeners();
212
267
  });
213
268
  }
214
- async startThread({ messageId, message, attachments, name, backend, provider, model, voice, outputModalities, realtimeProtocol, senderName, clientToolkits, toolChoice, omitContent = false, }) {
269
+ async startThread({ messageId, message, attachments, name, backend, provider, model, voice, outputModalities, realtimeProtocol, senderName, clientToolkits, omitContent = false, }) {
215
270
  const resolvedMessageId = messageId == null || messageId.trim() === "" ? (0, uuid_1.v4)() : messageId.trim();
216
271
  const resolvedSenderName = this.cleanParticipantName(senderName) ?? this.localParticipantName();
217
272
  const payload = new agent_messages_js_1.StartThread({
@@ -226,10 +281,9 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
226
281
  realtimeProtocol: nonEmptyTrimmed(realtimeProtocol),
227
282
  senderName: resolvedSenderName,
228
283
  clientToolkits: clientToolkits != null && clientToolkits.length > 0 ? clientToolkits : undefined,
229
- toolChoice: toolChoice?.toJson(),
230
284
  });
231
285
  const completer = new meshagent_1.Completer();
232
- this.pendingStartRequests.set(resolvedMessageId, completer);
286
+ this.pendingStartRequests.set(resolvedMessageId, { request: payload, completer });
233
287
  try {
234
288
  await this.sendAgentMessage(payload);
235
289
  const response = await completer.fut;
@@ -239,18 +293,18 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
239
293
  if (threadPath === "") {
240
294
  throw new Error("Agent did not return a thread_id for the new thread.");
241
295
  }
242
- const session = this.openThread(threadPath, { load: false, drainPendingEvents: false });
296
+ const session = this.openThread(threadPath, { load: false });
243
297
  if (!omitContent) {
244
298
  session.addAgentMessage(new AgentMessageEvent({
245
299
  message: this.resolvedStartThreadMessage({ payload, threadPath }),
246
- createdAt: dateOrNull(payload.createdAt) ?? undefined,
300
+ createdAt: payload.createdAtUtc,
247
301
  }));
248
302
  }
249
303
  this.drainPendingSessionEvents(threadPath, session);
250
304
  return new ChatThreadStartResult({
251
305
  session,
252
306
  threadPath,
253
- realtimeConnection: response.type === agent_messages_js_1.agentThreadStartedType && response.realtimeConnection != null
307
+ realtimeConnection: response instanceof agent_messages_js_1.ThreadStarted && response.realtimeConnection != null
254
308
  ? response.realtimeConnection.toJson()
255
309
  : undefined,
256
310
  });
@@ -274,6 +328,7 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
274
328
  mcp: payload.mcp,
275
329
  clientToolkits: payload.clientToolkits,
276
330
  toolkits: payload.toolkits,
331
+ toolChoice: payload.toolChoice,
277
332
  });
278
333
  }
279
334
  drainPendingSessionEvents(threadPath, session) {
@@ -287,9 +342,13 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
287
342
  }
288
343
  }
289
344
  handleAgentMessage(message, { createdAt, attachment } = {}) {
290
- if (message instanceof agent_messages_js_1.AgentClientToolCallRequested &&
291
- !this.isClientToolCallForLocalParticipant(message)) {
292
- return;
345
+ if (message instanceof agent_messages_js_1.AgentClientToolCallRequested) {
346
+ const targetParticipantId = message.targetParticipantId?.trim();
347
+ if (targetParticipantId != null &&
348
+ targetParticipantId !== "" &&
349
+ targetParticipantId !== this.localParticipantId()) {
350
+ return;
351
+ }
293
352
  }
294
353
  if (message.type === agent_messages_js_1.agentConnectionStatusType) {
295
354
  this._connectionStatus = message;
@@ -300,10 +359,13 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
300
359
  sourceMessageId != null &&
301
360
  sourceMessageId.trim() !== "") {
302
361
  const pending = this.pendingStartRequests.get(sourceMessageId.trim());
303
- if (pending != null && !pending.completed) {
304
- pending.complete(message);
362
+ if (pending != null && !pending.completer.completed) {
363
+ pending.completer.complete(message);
305
364
  }
306
365
  }
366
+ if (message instanceof agent_messages_js_1.ThreadCreated) {
367
+ this.acknowledgePendingStartFromThreadCreated(message);
368
+ }
307
369
  const threadPath = "threadId" in message ? String(message.threadId).trim() : "";
308
370
  if (threadPath === "") {
309
371
  this.notifyListeners();
@@ -321,6 +383,40 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
321
383
  }
322
384
  this.notifyListeners();
323
385
  }
386
+ acknowledgePendingStartFromThreadCreated(message) {
387
+ const matcher = this.threadCreatedPendingStartMatcher;
388
+ const threadPath = String(message.thread?.path ?? "").trim();
389
+ if (matcher == null || threadPath === "") {
390
+ return;
391
+ }
392
+ const candidates = [...this.pendingStartRequests.entries()]
393
+ .filter(([, pending]) => !pending.completer.completed)
394
+ .map(([messageId, pending]) => new PendingThreadStartCandidate({
395
+ messageId,
396
+ senderName: pending.request.senderName,
397
+ }));
398
+ if (candidates.length === 0) {
399
+ return;
400
+ }
401
+ let matchedMessageId;
402
+ try {
403
+ matchedMessageId = matcher(message, candidates)?.trim();
404
+ }
405
+ catch {
406
+ return;
407
+ }
408
+ if (matchedMessageId == null || matchedMessageId === "") {
409
+ return;
410
+ }
411
+ const pending = this.pendingStartRequests.get(matchedMessageId);
412
+ if (pending == null || pending.completer.completed) {
413
+ return;
414
+ }
415
+ pending.completer.complete(new agent_messages_js_1.ThreadStarted({
416
+ sourceMessageId: matchedMessageId,
417
+ threadId: threadPath,
418
+ }));
419
+ }
324
420
  emitConnectionStatus({ status, message, reason, retryDelay, }) {
325
421
  const event = new agent_messages_js_1.AgentConnectionStatus({
326
422
  status,
@@ -377,9 +473,17 @@ class ThreadListSubscribe {
377
473
  }
378
474
  }
379
475
  exports.ThreadListSubscribe = ThreadListSubscribe;
476
+ function participantWaitAbortedError(reason) {
477
+ if (reason instanceof Error) {
478
+ return reason;
479
+ }
480
+ const error = new Error("Agent participant wait was cancelled.");
481
+ error.name = "AbortError";
482
+ return error;
483
+ }
380
484
  class BaseMessagingChatClient extends BaseChatClient {
381
- constructor({ room, agentName }) {
382
- super();
485
+ constructor({ room, agentName, threadCreatedPendingStartMatcher, deduplicateClientToolRequests = true, }) {
486
+ super({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests });
383
487
  this.pendingParticipantWaits = new Map();
384
488
  this.started = false;
385
489
  this.hasConnected = false;
@@ -476,7 +580,7 @@ class BaseMessagingChatClient extends BaseChatClient {
476
580
  this.attachMessagingListeners();
477
581
  this.room.messaging.start();
478
582
  this.startRoomStatusListener();
479
- await this.room.messaging.enable();
583
+ this.room.messaging.enable();
480
584
  this.waitingForParticipant = true;
481
585
  this.onMessagingChanged();
482
586
  }
@@ -527,7 +631,13 @@ class BaseMessagingChatClient extends BaseChatClient {
527
631
  }
528
632
  return null;
529
633
  }
530
- async waitForAgentParticipant({ waitKey } = {}) {
634
+ async waitForAgentParticipant({ waitKey, signal, timeoutMs, } = {}) {
635
+ if (signal?.aborted) {
636
+ throw participantWaitAbortedError(signal.reason);
637
+ }
638
+ if (timeoutMs != null && (!Number.isFinite(timeoutMs) || timeoutMs < 0)) {
639
+ throw new RangeError("Agent participant wait timeout must be a non-negative finite number.");
640
+ }
531
641
  const existing = this.agentParticipant();
532
642
  if (existing != null) {
533
643
  return existing;
@@ -535,12 +645,34 @@ class BaseMessagingChatClient extends BaseChatClient {
535
645
  const key = waitKey == null || waitKey.trim() === "" ? (0, uuid_1.v4)() : waitKey.trim();
536
646
  const completer = new meshagent_1.Completer();
537
647
  this.pendingParticipantWaits.set(key, completer);
648
+ const handleAbort = () => {
649
+ if (!completer.completed) {
650
+ completer.completeError(participantWaitAbortedError(signal?.reason));
651
+ }
652
+ };
653
+ signal?.addEventListener("abort", handleAbort, { once: true });
654
+ if (signal?.aborted) {
655
+ handleAbort();
656
+ }
657
+ const timeout = timeoutMs == null
658
+ ? undefined
659
+ : setTimeout(() => {
660
+ if (!completer.completed) {
661
+ completer.completeError(new Error(`Agent messaging participant was not available within ${timeoutMs}ms.`));
662
+ }
663
+ }, timeoutMs);
538
664
  this.onMessagingChanged();
539
665
  try {
540
666
  return await completer.fut;
541
667
  }
542
668
  finally {
543
- this.pendingParticipantWaits.delete(key);
669
+ signal?.removeEventListener("abort", handleAbort);
670
+ if (timeout != null) {
671
+ clearTimeout(timeout);
672
+ }
673
+ if (this.pendingParticipantWaits.get(key) === completer) {
674
+ this.pendingParticipantWaits.delete(key);
675
+ }
544
676
  }
545
677
  }
546
678
  async sendAgentMessage(message, { attachment } = {}) {
@@ -595,6 +727,255 @@ class BaseMessagingChatClient extends BaseChatClient {
595
727
  }
596
728
  }
597
729
  exports.BaseMessagingChatClient = BaseMessagingChatClient;
730
+ class WebSocketChatClient extends BaseChatClient {
731
+ constructor({ url, token, participantName, protocols = ["meshagent-msgpack"], reconnect = true, reconnectInitialDelay = 1000, reconnectMaxDelay = 10000, }) {
732
+ super({ deduplicateClientToolRequests: true });
733
+ this.started = false;
734
+ this.stopping = false;
735
+ this.connecting = false;
736
+ this.reconnectAttempts = 0;
737
+ this.onMessage = (event) => {
738
+ try {
739
+ const bytes = webSocketMessageBytes(event.data);
740
+ if (bytes == null) {
741
+ return;
742
+ }
743
+ const decoded = (0, msgpack_1.decode)(bytes);
744
+ if (!isJsonMap(decoded)) {
745
+ throw new Error("chat websocket received a non-object message");
746
+ }
747
+ const message = agent_messages_js_1.AgentMessage.fromJson(decoded);
748
+ if (message instanceof agent_messages_js_1.AgentConnectionStatus) {
749
+ const participantId = message.participantId?.trim();
750
+ if (participantId != null && participantId !== "") {
751
+ this.assignedParticipantId = participantId;
752
+ }
753
+ }
754
+ this.handleAgentMessage(message);
755
+ }
756
+ catch (error) {
757
+ this.receiveError = error;
758
+ this.emitConnectionStatus({
759
+ status: "disconnected",
760
+ message: "Chat websocket message could not be decoded",
761
+ reason: describeError(error),
762
+ });
763
+ this.webSocket?.close(1003);
764
+ }
765
+ };
766
+ this.onSocketError = (event) => {
767
+ this.receiveError = event.error ?? new Error("chat websocket error");
768
+ };
769
+ this.onSocketClose = (event) => {
770
+ const webSocket = this.webSocket;
771
+ if (webSocket == null) {
772
+ return;
773
+ }
774
+ this.closeCode = event.code;
775
+ this.closeReason = event.reason;
776
+ this.detachSocketListeners(webSocket);
777
+ this.webSocket = undefined;
778
+ this.assignedParticipantId = undefined;
779
+ if (this.stopping || !this.started) {
780
+ this.notifyListeners();
781
+ return;
782
+ }
783
+ const reason = event.reason !== "" ? `code=${event.code}: ${event.reason}` : `code=${event.code}`;
784
+ if (this.reconnect) {
785
+ this.scheduleReconnect({ reason });
786
+ }
787
+ else {
788
+ this.emitConnectionStatus({
789
+ status: "disconnected",
790
+ message: "Chat websocket disconnected",
791
+ reason,
792
+ });
793
+ }
794
+ this.notifyListeners();
795
+ };
796
+ this.url = url;
797
+ this.token = token;
798
+ this.participantName = participantName;
799
+ this.protocols = protocols;
800
+ this.reconnect = reconnect;
801
+ this.reconnectInitialDelay = reconnectInitialDelay;
802
+ this.reconnectMaxDelay = reconnectMaxDelay;
803
+ }
804
+ get isConnected() {
805
+ return this.webSocket != null && this.webSocket.readyState === isomorphic_ws_1.default.OPEN;
806
+ }
807
+ localParticipantName() {
808
+ return this.cleanParticipantName(this.participantName);
809
+ }
810
+ localParticipantId() {
811
+ return this.assignedParticipantId;
812
+ }
813
+ async start() {
814
+ this.started = true;
815
+ this.stopping = false;
816
+ if (this.webSocket != null || this.connecting) {
817
+ return;
818
+ }
819
+ await this.connect({ isReconnect: false });
820
+ }
821
+ async connect({ isReconnect }) {
822
+ if (this.webSocket != null || this.connecting || !this.started || this.stopping) {
823
+ return;
824
+ }
825
+ this.connecting = true;
826
+ const webSocket = new isomorphic_ws_1.default(this.url.toString(), this.resolvedProtocols());
827
+ this.webSocket = webSocket;
828
+ this.assignedParticipantId = undefined;
829
+ webSocket.binaryType = "arraybuffer";
830
+ try {
831
+ await new Promise((resolve, reject) => {
832
+ const onOpen = () => {
833
+ cleanup();
834
+ resolve();
835
+ };
836
+ const onError = (event) => {
837
+ cleanup();
838
+ reject(event.error ?? new Error("chat websocket connection failed"));
839
+ };
840
+ const cleanup = () => {
841
+ webSocket.removeEventListener("open", onOpen);
842
+ webSocket.removeEventListener("error", onError);
843
+ };
844
+ webSocket.addEventListener("open", onOpen);
845
+ webSocket.addEventListener("error", onError);
846
+ });
847
+ }
848
+ catch (error) {
849
+ if (this.webSocket === webSocket) {
850
+ this.webSocket = undefined;
851
+ }
852
+ this.receiveError = error;
853
+ this.connecting = false;
854
+ if (isReconnect && this.reconnect && !this.stopping) {
855
+ this.scheduleReconnect({ reason: describeError(error) });
856
+ return;
857
+ }
858
+ this.emitConnectionStatus({
859
+ status: "disconnected",
860
+ message: "Chat websocket connection failed",
861
+ reason: describeError(error),
862
+ });
863
+ throw error;
864
+ }
865
+ webSocket.addEventListener("message", this.onMessage);
866
+ webSocket.addEventListener("error", this.onSocketError);
867
+ webSocket.addEventListener("close", this.onSocketClose);
868
+ this.connecting = false;
869
+ this.receiveError = undefined;
870
+ this.closeCode = undefined;
871
+ this.closeReason = undefined;
872
+ const status = isReconnect ? "reconnected" : "connected";
873
+ this.emitConnectionStatus({
874
+ status,
875
+ message: isReconnect ? "Chat websocket reconnected" : "Chat websocket connected",
876
+ });
877
+ if (isReconnect) {
878
+ await this.reopenOpenSessions();
879
+ }
880
+ this.reconnectAttempts = 0;
881
+ this.notifyListeners();
882
+ }
883
+ async stop() {
884
+ this.started = false;
885
+ this.stopping = true;
886
+ if (this.reconnectTimer != null) {
887
+ clearTimeout(this.reconnectTimer);
888
+ this.reconnectTimer = undefined;
889
+ }
890
+ const webSocket = this.webSocket;
891
+ this.webSocket = undefined;
892
+ this.assignedParticipantId = undefined;
893
+ if (webSocket != null) {
894
+ this.detachSocketListeners(webSocket);
895
+ webSocket.close(1000);
896
+ }
897
+ this.emitConnectionStatus({
898
+ status: "disconnected",
899
+ message: "Chat websocket disconnected",
900
+ reason: "client_stopped",
901
+ });
902
+ this.stopping = false;
903
+ this.notifyListeners();
904
+ }
905
+ async sendAgentMessage(message, { attachment } = {}) {
906
+ if (attachment != null) {
907
+ throw new Error("WebSocketChatClient does not support binary attachments yet.");
908
+ }
909
+ const webSocket = this.webSocket;
910
+ if (webSocket == null || webSocket.readyState !== isomorphic_ws_1.default.OPEN) {
911
+ throw new Error(this.closedMessage());
912
+ }
913
+ webSocket.send((0, msgpack_1.encode)(message.toJson()));
914
+ }
915
+ detachSocketListeners(webSocket) {
916
+ webSocket.removeEventListener("message", this.onMessage);
917
+ webSocket.removeEventListener("error", this.onSocketError);
918
+ webSocket.removeEventListener("close", this.onSocketClose);
919
+ }
920
+ scheduleReconnect({ reason }) {
921
+ if (this.reconnectTimer != null || this.stopping || !this.started) {
922
+ return;
923
+ }
924
+ const retryDelay = this.nextReconnectDelay();
925
+ this.emitConnectionStatus({
926
+ status: "reconnecting",
927
+ message: "Chat websocket disconnected; reconnecting",
928
+ reason,
929
+ retryDelay,
930
+ });
931
+ this.reconnectTimer = setTimeout(() => {
932
+ this.reconnectTimer = undefined;
933
+ void this.connect({ isReconnect: true });
934
+ }, retryDelay);
935
+ }
936
+ nextReconnectDelay() {
937
+ const initialDelay = Math.max(1, this.reconnectInitialDelay);
938
+ const maxDelay = Math.max(initialDelay, this.reconnectMaxDelay);
939
+ const factor = 2 ** Math.min(this.reconnectAttempts, 6);
940
+ this.reconnectAttempts += 1;
941
+ return Math.min(initialDelay * factor, maxDelay);
942
+ }
943
+ async reopenOpenSessions() {
944
+ for (const session of this.sessions) {
945
+ if (!session.isOpen) {
946
+ continue;
947
+ }
948
+ await session.open({ load: true, sinceTurn: session.lastCompletedTurnId });
949
+ }
950
+ }
951
+ resolvedProtocols() {
952
+ const resolved = [];
953
+ for (const protocol of this.protocols) {
954
+ const normalized = protocol.trim();
955
+ if (normalized !== "" && !resolved.includes(normalized)) {
956
+ resolved.push(normalized);
957
+ }
958
+ }
959
+ const normalizedToken = this.token.trim();
960
+ if (normalizedToken !== "") {
961
+ resolved.push(`meshagent-agent.${normalizedToken}`);
962
+ }
963
+ return resolved;
964
+ }
965
+ closedMessage() {
966
+ if (this.receiveError != null) {
967
+ return `chat websocket is closed: ${describeError(this.receiveError)}`;
968
+ }
969
+ if (this.closeCode != null) {
970
+ return `chat websocket is closed (code=${this.closeCode})`;
971
+ }
972
+ if (this.closeReason != null && this.closeReason.trim() !== "") {
973
+ return `chat websocket is closed: ${this.closeReason}`;
974
+ }
975
+ return "chat websocket is closed";
976
+ }
977
+ }
978
+ exports.WebSocketChatClient = WebSocketChatClient;
598
979
  class MessagingChatClient extends BaseMessagingChatClient {
599
980
  constructor() {
600
981
  super(...arguments);
@@ -658,7 +1039,7 @@ class MessagingChatClient extends BaseMessagingChatClient {
658
1039
  await super.sendAgentMessage(message, { attachment });
659
1040
  return;
660
1041
  }
661
- if (message.type === agent_messages_js_1.agentThreadOpenType) {
1042
+ if (message instanceof agent_messages_js_1.OpenThread) {
662
1043
  const previous = this.threadSubscriptions.get(message.threadId);
663
1044
  if (previous != null) {
664
1045
  await previous.close();
@@ -674,7 +1055,7 @@ class MessagingChatClient extends BaseMessagingChatClient {
674
1055
  this.trackStream(subscription);
675
1056
  return;
676
1057
  }
677
- if (message.type === agent_messages_js_1.agentThreadCloseType) {
1058
+ if (message instanceof agent_messages_js_1.CloseThread) {
678
1059
  const subscription = this.threadSubscriptions.get(message.threadId);
679
1060
  if (subscription != null) {
680
1061
  this.threadSubscriptions.delete(message.threadId);
@@ -682,7 +1063,7 @@ class MessagingChatClient extends BaseMessagingChatClient {
682
1063
  return;
683
1064
  }
684
1065
  }
685
- if (message.type === agent_messages_js_1.agentThreadWatchType) {
1066
+ if (message instanceof agent_messages_js_1.WatchThreads) {
686
1067
  await this.threadListSubscription?.close();
687
1068
  const stream = await this.room.messaging.stream({
688
1069
  to: participant,
@@ -695,7 +1076,7 @@ class MessagingChatClient extends BaseMessagingChatClient {
695
1076
  this.trackStream(subscription);
696
1077
  return;
697
1078
  }
698
- if (message.type === agent_messages_js_1.agentThreadUnwatchType && this.threadListSubscription != null) {
1079
+ if (message instanceof agent_messages_js_1.UnwatchThreads && this.threadListSubscription != null) {
699
1080
  const subscription = this.threadListSubscription;
700
1081
  this.threadListSubscription = undefined;
701
1082
  await subscription.close();
@@ -734,6 +1115,9 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
734
1115
  this.client = client;
735
1116
  this.threadPath = threadPath;
736
1117
  }
1118
+ static create({ client, threadPath }) {
1119
+ return new ChatThreadSession({ client, threadPath });
1120
+ }
737
1121
  get messages() {
738
1122
  return [...this._messages];
739
1123
  }
@@ -752,18 +1136,6 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
752
1136
  get lastCompletedTurnId() {
753
1137
  return this.lastCompletedTurnIdValue;
754
1138
  }
755
- get activeTurnId() {
756
- return this.activeTurnIdValue;
757
- }
758
- get threadStatus() {
759
- return this.threadStatusValue;
760
- }
761
- get currentModel() {
762
- return this.currentModelValue;
763
- }
764
- get modelsResponse() {
765
- return this.modelsResponseValue;
766
- }
767
1139
  async open({ load = true, sinceTurn } = {}) {
768
1140
  if (this.openState) {
769
1141
  if (load) {
@@ -778,7 +1150,6 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
778
1150
  }
779
1151
  catch (error) {
780
1152
  this.setLoadState(this.failedLoadState(error));
781
- throw error;
782
1153
  }
783
1154
  }
784
1155
  return;
@@ -797,7 +1168,6 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
797
1168
  }
798
1169
  catch (error) {
799
1170
  this.setLoadState(this.failedLoadState(error));
800
- throw error;
801
1171
  }
802
1172
  }
803
1173
  resetReplayState() {
@@ -844,16 +1214,20 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
844
1214
  response,
845
1215
  }));
846
1216
  }
847
- async sendText({ messageId, text, attachments, steer = false, turnId, backend, provider, model, voice, outputModalities, senderName, clientToolkits, toolChoice, }) {
1217
+ claimClientToolCall(requestId) {
1218
+ return this.client.claimClientToolRequest(this.threadPath, requestId);
1219
+ }
1220
+ finishClientToolCall(requestId, { responseSent }) {
1221
+ this.client.finishClientToolRequest(this.threadPath, requestId, { responseSent });
1222
+ }
1223
+ injectMessages(messages) {
1224
+ return this.client.sendAgentMessage(new agent_messages_js_1.InjectMessages({
1225
+ threadId: this.threadPath,
1226
+ messages: [...messages],
1227
+ }));
1228
+ }
1229
+ async sendText({ messageId, text, attachments, steer = false, turnId, backend, provider, model, voice, outputModalities, senderName, clientToolkits, }) {
848
1230
  const resolvedMessageId = messageId == null || messageId.trim() === "" ? (0, uuid_1.v4)() : messageId.trim();
849
- const currentModel = this.currentModelValue;
850
- const resolvedBackend = nonEmptyTrimmed(backend) ?? currentModel?.backend;
851
- const resolvedProvider = nonEmptyTrimmed(provider) ?? currentModel?.provider;
852
- const resolvedModel = nonEmptyTrimmed(model) ?? currentModel?.model;
853
- const resolvedVoice = nonEmptyTrimmed(voice) ?? currentModel?.voice;
854
- const resolvedOutputModalities = outputModalities != null && outputModalities.length > 0
855
- ? outputModalities
856
- : currentModel?.outputModalities;
857
1231
  const payload = steer
858
1232
  ? new agent_messages_js_1.TurnSteer({
859
1233
  threadId: this.threadPath,
@@ -867,13 +1241,12 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
867
1241
  messageId: resolvedMessageId,
868
1242
  senderName: nonEmptyTrimmed(senderName),
869
1243
  content: (0, agent_messages_js_1.agentInputContent)({ text, attachments }),
870
- backend: resolvedBackend,
871
- provider: resolvedProvider,
872
- model: resolvedModel,
873
- voice: resolvedVoice,
874
- outputModalities: resolvedOutputModalities,
1244
+ backend: nonEmptyTrimmed(backend),
1245
+ provider: nonEmptyTrimmed(provider),
1246
+ model: nonEmptyTrimmed(model),
1247
+ voice: nonEmptyTrimmed(voice),
1248
+ outputModalities: outputModalities != null && outputModalities.length > 0 ? outputModalities : undefined,
875
1249
  clientToolkits: clientToolkits != null && clientToolkits.length > 0 ? clientToolkits : undefined,
876
- toolChoice: toolChoice?.toJson(),
877
1250
  });
878
1251
  this.localAgentMessageIds.add(resolvedMessageId);
879
1252
  this.pendingLocalInputMessageIds.add(resolvedMessageId);
@@ -892,10 +1265,10 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
892
1265
  await this.client.sendAgentMessage(new agent_messages_js_1.AgentRealtimeAudioChunk({
893
1266
  threadId: this.threadPath,
894
1267
  messageId: (0, uuid_1.v4)(),
895
- format,
1268
+ format: new agent_messages_js_1.AgentAudioFormat(format),
896
1269
  }), { attachment: chunk });
897
1270
  }
898
- async commitRealtimeAudio({ turnId, provider, model, voice, outputModalities, }) {
1271
+ async commitRealtimeAudio({ turnId, backend, provider, model, voice, outputModalities, }) {
899
1272
  const messageId = (0, uuid_1.v4)();
900
1273
  await this.client.sendAgentMessage(new agent_messages_js_1.AgentRealtimeAudioCommit({
901
1274
  threadId: this.threadPath,
@@ -906,6 +1279,7 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
906
1279
  threadId: this.threadPath,
907
1280
  messageId: (0, uuid_1.v4)(),
908
1281
  turnId,
1282
+ backend: nonEmptyTrimmed(backend),
909
1283
  provider: nonEmptyTrimmed(provider),
910
1284
  model: nonEmptyTrimmed(model),
911
1285
  voice: nonEmptyTrimmed(voice),
@@ -934,56 +1308,9 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
934
1308
  const turnId = normalizedString(threadMessageValue(message, "turnId"));
935
1309
  if (turnId != null) {
936
1310
  this.lastCompletedTurnIdValue = turnId;
937
- if (this.activeTurnIdValue === turnId) {
938
- this.activeTurnIdValue = undefined;
939
- }
940
- }
941
- const statusTurnId = normalizedString(this.threadStatusValue?.turnId);
942
- if (statusTurnId == null || statusTurnId === turnId) {
943
- this.threadStatusValue = undefined;
944
1311
  }
945
- return;
946
- }
947
- if (message.type === agent_messages_js_1.agentTurnStartAcceptedType || message.type === agent_messages_js_1.agentTurnStartedType) {
948
- const turnId = normalizedString(threadMessageValue(message, "turnId"));
949
- if (turnId != null) {
950
- this.activeTurnIdValue = turnId;
951
- }
952
- if (message.type === agent_messages_js_1.agentTurnStartedType) {
953
- const statusTurnId = normalizedString(this.threadStatusValue?.turnId);
954
- if (statusTurnId == null || statusTurnId === turnId) {
955
- this.threadStatusValue = undefined;
956
- }
957
- }
958
- return;
959
- }
960
- if (message.type === agent_messages_js_1.agentThreadStatusType && message instanceof agent_messages_js_1.AgentThreadStatus) {
961
- const mode = normalizedString(message.mode);
962
- const status = normalizedString(message.status);
963
- const turnId = normalizedString(message.turnId);
964
- if (status == null) {
965
- this.threadStatusValue = undefined;
966
- if (turnId != null && this.activeTurnIdValue === turnId) {
967
- this.activeTurnIdValue = undefined;
968
- }
969
- return;
970
- }
971
- this.threadStatusValue = message;
972
- if (mode === "steerable" && turnId != null) {
973
- this.activeTurnIdValue = turnId;
974
- }
975
- return;
976
1312
  }
977
- if (message.type === agent_messages_js_1.agentModelChangedType && message instanceof agent_messages_js_1.AgentModelChanged) {
978
- this.currentModelValue = message;
979
- return;
980
- }
981
- if (message.type === agent_messages_js_1.agentModelsResponseType && message instanceof agent_messages_js_1.ModelsResponse) {
982
- this.modelsResponseValue = message;
983
- this.applyActiveModel(message);
984
- return;
985
- }
986
- if (message.type === agent_messages_js_1.agentThreadLoadedType) {
1313
+ else if (message.type === agent_messages_js_1.agentThreadLoadedType) {
987
1314
  this.setLoadState(new ChatThreadSessionLoadState({
988
1315
  phase: ChatThreadSessionLoadPhase.Loaded,
989
1316
  startedAt: this.loadStateValue.startedAt,
@@ -1061,45 +1388,21 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
1061
1388
  }
1062
1389
  appendRenderableMessage(event) {
1063
1390
  const message = event.message;
1064
- if (message.type === agent_messages_js_1.agentTurnEndedType) {
1065
- if (message.error != null) {
1066
- this.appendMessage(event);
1067
- }
1068
- return;
1069
- }
1070
- if (message.type === agent_messages_js_1.agentToolCallEndedType) {
1071
- const itemId = message.error == null ? undefined : normalizedString(message.itemId);
1072
- if (itemId != null) {
1073
- this.upsertItemMessage(`tool_call:${itemId}`, event);
1074
- }
1075
- else if (message.error != null) {
1076
- this.appendMessage(event);
1077
- }
1078
- return;
1079
- }
1080
- if (message.type === agent_messages_js_1.agentToolCallPendingType || message.type === agent_messages_js_1.agentToolCallInProgressType || message.type === agent_messages_js_1.agentToolCallStartedType) {
1081
- const itemId = normalizedString(message.itemId);
1082
- if (itemId != null) {
1083
- this.upsertItemMessage(`tool_call:${itemId}`, event);
1084
- }
1085
- return;
1086
- }
1087
- if (message.type === agent_messages_js_1.agentSecretRequestedType) {
1391
+ if (message instanceof agent_messages_js_1.TurnEnded) {
1088
1392
  this.appendMessage(event);
1089
1393
  return;
1090
1394
  }
1091
- if (message.type === agent_messages_js_1.agentModelChangedType) {
1092
- this.appendMessage(event);
1093
- return;
1094
- }
1095
- if (message.type === agent_messages_js_1.agentThreadStartType || message.type === agent_messages_js_1.agentTurnStartType || message.type === agent_messages_js_1.agentTurnSteerType) {
1096
- if (agentInputText(message.content).trim() !== "") {
1395
+ if (message instanceof agent_messages_js_1.StartThread || message instanceof agent_messages_js_1.TurnStart || message instanceof agent_messages_js_1.TurnSteer) {
1396
+ if (agentInputText(messageValue(message, "content")).trim() !== "") {
1097
1397
  this.appendMessage(event);
1398
+ const messageId = normalizedString(message.messageId);
1399
+ if (messageId != null)
1400
+ this.pendingLocalInputMessageIds.add(messageId);
1098
1401
  }
1099
1402
  return;
1100
1403
  }
1101
- if (message.type === agent_messages_js_1.agentTurnStartAcceptedType || message.type === agent_messages_js_1.agentTurnSteerAcceptedType) {
1102
- const sourceMessageId = normalizedString(sourceMessageIdFor(message));
1404
+ if (message instanceof agent_messages_js_1.TurnStartAccepted) {
1405
+ const sourceMessageId = normalizedString(message.sourceMessageId);
1103
1406
  if (sourceMessageId != null && this.localAgentMessageIds.has(sourceMessageId)) {
1104
1407
  this.pendingLocalInputMessageIds.delete(sourceMessageId);
1105
1408
  return;
@@ -1107,36 +1410,21 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
1107
1410
  if (agentInputText(message.content).trim() !== "") {
1108
1411
  this.appendMessage(event, { beforePendingLocalInputs: true });
1109
1412
  }
1110
- else {
1111
- this.appendMessage(event);
1112
- }
1113
- return;
1114
- }
1115
- if (message.type === agent_messages_js_1.agentTurnStartedType ||
1116
- message.type === agent_messages_js_1.agentTurnSteeredType ||
1117
- message.type === agent_messages_js_1.agentTurnStartRejectedType ||
1118
- message.type === agent_messages_js_1.agentTurnSteerRejectedType ||
1119
- message.type === agent_messages_js_1.agentTurnInterruptAcceptedType ||
1120
- message.type === agent_messages_js_1.agentTurnInterruptedType) {
1121
- this.appendMessage(event);
1122
1413
  return;
1123
1414
  }
1124
1415
  if (isMergeableDelta(message)) {
1125
1416
  this.appendOrMergeDelta(event);
1126
1417
  return;
1127
1418
  }
1128
- if (message.type === agent_messages_js_1.agentImageGenerationPartialType || message.type === agent_messages_js_1.agentImageGenerationCompletedType) {
1129
- const itemId = normalizedString(message.itemId);
1130
- if (itemId != null) {
1131
- this.upsertItemMessage(`image_generation:${itemId}`, event);
1132
- }
1419
+ if (message instanceof agent_messages_js_1.AgentImageGenerationPartial || message instanceof agent_messages_js_1.AgentImageGenerationCompleted) {
1420
+ this.appendMessage(event);
1133
1421
  return;
1134
1422
  }
1135
- if (message.type === agent_messages_js_1.agentUsageUpdatedType) {
1423
+ if (message instanceof agent_messages_js_1.AgentClientToolCallRequested) {
1136
1424
  this.appendMessage(event);
1137
1425
  return;
1138
1426
  }
1139
- if (message instanceof agent_messages_js_1.AgentClientToolCallRequested) {
1427
+ if (message instanceof agent_messages_js_1.AgentConnectionStatus || message instanceof agent_messages_js_1.AgentThreadMessage) {
1140
1428
  this.appendMessage(event);
1141
1429
  }
1142
1430
  }
@@ -1156,15 +1444,6 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
1156
1444
  this.messageIndexes.set(normalizedMessageId, this._messages.length);
1157
1445
  this._messages.push(event);
1158
1446
  }
1159
- upsertItemMessage(key, event) {
1160
- const existingIndex = this.messageIndexes.get(key);
1161
- if (existingIndex == null) {
1162
- this.messageIndexes.set(key, this._messages.length);
1163
- this._messages.push(event);
1164
- return;
1165
- }
1166
- this._messages[existingIndex] = event;
1167
- }
1168
1447
  appendOrMergeDelta(event) {
1169
1448
  const message = event.message;
1170
1449
  const normalizedMessageId = normalizedString(message.messageId);
@@ -1174,7 +1453,7 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
1174
1453
  }
1175
1454
  this.mergedDeltaMessageIds.add(normalizedMessageId);
1176
1455
  }
1177
- const itemId = normalizedString(message.itemId);
1456
+ const itemId = normalizedString(messageValue(message, "itemId"));
1178
1457
  if (itemId == null) {
1179
1458
  return;
1180
1459
  }
@@ -1188,7 +1467,7 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
1188
1467
  const existing = this._messages[existingIndex].message;
1189
1468
  const merged = mergeDeltaMessage(existing, message);
1190
1469
  if (merged != null) {
1191
- this._messages[existingIndex] = new AgentMessageEvent({ message: merged, createdAt: event.createdAt, attachment: event.attachment });
1470
+ this._messages[existingIndex].replaceMessage(merged);
1192
1471
  }
1193
1472
  }
1194
1473
  indexMessagesFrom(start) {
@@ -1199,29 +1478,6 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
1199
1478
  }
1200
1479
  }
1201
1480
  }
1202
- applyActiveModel(response) {
1203
- for (const provider of response.providers) {
1204
- for (const model of provider.models) {
1205
- if (!model.active) {
1206
- continue;
1207
- }
1208
- this.currentModelValue = new agent_messages_js_1.AgentModelChanged({
1209
- threadId: this.threadPath,
1210
- sourceMessageId: response.sourceMessageId,
1211
- backend: provider.backend,
1212
- provider: provider.name,
1213
- model: model.name,
1214
- voice: model.defaultOutputVoice,
1215
- inputFormat: model.inputFormat,
1216
- outputFormat: model.outputFormat,
1217
- turnDetection: model.turnDetection,
1218
- realtimeProtocols: model.realtimeProtocols,
1219
- outputModalities: model.modalities.length > 0 ? [model.modalities[0]] : ["text"],
1220
- });
1221
- return;
1222
- }
1223
- }
1224
- }
1225
1481
  markClosed({ notify = true } = {}) {
1226
1482
  this.openState = false;
1227
1483
  this.loadStateValue = new ChatThreadSessionLoadState({
@@ -1281,12 +1537,33 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
1281
1537
  }
1282
1538
  }
1283
1539
  exports.ChatThreadSession = ChatThreadSession;
1540
+ function webSocketMessageBytes(value) {
1541
+ if (value instanceof Uint8Array) {
1542
+ return value;
1543
+ }
1544
+ if (value instanceof ArrayBuffer) {
1545
+ return new Uint8Array(value);
1546
+ }
1547
+ if (ArrayBuffer.isView(value)) {
1548
+ return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
1549
+ }
1550
+ return undefined;
1551
+ }
1552
+ function isJsonMap(value) {
1553
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1554
+ }
1555
+ function describeError(error) {
1556
+ return error instanceof Error ? error.message : String(error);
1557
+ }
1284
1558
  function sourceMessageIdFor(message) {
1285
1559
  const value = "sourceMessageId" in message ? message.sourceMessageId : undefined;
1286
1560
  return typeof value === "string" ? value : undefined;
1287
1561
  }
1562
+ function messageValue(message, key) {
1563
+ return message[key];
1564
+ }
1288
1565
  function threadMessageValue(message, key) {
1289
- const value = message[key];
1566
+ const value = messageValue(message, key);
1290
1567
  return typeof value === "string" ? value : undefined;
1291
1568
  }
1292
1569
  function agentInputText(content) {
@@ -1314,7 +1591,7 @@ function isMergeableDelta(message) {
1314
1591
  }
1315
1592
  function messageIndexKey(message) {
1316
1593
  if (isMergeableDelta(message)) {
1317
- const itemId = normalizedString(message.itemId);
1594
+ const itemId = normalizedString(messageValue(message, "itemId"));
1318
1595
  return itemId == null ? undefined : `${message.type}:${itemId}`;
1319
1596
  }
1320
1597
  return normalizedString(message.messageId);
@@ -1327,30 +1604,30 @@ function mergeDeltaMessage(existing, incoming) {
1327
1604
  const data = new Uint8Array(existing.data.length + incoming.data.length);
1328
1605
  data.set(existing.data, 0);
1329
1606
  data.set(incoming.data, existing.data.length);
1330
- return new agent_messages_js_1.AgentAudioGenerationDelta({ ...existing.toJson(), data });
1607
+ return agent_messages_js_1.AgentAudioGenerationDelta.fromJson({ ...existing.toJson(), data });
1331
1608
  }
1332
1609
  if (existing.type === agent_messages_js_1.agentAudioTranscriptionDeltaType && existing instanceof agent_messages_js_1.AgentAudioTranscriptionDelta && incoming instanceof agent_messages_js_1.AgentAudioTranscriptionDelta) {
1333
- return new agent_messages_js_1.AgentAudioTranscriptionDelta({ ...existing.toJson(), text: `${existing.text}${incoming.text}` });
1610
+ return agent_messages_js_1.AgentAudioTranscriptionDelta.fromJson({ ...existing.toJson(), text: `${existing.text}${incoming.text}` });
1334
1611
  }
1335
1612
  if (existing.type === agent_messages_js_1.agentFileContentDeltaType && incoming instanceof agent_messages_js_1.AgentFileContentDelta) {
1336
1613
  return incoming;
1337
1614
  }
1338
1615
  if (existing.type === agent_messages_js_1.agentReasoningContentDeltaType && existing instanceof agent_messages_js_1.AgentReasoningContentDelta && incoming instanceof agent_messages_js_1.AgentReasoningContentDelta) {
1339
- return new agent_messages_js_1.AgentReasoningContentDelta({ ...existing.toJson(), text: `${existing.text}${incoming.text}` });
1616
+ return agent_messages_js_1.AgentReasoningContentDelta.fromJson({ ...existing.toJson(), text: `${existing.text}${incoming.text}` });
1340
1617
  }
1341
1618
  if (existing.type === agent_messages_js_1.agentTextContentDeltaType && existing instanceof agent_messages_js_1.AgentTextContentDelta && incoming instanceof agent_messages_js_1.AgentTextContentDelta) {
1342
- return new agent_messages_js_1.AgentTextContentDelta({ ...existing.toJson(), text: `${existing.text}${incoming.text}` });
1619
+ return agent_messages_js_1.AgentTextContentDelta.fromJson({ ...existing.toJson(), text: `${existing.text}${incoming.text}` });
1343
1620
  }
1344
1621
  if (existing.type === agent_messages_js_1.agentToolCallArgumentsDeltaType && existing instanceof agent_messages_js_1.AgentToolCallArgumentsDelta && incoming instanceof agent_messages_js_1.AgentToolCallArgumentsDelta) {
1345
- return new agent_messages_js_1.AgentToolCallArgumentsDelta({ ...existing.toJson(), delta: `${existing.delta}${incoming.delta}` });
1622
+ return agent_messages_js_1.AgentToolCallArgumentsDelta.fromJson({ ...existing.toJson(), delta: `${existing.delta}${incoming.delta}` });
1346
1623
  }
1347
1624
  if (existing.type === agent_messages_js_1.agentToolCallLogDeltaType && existing instanceof agent_messages_js_1.AgentToolCallLogDelta && incoming instanceof agent_messages_js_1.AgentToolCallLogDelta) {
1348
- return new agent_messages_js_1.AgentToolCallLogDelta({ ...existing.toJson(), lines: [...existing.lines, ...incoming.lines] });
1625
+ return agent_messages_js_1.AgentToolCallLogDelta.fromJson({ ...existing.toJson(), lines: [...existing.lines, ...incoming.lines] });
1349
1626
  }
1350
1627
  return undefined;
1351
1628
  }
1352
1629
  function normalizedString(value) {
1353
- const normalized = value?.trim();
1630
+ const normalized = typeof value === "string" ? value.trim() : undefined;
1354
1631
  return normalized == null || normalized === "" ? undefined : normalized;
1355
1632
  }
1356
1633
  function dateOrNull(value) {