@meshagent/meshagent-agents 0.46.4 → 0.47.1

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,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ChatThreadSession = exports.MessagingChatClient = exports.BaseChatClient = exports.ChatThreadStartResult = exports.ChatThreadSessionLoadState = exports.ChatThreadSessionLoadPhase = exports.PendingAgentInput = exports.AgentMessageEvent = void 0;
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;
4
4
  const meshagent_1 = require("@meshagent/meshagent");
5
5
  const uuid_1 = require("uuid");
6
6
  const agent_messages_js_1 = require("./agent-messages.js");
@@ -175,6 +175,13 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
175
175
  localParticipantName() {
176
176
  return undefined;
177
177
  }
178
+ localParticipantId() {
179
+ return undefined;
180
+ }
181
+ isClientToolCallForLocalParticipant(request) {
182
+ const targetParticipantId = request.targetParticipantId?.trim();
183
+ return targetParticipantId == null || targetParticipantId === "" || targetParticipantId === this.localParticipantId();
184
+ }
178
185
  cleanParticipantName(value) {
179
186
  return nonEmptyTrimmed(value);
180
187
  }
@@ -280,6 +287,10 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
280
287
  }
281
288
  }
282
289
  handleAgentMessage(message, { createdAt, attachment } = {}) {
290
+ if (message instanceof agent_messages_js_1.AgentClientToolCallRequested &&
291
+ !this.isClientToolCallForLocalParticipant(message)) {
292
+ return;
293
+ }
283
294
  if (message.type === agent_messages_js_1.agentConnectionStatusType) {
284
295
  this._connectionStatus = message;
285
296
  }
@@ -332,7 +343,41 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
332
343
  }
333
344
  }
334
345
  exports.BaseChatClient = BaseChatClient;
335
- class MessagingChatClient extends BaseChatClient {
346
+ exports.messagingChatThreadSubscribeType = "meshagent.chat.thread.subscribe";
347
+ exports.messagingChatThreadListSubscribeType = "meshagent.chat.thread_list.subscribe";
348
+ class ThreadSubscribe {
349
+ constructor({ threadId, stream }) {
350
+ this.threadId = threadId;
351
+ this.stream = stream;
352
+ }
353
+ get closed() {
354
+ return this.stream.closed;
355
+ }
356
+ async send(message, { attachment } = {}) {
357
+ await this.stream.sendMessage({
358
+ type: agent_messages_js_1.agentRoomMessageType,
359
+ message: message.toJson(),
360
+ attachment,
361
+ });
362
+ }
363
+ async close() {
364
+ await this.stream.close();
365
+ }
366
+ }
367
+ exports.ThreadSubscribe = ThreadSubscribe;
368
+ class ThreadListSubscribe {
369
+ constructor({ stream }) {
370
+ this.stream = stream;
371
+ }
372
+ get closed() {
373
+ return this.stream.closed;
374
+ }
375
+ async close() {
376
+ await this.stream.close();
377
+ }
378
+ }
379
+ exports.ThreadListSubscribe = ThreadListSubscribe;
380
+ class BaseMessagingChatClient extends BaseChatClient {
336
381
  constructor({ room, agentName }) {
337
382
  super();
338
383
  this.pendingParticipantWaits = new Map();
@@ -420,6 +465,9 @@ class MessagingChatClient extends BaseChatClient {
420
465
  const name = this.room.localParticipant?.getAttribute("name");
421
466
  return typeof name === "string" ? this.cleanParticipantName(name) : undefined;
422
467
  }
468
+ localParticipantId() {
469
+ return this.room.localParticipant?.id;
470
+ }
423
471
  async start() {
424
472
  if (this.started) {
425
473
  return;
@@ -546,6 +594,123 @@ class MessagingChatClient extends BaseChatClient {
546
594
  }
547
595
  }
548
596
  }
597
+ exports.BaseMessagingChatClient = BaseMessagingChatClient;
598
+ class MessagingChatClient extends BaseMessagingChatClient {
599
+ constructor() {
600
+ super(...arguments);
601
+ this.threadSubscriptions = new Map();
602
+ this.streamTasks = new Set();
603
+ }
604
+ async stop() {
605
+ const subscriptions = [
606
+ ...this.threadSubscriptions.values(),
607
+ ];
608
+ if (this.threadListSubscription != null) {
609
+ subscriptions.push(this.threadListSubscription);
610
+ }
611
+ this.threadSubscriptions.clear();
612
+ this.threadListSubscription = undefined;
613
+ await Promise.all(subscriptions.map(async (subscription) => subscription.close()));
614
+ await Promise.all(this.streamTasks);
615
+ await super.stop();
616
+ }
617
+ supportsThreadSubscriptions(participant) {
618
+ return participant.getAttribute("supports_messaging_streams") === true;
619
+ }
620
+ trackStream(subscription) {
621
+ const task = (async () => {
622
+ try {
623
+ for await (const event of subscription.stream) {
624
+ if (event.kind !== "message" || event.message.type !== agent_messages_js_1.agentRoomMessageType) {
625
+ continue;
626
+ }
627
+ const raw = event.message.message;
628
+ if (typeof raw["type"] !== "string") {
629
+ continue;
630
+ }
631
+ this.handleAgentMessage(agent_messages_js_1.AgentMessage.fromJson(raw), {
632
+ createdAt: dateOrNull(raw["created_at"]),
633
+ attachment: event.message.attachment,
634
+ });
635
+ }
636
+ }
637
+ finally {
638
+ if (subscription instanceof ThreadSubscribe) {
639
+ if (this.threadSubscriptions.get(subscription.threadId) === subscription) {
640
+ this.threadSubscriptions.delete(subscription.threadId);
641
+ }
642
+ }
643
+ else if (this.threadListSubscription === subscription) {
644
+ this.threadListSubscription = undefined;
645
+ }
646
+ }
647
+ })();
648
+ this.streamTasks.add(task);
649
+ void task.finally(() => this.streamTasks.delete(task));
650
+ }
651
+ async sendAgentMessage(message, { attachment } = {}) {
652
+ await this.start();
653
+ const participant = this.agentParticipant();
654
+ if (participant == null) {
655
+ throw new Error("Agent messaging participant is not available.");
656
+ }
657
+ if (!this.supportsThreadSubscriptions(participant)) {
658
+ await super.sendAgentMessage(message, { attachment });
659
+ return;
660
+ }
661
+ if (message.type === agent_messages_js_1.agentThreadOpenType) {
662
+ const previous = this.threadSubscriptions.get(message.threadId);
663
+ if (previous != null) {
664
+ await previous.close();
665
+ }
666
+ const stream = await this.room.messaging.stream({
667
+ to: participant,
668
+ type: exports.messagingChatThreadSubscribeType,
669
+ message: message.toJson(),
670
+ attachment,
671
+ });
672
+ const subscription = new ThreadSubscribe({ threadId: message.threadId, stream });
673
+ this.threadSubscriptions.set(message.threadId, subscription);
674
+ this.trackStream(subscription);
675
+ return;
676
+ }
677
+ if (message.type === agent_messages_js_1.agentThreadCloseType) {
678
+ const subscription = this.threadSubscriptions.get(message.threadId);
679
+ if (subscription != null) {
680
+ this.threadSubscriptions.delete(message.threadId);
681
+ await subscription.close();
682
+ return;
683
+ }
684
+ }
685
+ if (message.type === agent_messages_js_1.agentThreadWatchType) {
686
+ await this.threadListSubscription?.close();
687
+ const stream = await this.room.messaging.stream({
688
+ to: participant,
689
+ type: exports.messagingChatThreadListSubscribeType,
690
+ message: message.toJson(),
691
+ attachment,
692
+ });
693
+ const subscription = new ThreadListSubscribe({ stream });
694
+ this.threadListSubscription = subscription;
695
+ this.trackStream(subscription);
696
+ return;
697
+ }
698
+ if (message.type === agent_messages_js_1.agentThreadUnwatchType && this.threadListSubscription != null) {
699
+ const subscription = this.threadListSubscription;
700
+ this.threadListSubscription = undefined;
701
+ await subscription.close();
702
+ return;
703
+ }
704
+ if ("threadId" in message && typeof message.threadId === "string") {
705
+ const subscription = this.threadSubscriptions.get(message.threadId);
706
+ if (subscription != null) {
707
+ await subscription.send(message, { attachment });
708
+ return;
709
+ }
710
+ }
711
+ await super.sendAgentMessage(message, { attachment });
712
+ }
713
+ }
549
714
  exports.MessagingChatClient = MessagingChatClient;
550
715
  function isThreadListMessage(message) {
551
716
  return message.type === agent_messages_js_1.agentThreadListedType
@@ -560,6 +725,8 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
560
725
  this.messageIndexes = new Map();
561
726
  this.localAgentMessageIds = new Set();
562
727
  this.pendingLocalInputMessageIds = new Set();
728
+ this.resolvedInputMessageIds = new Set();
729
+ this.completedTurnIds = new Set();
563
730
  this.mergedDeltaMessageIds = new Set();
564
731
  this.pendingInputsById = new Map();
565
732
  this.openState = false;
@@ -638,6 +805,8 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
638
805
  this.messageIndexes.clear();
639
806
  this.localAgentMessageIds.clear();
640
807
  this.pendingLocalInputMessageIds.clear();
808
+ this.resolvedInputMessageIds.clear();
809
+ this.completedTurnIds.clear();
641
810
  this.mergedDeltaMessageIds.clear();
642
811
  this.pendingInputsById.clear();
643
812
  this.lastCompletedTurnIdValue = undefined;
@@ -789,15 +958,19 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
789
958
  return;
790
959
  }
791
960
  if (message.type === agent_messages_js_1.agentThreadStatusType && message instanceof agent_messages_js_1.AgentThreadStatus) {
792
- this.threadStatusValue = message;
793
961
  const mode = normalizedString(message.mode);
794
962
  const status = normalizedString(message.status);
795
963
  const turnId = normalizedString(message.turnId);
796
- if (status != null && mode === "steerable" && turnId != null) {
797
- this.activeTurnIdValue = turnId;
964
+ if (status == null) {
965
+ this.threadStatusValue = undefined;
966
+ if (turnId != null && this.activeTurnIdValue === turnId) {
967
+ this.activeTurnIdValue = undefined;
968
+ }
969
+ return;
798
970
  }
799
- else if (status == null && turnId != null && this.activeTurnIdValue === turnId) {
800
- this.activeTurnIdValue = undefined;
971
+ this.threadStatusValue = message;
972
+ if (mode === "steerable" && turnId != null) {
973
+ this.activeTurnIdValue = turnId;
801
974
  }
802
975
  return;
803
976
  }
@@ -825,21 +998,29 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
825
998
  updatePendingInputsForMessage(message, createdAt) {
826
999
  const type = message.type;
827
1000
  const messageId = message.messageId;
828
- const sourceMessageId = sourceMessageIdFor(message);
1001
+ const sourceMessageId = normalizedString(sourceMessageIdFor(message));
829
1002
  if (type === agent_messages_js_1.agentThreadStartType || type === agent_messages_js_1.agentTurnStartType || type === agent_messages_js_1.agentTurnSteerType) {
830
1003
  const normalizedMessageId = messageId.trim();
831
1004
  if (normalizedMessageId !== "") {
1005
+ const wasPending = this.pendingInputsById.has(normalizedMessageId);
1006
+ const turnId = type === agent_messages_js_1.agentTurnStartType || type === agent_messages_js_1.agentTurnSteerType
1007
+ ? normalizedString(threadMessageValue(message, "turnId"))
1008
+ : undefined;
1009
+ const wasAlreadyResolved = !wasPending && (this.resolvedInputMessageIds.has(normalizedMessageId) ||
1010
+ (turnId != null && this.completedTurnIds.has(turnId)));
832
1011
  this.localAgentMessageIds.add(normalizedMessageId);
833
1012
  this.pendingLocalInputMessageIds.add(normalizedMessageId);
834
- this.markPending(new PendingAgentInput({
835
- messageId: normalizedMessageId,
836
- messageType: type,
837
- threadPath: this.threadPath,
838
- payload: message,
839
- createdAt,
840
- awaitingAcceptance: true,
841
- awaitingApplication: true,
842
- }));
1013
+ if (!wasAlreadyResolved) {
1014
+ this.markPending(new PendingAgentInput({
1015
+ messageId: normalizedMessageId,
1016
+ messageType: type,
1017
+ threadPath: this.threadPath,
1018
+ payload: message,
1019
+ createdAt,
1020
+ awaitingAcceptance: true,
1021
+ awaitingApplication: true,
1022
+ }));
1023
+ }
843
1024
  }
844
1025
  }
845
1026
  else if (type === agent_messages_js_1.agentThreadStartRejectedType) {
@@ -852,12 +1033,14 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
852
1033
  }
853
1034
  else if (type === agent_messages_js_1.agentTurnStartedType || type === agent_messages_js_1.agentTurnSteeredType) {
854
1035
  if (sourceMessageId != null) {
1036
+ this.resolvedInputMessageIds.add(sourceMessageId);
855
1037
  this.pendingInputsById.delete(sourceMessageId);
856
1038
  this.pendingLocalInputMessageIds.delete(sourceMessageId);
857
1039
  }
858
1040
  }
859
1041
  else if (type === agent_messages_js_1.agentTurnStartRejectedType || type === agent_messages_js_1.agentTurnSteerRejectedType) {
860
1042
  if (sourceMessageId != null) {
1043
+ this.resolvedInputMessageIds.add(sourceMessageId);
861
1044
  this.pendingInputsById.delete(sourceMessageId);
862
1045
  this.pendingLocalInputMessageIds.delete(sourceMessageId);
863
1046
  }
@@ -865,6 +1048,15 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
865
1048
  else if (type === agent_messages_js_1.agentTurnEndedType || type === agent_messages_js_1.agentThreadClearedType) {
866
1049
  this.pendingInputsById.clear();
867
1050
  this.pendingLocalInputMessageIds.clear();
1051
+ if (type === agent_messages_js_1.agentTurnEndedType) {
1052
+ const turnId = normalizedString(threadMessageValue(message, "turnId"));
1053
+ if (turnId != null)
1054
+ this.completedTurnIds.add(turnId);
1055
+ }
1056
+ else if (type === agent_messages_js_1.agentThreadClearedType) {
1057
+ this.resolvedInputMessageIds.clear();
1058
+ this.completedTurnIds.clear();
1059
+ }
868
1060
  }
869
1061
  }
870
1062
  appendRenderableMessage(event) {
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@meshagent/meshagent-agents",
3
- "version": "0.46.4",
3
+ "version": "0.47.1",
4
4
  "description": "Agent chat sessions and clients for Meshagent TypeScript applications.",
5
5
  "homepage": "https://github.com/meshagent/meshagent-agents-ts",
6
6
  "scripts": {
7
7
  "test": "./run-tests.sh",
8
+ "test:rust-process-e2e": "bash ./run-rust-process-agent-e2e.sh",
8
9
  "build": "mkdir -p dist && ./scripts/build.sh"
9
10
  },
10
11
  "author": "Timu, LLC",
@@ -47,7 +48,7 @@
47
48
  "typescript": "^5.8.2"
48
49
  },
49
50
  "dependencies": {
50
- "@meshagent/meshagent": "^0.46.4",
51
+ "@meshagent/meshagent": "^0.47.1",
51
52
  "apache-arrow": "^21.0.0",
52
53
  "uuid": "^14.0.0"
53
54
  },