@meshagent/meshagent-agents 0.43.3 → 0.44.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,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.agentToolCallStartedType = exports.agentToolCallInProgressType = exports.agentToolCallPendingType = exports.agentFileContentEndedType = exports.agentFileContentDeltaType = exports.agentFileContentStartedType = exports.agentTextContentEndedType = exports.agentTextContentDeltaType = exports.agentTextContentStartedType = exports.agentReasoningContentEndedType = exports.agentReasoningContentDeltaType = exports.agentReasoningContentStartedType = exports.agentTurnEndedType = exports.agentTurnStartedType = exports.agentTurnSteerRejectedType = exports.agentTurnSteeredType = exports.agentTurnSteerAcceptedType = exports.agentTurnInterruptedType = exports.agentTurnInterruptAcceptedType = exports.agentTurnStartRejectedType = exports.agentTurnStartAcceptedType = exports.agentThreadClearedType = exports.agentModelChangedType = exports.agentModelChangeType = exports.agentModelsResponseType = exports.agentModelsRequestType = exports.agentCapabilitiesResponseType = exports.agentCapabilitiesRequestType = exports.agentThreadDeletedType = exports.agentThreadUpdatedType = exports.agentThreadCreatedType = exports.agentThreadListedType = exports.agentThreadListType = exports.agentThreadRenameType = exports.agentThreadDeleteType = exports.agentParticipantDisconnectType = exports.agentParticipantConnectType = exports.agentThreadCloseType = exports.agentThreadOpenType = exports.agentThreadStartRejectedType = exports.agentThreadLoadedType = exports.agentThreadStartedType = exports.agentThreadStartType = exports.agentRealtimeAudioCommitType = exports.agentRealtimeAudioChunkType = exports.agentThreadClearType = exports.agentTurnInterruptType = exports.agentTurnSteerType = exports.agentTurnStartType = exports.agentRoomMessageType = void 0;
4
- exports.StartThread = exports.AgentLLMMessage = exports.AgentThreadMessage = exports.AgentMessage = exports.AgentContextWindowUsage = exports.AgentGeneratedAudio = exports.AgentGeneratedImage = exports.AgentToolCallLogLine = exports.AgentRealtimeConnectionInfo = exports.AgentThreadListEntry = exports.AgentProviderInfo = exports.AgentModelInfo = exports.ToolkitCapabilities = exports.ToolkitToolCapabilities = exports.AgentError = exports.AgentAudioFormat = exports.TurnToolkitConfig = exports.ClientToolkitDescription = exports.TurnMcpConfig = exports.ToolChoice = exports.agentClientToolCallResponseType = exports.agentSecretResponseType = exports.agentToolRejectType = exports.agentToolApproveType = exports.agentUsageUpdatedType = exports.agentContextCompactedType = exports.agentAudioInputSpeechEndedType = exports.agentAudioInputSpeechStartedType = exports.agentAudioTranscriptionFailedType = exports.agentAudioTranscriptionCompletedType = exports.agentAudioTranscriptionDeltaType = exports.agentAudioTranscriptionStartedType = exports.agentAudioGenerationFailedType = exports.agentAudioGenerationCompletedType = exports.agentAudioGenerationDeltaType = exports.agentAudioGenerationStartedType = exports.agentImageGenerationFailedType = exports.agentImageGenerationCompletedType = exports.agentImageGenerationPartialType = exports.agentImageGenerationStartedType = exports.agentThreadEventType = exports.agentConnectionStatusType = exports.agentThreadStatusType = exports.agentSecretRequestedType = exports.agentClientToolCallCancelledType = exports.agentClientToolCallRequestedType = exports.agentToolCallApprovalRequestedType = exports.agentToolCallEndedType = exports.agentToolCallLogDeltaType = exports.agentToolCallArgumentsDeltaType = void 0;
5
- exports.AgentToolCallLogDelta = exports.AgentToolCallArgumentsDelta = exports.AgentToolCallStarted = exports.AgentToolCallInProgress = exports.AgentToolCallPending = exports.AgentFileContentEnded = exports.AgentFileContentDelta = exports.AgentFileContentStarted = exports.AgentTextContentEnded = exports.AgentTextContentDelta = exports.AgentTextContentStarted = exports.AgentReasoningContentEnded = exports.AgentReasoningContentDelta = exports.AgentReasoningContentStarted = exports.ThreadStartRejected = exports.ThreadLoaded = exports.ThreadStarted = exports.TurnEnded = exports.TurnStarted = exports.TurnSteerRejected = exports.TurnSteered = exports.TurnSteerAccepted = exports.TurnInterrupted = exports.TurnInterruptAccepted = exports.TurnStartRejected = exports.TurnStartAccepted = exports.ThreadCleared = exports.AgentModelChanged = exports.ChangeModel = exports.ModelsResponse = exports.ModelsRequest = exports.CapabilitiesResponse = exports.CapabilitiesRequest = exports.ThreadDeleted = exports.ThreadUpdated = exports.ThreadCreated = exports.ThreadsListed = exports.ListThreads = exports.RenameThread = exports.DeleteThread = exports.ParticipantDisconnect = exports.ParticipantConnect = exports.CloseThread = exports.OpenThread = exports.ClearThread = exports.AgentRealtimeAudioCommit = exports.AgentRealtimeAudioChunk = exports.TurnInterrupt = exports.TurnSteer = exports.TurnStart = void 0;
6
- exports.AgentClientToolCallResponse = exports.AgentSecretResponse = exports.RejectAgentToolCall = exports.ApproveAgentToolCall = exports.AgentUsageUpdated = exports.AgentContextCompacted = exports.AgentAudioInputSpeechEnded = exports.AgentAudioInputSpeechStarted = exports.AgentAudioTranscriptionFailed = exports.AgentAudioTranscriptionCompleted = exports.AgentAudioTranscriptionDelta = exports.AgentAudioTranscriptionStarted = exports.AgentAudioGenerationFailed = exports.AgentAudioGenerationCompleted = exports.AgentAudioGenerationDelta = exports.AgentAudioGenerationStarted = exports.AgentImageGenerationFailed = exports.AgentImageGenerationCompleted = exports.AgentImageGenerationPartial = exports.AgentImageGenerationStarted = exports.AgentThreadEvent = exports.AgentConnectionStatus = exports.AgentThreadStatus = exports.AgentClientToolCallCancelled = exports.AgentClientToolCallRequested = exports.AgentSecretRequested = exports.AgentToolCallApprovalRequested = exports.AgentToolCallEnded = void 0;
3
+ exports.agentToolCallPendingType = exports.agentFileContentEndedType = exports.agentFileContentDeltaType = exports.agentFileContentStartedType = exports.agentTextContentEndedType = exports.agentTextContentDeltaType = exports.agentTextContentStartedType = exports.agentReasoningContentEndedType = exports.agentReasoningContentDeltaType = exports.agentReasoningContentStartedType = exports.agentTurnEndedType = exports.agentTurnStartedType = exports.agentTurnSteerRejectedType = exports.agentTurnSteeredType = exports.agentTurnSteerAcceptedType = exports.agentTurnInterruptedType = exports.agentTurnInterruptAcceptedType = exports.agentTurnStartRejectedType = exports.agentTurnStartAcceptedType = exports.agentThreadClearedType = exports.agentModelChangedType = exports.agentModelChangeType = exports.agentModelsResponseType = exports.agentModelsRequestType = exports.agentCapabilitiesResponseType = exports.agentCapabilitiesRequestType = exports.agentThreadDeletedType = exports.agentThreadUpdatedType = exports.agentThreadCreatedType = exports.agentThreadListedType = exports.agentThreadUnwatchType = exports.agentThreadWatchType = exports.agentThreadListType = exports.agentThreadRenameType = exports.agentThreadDeleteType = exports.agentParticipantDisconnectType = exports.agentParticipantConnectType = exports.agentThreadCloseType = exports.agentThreadOpenType = exports.agentThreadStartRejectedType = exports.agentThreadLoadedType = exports.agentThreadStartedType = exports.agentThreadStartType = exports.agentRealtimeAudioCommitType = exports.agentRealtimeAudioChunkType = exports.agentThreadClearType = exports.agentTurnInterruptType = exports.agentTurnSteerType = exports.agentTurnStartType = exports.agentRoomMessageType = void 0;
4
+ exports.AgentThreadMessage = exports.AgentMessage = exports.AgentContextWindowUsage = exports.AgentGeneratedAudio = exports.AgentGeneratedImage = exports.AgentToolCallLogLine = exports.AgentRealtimeConnectionInfo = exports.AgentThreadListEntry = exports.AgentProviderInfo = exports.AgentModelInfo = exports.ToolkitCapabilities = exports.ToolkitToolCapabilities = exports.AgentError = exports.AgentAudioFormat = exports.TurnToolkitConfig = exports.ClientToolkitDescription = exports.TurnMcpConfig = exports.ToolChoice = exports.agentClientToolCallResponseType = exports.agentSecretResponseType = exports.agentToolRejectType = exports.agentToolApproveType = exports.agentUsageUpdatedType = exports.agentContextCompactedType = exports.agentAudioInputSpeechEndedType = exports.agentAudioInputSpeechStartedType = exports.agentAudioTranscriptionFailedType = exports.agentAudioTranscriptionCompletedType = exports.agentAudioTranscriptionDeltaType = exports.agentAudioTranscriptionStartedType = exports.agentAudioGenerationFailedType = exports.agentAudioGenerationCompletedType = exports.agentAudioGenerationDeltaType = exports.agentAudioGenerationStartedType = exports.agentImageGenerationFailedType = exports.agentImageGenerationCompletedType = exports.agentImageGenerationPartialType = exports.agentImageGenerationStartedType = exports.agentThreadEventType = exports.agentConnectionStatusType = exports.agentThreadStatusType = exports.agentSecretRequestedType = exports.agentClientToolCallCancelledType = exports.agentClientToolCallRequestedType = exports.agentToolCallApprovalRequestedType = exports.agentToolCallEndedType = exports.agentToolCallLogDeltaType = exports.agentToolCallArgumentsDeltaType = exports.agentToolCallStartedType = exports.agentToolCallInProgressType = void 0;
5
+ exports.AgentToolCallPending = exports.AgentFileContentEnded = exports.AgentFileContentDelta = exports.AgentFileContentStarted = exports.AgentTextContentEnded = exports.AgentTextContentDelta = exports.AgentTextContentStarted = exports.AgentReasoningContentEnded = exports.AgentReasoningContentDelta = exports.AgentReasoningContentStarted = exports.ThreadStartRejected = exports.ThreadLoaded = exports.ThreadStarted = exports.TurnEnded = exports.TurnStarted = exports.TurnSteerRejected = exports.TurnSteered = exports.TurnSteerAccepted = exports.TurnInterrupted = exports.TurnInterruptAccepted = exports.TurnStartRejected = exports.TurnStartAccepted = exports.ThreadCleared = exports.AgentModelChanged = exports.ChangeModel = exports.ModelsResponse = exports.ModelsRequest = exports.CapabilitiesResponse = exports.CapabilitiesRequest = exports.ThreadDeleted = exports.ThreadUpdated = exports.ThreadCreated = exports.ThreadsListed = exports.UnwatchThreads = exports.WatchThreads = exports.ListThreads = exports.RenameThread = exports.DeleteThread = exports.ParticipantDisconnect = exports.ParticipantConnect = exports.CloseThread = exports.OpenThread = exports.ClearThread = exports.AgentRealtimeAudioCommit = exports.AgentRealtimeAudioChunk = exports.TurnInterrupt = exports.TurnSteer = exports.TurnStart = exports.StartThread = exports.AgentLLMMessage = void 0;
6
+ exports.AgentClientToolCallResponse = exports.AgentSecretResponse = exports.RejectAgentToolCall = exports.ApproveAgentToolCall = exports.AgentUsageUpdated = exports.AgentContextCompacted = exports.AgentAudioInputSpeechEnded = exports.AgentAudioInputSpeechStarted = exports.AgentAudioTranscriptionFailed = exports.AgentAudioTranscriptionCompleted = exports.AgentAudioTranscriptionDelta = exports.AgentAudioTranscriptionStarted = exports.AgentAudioGenerationFailed = exports.AgentAudioGenerationCompleted = exports.AgentAudioGenerationDelta = exports.AgentAudioGenerationStarted = exports.AgentImageGenerationFailed = exports.AgentImageGenerationCompleted = exports.AgentImageGenerationPartial = exports.AgentImageGenerationStarted = exports.AgentThreadEvent = exports.AgentConnectionStatus = exports.AgentThreadStatus = exports.AgentClientToolCallCancelled = exports.AgentClientToolCallRequested = exports.AgentSecretRequested = exports.AgentToolCallApprovalRequested = exports.AgentToolCallEnded = exports.AgentToolCallLogDelta = exports.AgentToolCallArgumentsDelta = exports.AgentToolCallStarted = exports.AgentToolCallInProgress = void 0;
7
7
  exports.agentInputContent = agentInputContent;
8
8
  const meshagent_1 = require("@meshagent/meshagent");
9
9
  const uuid_1 = require("uuid");
@@ -25,6 +25,8 @@ exports.agentParticipantDisconnectType = "meshagent.agent.participant.disconnect
25
25
  exports.agentThreadDeleteType = "meshagent.agent.thread.delete";
26
26
  exports.agentThreadRenameType = "meshagent.agent.thread.rename";
27
27
  exports.agentThreadListType = "meshagent.agent.thread.list";
28
+ exports.agentThreadWatchType = "meshagent.agent.thread.watch";
29
+ exports.agentThreadUnwatchType = "meshagent.agent.thread.unwatch";
28
30
  exports.agentThreadListedType = "meshagent.agent.thread.listed";
29
31
  exports.agentThreadCreatedType = "meshagent.agent.thread.created";
30
32
  exports.agentThreadUpdatedType = "meshagent.agent.thread.updated";
@@ -654,16 +656,18 @@ function omitUndefined(value) {
654
656
  return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined));
655
657
  }
656
658
  class AgentMessage {
657
- constructor({ type, messageId, message_id, senderName, sender_name }) {
659
+ constructor({ type, messageId, message_id, senderName, sender_name, createdAt, created_at }) {
658
660
  this.type = String(type);
659
661
  const resolvedMessageId = stringOrNull(messageId ?? message_id)?.trim();
660
662
  this.messageId = resolvedMessageId == null || resolvedMessageId.length === 0 ? (0, uuid_1.v4)() : resolvedMessageId;
661
663
  this.senderName = stringOrNull(senderName ?? sender_name);
664
+ this.createdAt = stringOrNull(createdAt ?? created_at) ?? new Date().toISOString();
662
665
  }
663
666
  toJson() {
664
667
  return {
665
668
  type: this.type,
666
669
  message_id: this.messageId,
670
+ created_at: this.createdAt,
667
671
  ...(this.senderName != null ? { sender_name: this.senderName } : {}),
668
672
  };
669
673
  }
@@ -730,6 +734,7 @@ function makeMessageClass({ type, base = "message", fields = [], }) {
730
734
  const params = {
731
735
  messageId: stringOrNull(json.message_id),
732
736
  senderName: stringOrNull(json.sender_name),
737
+ createdAt: stringOrNull(json.created_at),
733
738
  };
734
739
  if (base !== "message") {
735
740
  params.threadId = requiredString(json, "thread_id");
@@ -940,6 +945,8 @@ exports.ParticipantDisconnect = makeMessageClass({ type: exports.agentParticipan
940
945
  exports.DeleteThread = makeMessageClass({ type: exports.agentThreadDeleteType, base: "thread" });
941
946
  exports.RenameThread = makeMessageClass({ type: exports.agentThreadRenameType, base: "thread", fields: [s("name", "name", true)] });
942
947
  exports.ListThreads = makeMessageClass({ type: exports.agentThreadListType, fields: [{ prop: "limit", json: "limit", from: (value) => intOrNull(value) ?? 200, default: () => 200, always: true }, { prop: "offset", json: "offset", from: (value) => intOrNull(value) ?? 0, default: () => 0, always: true }] });
948
+ exports.WatchThreads = makeMessageClass({ type: exports.agentThreadWatchType });
949
+ exports.UnwatchThreads = makeMessageClass({ type: exports.agentThreadUnwatchType });
943
950
  exports.ThreadsListed = makeMessageClass({ type: exports.agentThreadListedType, fields: [s("sourceMessageId", "source_message_id", true), objList("threads", "threads", AgentThreadListEntry.fromJson, true), i("total"), i("offset"), i("limit")] });
944
951
  exports.ThreadCreated = makeMessageClass({ type: exports.agentThreadCreatedType, fields: [obj("thread", "thread", AgentThreadListEntry.fromJson, true)] });
945
952
  exports.ThreadUpdated = makeMessageClass({ type: exports.agentThreadUpdatedType, fields: [obj("thread", "thread", AgentThreadListEntry.fromJson, true)] });
@@ -1,13 +1,15 @@
1
1
  import { RemoteParticipant } from "@meshagent/meshagent";
2
2
  import type { RoomClient, Content } from "@meshagent/meshagent";
3
- import { AgentMessage, AgentModelChanged, AgentThreadStatus, ModelsResponse, AgentConnectionStatus } from "./agent-messages.js";
3
+ import { AgentMessage, AgentModelChanged, AgentThreadStatus, ModelsResponse, ToolChoice, AgentConnectionStatus } from "./agent-messages.js";
4
4
  import type { AgentPayload, JsonMap, ClientToolkitDescription } from "./agent-messages.js";
5
5
  import { ChangeEmitter } from "./change-emitter.js";
6
6
  export declare class AgentMessageEvent {
7
7
  readonly message: AgentMessage;
8
+ readonly createdAt: Date;
8
9
  readonly attachment?: Uint8Array;
9
- constructor({ message, attachment }: {
10
+ constructor({ message, createdAt, attachment }: {
10
11
  message: AgentMessage;
12
+ createdAt?: Date;
11
13
  attachment?: Uint8Array;
12
14
  });
13
15
  get payload(): AgentPayload;
@@ -96,7 +98,7 @@ export declare abstract class BaseChatClient extends ChangeEmitter {
96
98
  drainPendingEvents?: boolean;
97
99
  }): ChatThreadSession;
98
100
  private openSession;
99
- startThread({ messageId, message, attachments, name, backend, provider, model, voice, outputModalities, realtimeProtocol, senderName, clientToolkits, omitContent, }: {
101
+ startThread({ messageId, message, attachments, name, backend, provider, model, voice, outputModalities, realtimeProtocol, senderName, clientToolkits, toolChoice, omitContent, }: {
100
102
  messageId?: string;
101
103
  message: string;
102
104
  attachments: string[];
@@ -109,14 +111,17 @@ export declare abstract class BaseChatClient extends ChangeEmitter {
109
111
  realtimeProtocol?: string;
110
112
  senderName?: string;
111
113
  clientToolkits?: ClientToolkitDescription[];
114
+ toolChoice?: ToolChoice;
112
115
  omitContent?: boolean;
113
116
  }): Promise<ChatThreadStartResult>;
117
+ private resolvedStartThreadMessage;
114
118
  abstract sendAgentMessage(message: AgentMessage, options?: {
115
119
  attachment?: Uint8Array;
116
120
  ignoreOffline?: boolean;
117
121
  }): Promise<void>;
118
122
  private drainPendingSessionEvents;
119
- handleAgentMessage(message: AgentMessage, { attachment }?: {
123
+ handleAgentMessage(message: AgentMessage, { createdAt, attachment }?: {
124
+ createdAt?: Date;
120
125
  attachment?: Uint8Array;
121
126
  }): void;
122
127
  emitConnectionStatus({ status, message, reason, retryDelay, }: {
@@ -132,6 +137,11 @@ export declare class MessagingChatClient extends BaseChatClient {
132
137
  readonly agentName?: string;
133
138
  private readonly pendingParticipantWaits;
134
139
  private started;
140
+ private agentParticipantId?;
141
+ private hasConnected;
142
+ private waitingForParticipant;
143
+ private roomAbortController?;
144
+ private messagingListenersAttached;
135
145
  constructor({ room, agentName }: {
136
146
  room: RoomClient;
137
147
  agentName?: string;
@@ -139,6 +149,8 @@ export declare class MessagingChatClient extends BaseChatClient {
139
149
  localParticipantName(): string | undefined;
140
150
  start(): Promise<void>;
141
151
  stop(): Promise<void>;
152
+ private attachMessagingListeners;
153
+ private detachMessagingListeners;
142
154
  agentParticipant(): RemoteParticipant | null;
143
155
  waitForAgentParticipant({ waitKey }?: {
144
156
  waitKey?: string;
@@ -148,6 +160,10 @@ export declare class MessagingChatClient extends BaseChatClient {
148
160
  ignoreOffline?: boolean;
149
161
  }): Promise<void>;
150
162
  private readonly onMessagingChanged;
163
+ private readonly onMessagingParticipantChanged;
164
+ private readonly onMessagingParticipantRemoved;
165
+ private startRoomStatusListener;
166
+ private reopenOpenSessions;
151
167
  private readonly onMessagingMessage;
152
168
  }
153
169
  export declare class ChatThreadSession extends ChangeEmitter {
@@ -186,6 +202,7 @@ export declare class ChatThreadSession extends ChangeEmitter {
186
202
  load?: boolean;
187
203
  sinceTurn?: string;
188
204
  }): Promise<void>;
205
+ private resetReplayState;
189
206
  close(): Promise<void>;
190
207
  requestModels({ ignoreOffline }?: {
191
208
  ignoreOffline?: boolean;
@@ -202,7 +219,7 @@ export declare class ChatThreadSession extends ChangeEmitter {
202
219
  requestId: string;
203
220
  response: Content;
204
221
  }): Promise<void>;
205
- sendText({ messageId, text, attachments, steer, turnId, backend, provider, model, voice, outputModalities, senderName, clientToolkits, }: {
222
+ sendText({ messageId, text, attachments, steer, turnId, backend, provider, model, voice, outputModalities, senderName, clientToolkits, toolChoice, }: {
206
223
  messageId?: string;
207
224
  text: string;
208
225
  attachments: string[];
@@ -215,6 +232,7 @@ export declare class ChatThreadSession extends ChangeEmitter {
215
232
  outputModalities?: string[];
216
233
  senderName?: string;
217
234
  clientToolkits?: ClientToolkitDescription[];
235
+ toolChoice?: ToolChoice;
218
236
  }): Promise<string>;
219
237
  sendRealtimeAudioChunk({ chunk, format }: {
220
238
  chunk: Uint8Array;
@@ -6,12 +6,13 @@ const uuid_1 = require("uuid");
6
6
  const agent_messages_js_1 = require("./agent-messages.js");
7
7
  const change_emitter_js_1 = require("./change-emitter.js");
8
8
  class AgentMessageEvent {
9
- constructor({ message, attachment }) {
9
+ constructor({ message, createdAt, attachment }) {
10
10
  this.message = message;
11
+ this.createdAt = createdAt ?? dateOrNull(message.createdAt) ?? new Date();
11
12
  this.attachment = attachment;
12
13
  }
13
14
  get payload() {
14
- return this.message.toJson();
15
+ return { ...this.message.toJson(), created_at: this.createdAt.toISOString() };
15
16
  }
16
17
  }
17
18
  exports.AgentMessageEvent = AgentMessageEvent;
@@ -203,7 +204,7 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
203
204
  this.notifyListeners();
204
205
  });
205
206
  }
206
- async startThread({ messageId, message, attachments, name, backend, provider, model, voice, outputModalities, realtimeProtocol, senderName, clientToolkits, omitContent = false, }) {
207
+ async startThread({ messageId, message, attachments, name, backend, provider, model, voice, outputModalities, realtimeProtocol, senderName, clientToolkits, toolChoice, omitContent = false, }) {
207
208
  const resolvedMessageId = messageId == null || messageId.trim() === "" ? (0, uuid_1.v4)() : messageId.trim();
208
209
  const resolvedSenderName = this.cleanParticipantName(senderName) ?? this.localParticipantName();
209
210
  const payload = new agent_messages_js_1.StartThread({
@@ -218,6 +219,7 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
218
219
  realtimeProtocol: nonEmptyTrimmed(realtimeProtocol),
219
220
  senderName: resolvedSenderName,
220
221
  clientToolkits: clientToolkits != null && clientToolkits.length > 0 ? clientToolkits : undefined,
222
+ toolChoice: toolChoice?.toJson(),
221
223
  });
222
224
  const completer = new meshagent_1.Completer();
223
225
  this.pendingStartRequests.set(resolvedMessageId, completer);
@@ -232,7 +234,10 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
232
234
  }
233
235
  const session = this.openThread(threadPath, { load: false, drainPendingEvents: false });
234
236
  if (!omitContent) {
235
- session.addAgentMessage(new AgentMessageEvent({ message: payload }));
237
+ session.addAgentMessage(new AgentMessageEvent({
238
+ message: this.resolvedStartThreadMessage({ payload, threadPath }),
239
+ createdAt: dateOrNull(payload.createdAt) ?? undefined,
240
+ }));
236
241
  }
237
242
  this.drainPendingSessionEvents(threadPath, session);
238
243
  return new ChatThreadStartResult({
@@ -247,6 +252,23 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
247
252
  this.pendingStartRequests.delete(resolvedMessageId);
248
253
  }
249
254
  }
255
+ resolvedStartThreadMessage({ payload, threadPath, }) {
256
+ return new agent_messages_js_1.TurnStart({
257
+ threadId: threadPath,
258
+ messageId: payload.messageId,
259
+ senderName: payload.senderName,
260
+ content: payload.content,
261
+ backend: payload.backend,
262
+ provider: payload.provider,
263
+ model: payload.model,
264
+ voice: payload.voice,
265
+ outputModalities: payload.outputModalities,
266
+ instructions: payload.instructions,
267
+ mcp: payload.mcp,
268
+ clientToolkits: payload.clientToolkits,
269
+ toolkits: payload.toolkits,
270
+ });
271
+ }
250
272
  drainPendingSessionEvents(threadPath, session) {
251
273
  const pendingEvents = this.pendingSessionEventsByPath.get(threadPath);
252
274
  if (pendingEvents == null) {
@@ -257,16 +279,11 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
257
279
  session.addAgentMessage(event);
258
280
  }
259
281
  }
260
- handleAgentMessage(message, { attachment } = {}) {
282
+ handleAgentMessage(message, { createdAt, attachment } = {}) {
261
283
  if (message.type === agent_messages_js_1.agentConnectionStatusType) {
262
284
  this._connectionStatus = message;
263
- for (const session of this.sessionsByPath.values()) {
264
- if (session.isOpen) {
265
- session.addAgentMessage(new AgentMessageEvent({ message, attachment }));
266
- }
267
- }
268
285
  }
269
- this.eventQueue.add(new AgentMessageEvent({ message, attachment }));
286
+ this.eventQueue.add(new AgentMessageEvent({ message, createdAt, attachment }));
270
287
  const sourceMessageId = sourceMessageIdFor(message);
271
288
  if ((message.type === agent_messages_js_1.agentThreadStartedType || message.type === agent_messages_js_1.agentThreadStartRejectedType) &&
272
289
  sourceMessageId != null &&
@@ -281,7 +298,7 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
281
298
  this.notifyListeners();
282
299
  return;
283
300
  }
284
- const event = new AgentMessageEvent({ message, attachment });
301
+ const event = new AgentMessageEvent({ message, createdAt, attachment });
285
302
  const session = this.sessionsByPath.get(threadPath);
286
303
  if (session != null) {
287
304
  session.addAgentMessage(event);
@@ -302,11 +319,6 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
302
319
  });
303
320
  this._connectionStatus = event;
304
321
  this.eventQueue.add(new AgentMessageEvent({ message: event }));
305
- for (const session of this.sessionsByPath.values()) {
306
- if (session.isOpen) {
307
- session.addAgentMessage(new AgentMessageEvent({ message: event }));
308
- }
309
- }
310
322
  this.notifyListeners();
311
323
  }
312
324
  removeThreadSession(threadPath) {
@@ -325,10 +337,50 @@ class MessagingChatClient extends BaseChatClient {
325
337
  super();
326
338
  this.pendingParticipantWaits = new Map();
327
339
  this.started = false;
340
+ this.hasConnected = false;
341
+ this.waitingForParticipant = false;
342
+ this.messagingListenersAttached = false;
328
343
  this.onMessagingChanged = () => {
329
344
  const participant = this.agentParticipant();
345
+ const participantId = participant?.id;
346
+ if (participantId !== this.agentParticipantId) {
347
+ if (participantId == null) {
348
+ if (this.agentParticipantId != null) {
349
+ this.waitingForParticipant = true;
350
+ this.emitConnectionStatus({
351
+ status: "disconnected",
352
+ message: "Agent messaging disconnected",
353
+ reason: "participant_disconnected",
354
+ });
355
+ this.emitConnectionStatus({
356
+ status: "reconnecting",
357
+ message: "Waiting for agent messaging",
358
+ reason: "participant_disconnected",
359
+ });
360
+ }
361
+ else if (this.started && this.waitingForParticipant) {
362
+ this.emitConnectionStatus({
363
+ status: "reconnecting",
364
+ message: "Waiting for agent messaging",
365
+ reason: "participant_offline",
366
+ });
367
+ }
368
+ }
369
+ else {
370
+ const status = this.hasConnected ? "reconnected" : "connected";
371
+ this.hasConnected = true;
372
+ this.waitingForParticipant = false;
373
+ this.emitConnectionStatus({
374
+ status,
375
+ message: status === "reconnected" ? "Agent messaging reconnected" : "Agent messaging connected",
376
+ });
377
+ if (status === "reconnected") {
378
+ void this.reopenOpenSessions();
379
+ }
380
+ }
381
+ this.agentParticipantId = participantId;
382
+ }
330
383
  if (participant != null) {
331
- this.emitConnectionStatus({ status: "connected", message: "Agent messaging connected" });
332
384
  for (const wait of this.pendingParticipantWaits.values()) {
333
385
  if (!wait.completed) {
334
386
  wait.complete(participant);
@@ -337,6 +389,12 @@ class MessagingChatClient extends BaseChatClient {
337
389
  }
338
390
  this.notifyListeners();
339
391
  };
392
+ this.onMessagingParticipantChanged = () => {
393
+ this.onMessagingChanged();
394
+ };
395
+ this.onMessagingParticipantRemoved = () => {
396
+ this.onMessagingChanged();
397
+ };
340
398
  this.onMessagingMessage = (event) => {
341
399
  this.onMessagingChanged();
342
400
  const roomMessage = agentRoomMessageFromEvent(event);
@@ -344,14 +402,19 @@ class MessagingChatClient extends BaseChatClient {
344
402
  return;
345
403
  }
346
404
  const participant = this.agentParticipant();
347
- if (participant == null || roomMessage.fromParticipantId !== participant.id) {
405
+ const fromSelectedAgent = participant != null && roomMessage.fromParticipantId === participant.id;
406
+ const fromParticipantlessThreadList = roomMessage.fromParticipantId == null && isThreadListMessage(roomMessage.message);
407
+ if (!fromSelectedAgent && !fromParticipantlessThreadList) {
348
408
  return;
349
409
  }
350
- this.handleAgentMessage(agent_messages_js_1.AgentMessage.fromJson(roomMessage.message), { attachment: roomMessage.attachment });
410
+ this.handleAgentMessage(agent_messages_js_1.AgentMessage.fromJson(roomMessage.message), {
411
+ createdAt: dateOrNull(roomMessage.message.created_at),
412
+ attachment: roomMessage.attachment,
413
+ });
351
414
  };
352
415
  this.room = room;
353
416
  this.agentName = agentName;
354
- this.room.messaging.addListener("message", this.onMessagingMessage);
417
+ this.attachMessagingListeners();
355
418
  }
356
419
  localParticipantName() {
357
420
  const name = this.room.localParticipant?.getAttribute("name");
@@ -362,12 +425,18 @@ class MessagingChatClient extends BaseChatClient {
362
425
  return;
363
426
  }
364
427
  this.started = true;
428
+ this.attachMessagingListeners();
365
429
  this.room.messaging.start();
366
- this.room.messaging.enable();
430
+ this.startRoomStatusListener();
431
+ await this.room.messaging.enable();
432
+ this.waitingForParticipant = true;
433
+ this.onMessagingChanged();
367
434
  }
368
435
  async stop() {
369
436
  this.started = false;
370
- this.room.messaging.removeListener("message", this.onMessagingMessage);
437
+ this.roomAbortController?.abort();
438
+ this.roomAbortController = undefined;
439
+ this.detachMessagingListeners();
371
440
  for (const wait of this.pendingParticipantWaits.values()) {
372
441
  if (!wait.completed) {
373
442
  wait.completeError(new Error("Chat client stopped while waiting for an agent participant."));
@@ -375,12 +444,35 @@ class MessagingChatClient extends BaseChatClient {
375
444
  }
376
445
  this.pendingParticipantWaits.clear();
377
446
  }
447
+ attachMessagingListeners() {
448
+ if (this.messagingListenersAttached) {
449
+ return;
450
+ }
451
+ this.room.messaging.addListener("message", this.onMessagingMessage);
452
+ this.room.messaging.addListener("participant_added", this.onMessagingParticipantChanged);
453
+ this.room.messaging.addListener("participant_removed", this.onMessagingParticipantRemoved);
454
+ this.room.messaging.addListener("messaging_enabled", this.onMessagingParticipantChanged);
455
+ this.messagingListenersAttached = true;
456
+ }
457
+ detachMessagingListeners() {
458
+ if (!this.messagingListenersAttached) {
459
+ return;
460
+ }
461
+ this.room.messaging.removeListener("messaging_enabled", this.onMessagingParticipantChanged);
462
+ this.room.messaging.removeListener("participant_removed", this.onMessagingParticipantRemoved);
463
+ this.room.messaging.removeListener("participant_added", this.onMessagingParticipantChanged);
464
+ this.room.messaging.removeListener("message", this.onMessagingMessage);
465
+ this.messagingListenersAttached = false;
466
+ }
378
467
  agentParticipant() {
379
468
  const normalizedAgentName = this.agentName?.trim();
380
469
  for (const participant of this.room.messaging.remoteParticipants) {
381
470
  if (normalizedAgentName != null && normalizedAgentName !== "" && participant.getAttribute("name") !== normalizedAgentName) {
382
471
  continue;
383
472
  }
473
+ if (normalizedAgentName != null && normalizedAgentName !== "") {
474
+ return participant;
475
+ }
384
476
  if (participant.getAttribute("supports_agent_messages") === true) {
385
477
  return participant;
386
478
  }
@@ -405,7 +497,13 @@ class MessagingChatClient extends BaseChatClient {
405
497
  }
406
498
  async sendAgentMessage(message, { attachment, ignoreOffline = false } = {}) {
407
499
  await this.start();
408
- const participant = this.agentParticipant() ?? await this.waitForAgentParticipant({ waitKey: message.messageId });
500
+ let participant = this.agentParticipant();
501
+ if (participant == null) {
502
+ if (ignoreOffline) {
503
+ return;
504
+ }
505
+ participant = await this.waitForAgentParticipant({ waitKey: message.messageId });
506
+ }
409
507
  await this.room.messaging.sendMessage({
410
508
  to: participant,
411
509
  type: agent_messages_js_1.agentRoomMessageType,
@@ -414,8 +512,51 @@ class MessagingChatClient extends BaseChatClient {
414
512
  ignoreOffline,
415
513
  });
416
514
  }
515
+ startRoomStatusListener() {
516
+ if (this.roomAbortController != null) {
517
+ return;
518
+ }
519
+ const controller = new AbortController();
520
+ this.roomAbortController = controller;
521
+ void (async () => {
522
+ for await (const event of this.room.listen({ abortSignal: controller.signal })) {
523
+ if (controller.signal.aborted || event.name !== "room.status") {
524
+ continue;
525
+ }
526
+ const status = String(event.status ?? "").trim().toLowerCase();
527
+ const message = String(event.message ?? "").trim();
528
+ if (status === "connected" || status === "ready" || status === "reconnected") {
529
+ this.waitingForParticipant = true;
530
+ this.onMessagingChanged();
531
+ }
532
+ else if (status === "disconnected" || status === "reconnecting" || status === "connecting") {
533
+ this.agentParticipantId = undefined;
534
+ this.waitingForParticipant = true;
535
+ this.emitConnectionStatus({
536
+ status: status === "disconnected" ? "disconnected" : "reconnecting",
537
+ message: message !== "" ? message : status === "disconnected" ? "Agent messaging disconnected" : "Waiting for agent messaging",
538
+ reason: message !== "" ? message : undefined,
539
+ });
540
+ }
541
+ }
542
+ })().catch(() => undefined);
543
+ }
544
+ async reopenOpenSessions() {
545
+ for (const session of this.sessions) {
546
+ if (!session.isOpen) {
547
+ continue;
548
+ }
549
+ await session.open({ load: true, sinceTurn: session.lastCompletedTurnId });
550
+ }
551
+ }
417
552
  }
418
553
  exports.MessagingChatClient = MessagingChatClient;
554
+ function isThreadListMessage(message) {
555
+ return message.type === agent_messages_js_1.agentThreadListedType
556
+ || message.type === agent_messages_js_1.agentThreadCreatedType
557
+ || message.type === agent_messages_js_1.agentThreadUpdatedType
558
+ || message.type === agent_messages_js_1.agentThreadDeletedType;
559
+ }
419
560
  class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
420
561
  constructor({ client, threadPath }) {
421
562
  super();
@@ -463,6 +604,9 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
463
604
  async open({ load = true, sinceTurn } = {}) {
464
605
  if (this.openState) {
465
606
  if (load) {
607
+ if (sinceTurn == null) {
608
+ this.resetReplayState();
609
+ }
466
610
  const openThread = new agent_messages_js_1.OpenThread({ threadId: this.threadPath, load: true, sinceTurn });
467
611
  this.setLoadState(this.loadingStateForOpen(openThread, sinceTurn));
468
612
  try {
@@ -493,6 +637,17 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
493
637
  throw error;
494
638
  }
495
639
  }
640
+ resetReplayState() {
641
+ this._messages.length = 0;
642
+ this.messageIndexes.clear();
643
+ this.localAgentMessageIds.clear();
644
+ this.pendingLocalInputMessageIds.clear();
645
+ this.mergedDeltaMessageIds.clear();
646
+ this.pendingInputsById.clear();
647
+ this.lastCompletedTurnIdValue = undefined;
648
+ this.lastAgentMessageType = undefined;
649
+ this.lastAgentMessageAt = undefined;
650
+ }
496
651
  async close() {
497
652
  if (!this.openState) {
498
653
  return;
@@ -524,7 +679,7 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
524
679
  response,
525
680
  }));
526
681
  }
527
- async sendText({ messageId, text, attachments, steer = false, turnId, backend, provider, model, voice, outputModalities, senderName, clientToolkits, }) {
682
+ async sendText({ messageId, text, attachments, steer = false, turnId, backend, provider, model, voice, outputModalities, senderName, clientToolkits, toolChoice, }) {
528
683
  const resolvedMessageId = messageId == null || messageId.trim() === "" ? (0, uuid_1.v4)() : messageId.trim();
529
684
  const currentModel = this.currentModelValue;
530
685
  const resolvedBackend = nonEmptyTrimmed(backend) ?? currentModel?.backend;
@@ -553,6 +708,7 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
553
708
  voice: resolvedVoice,
554
709
  outputModalities: resolvedOutputModalities,
555
710
  clientToolkits: clientToolkits != null && clientToolkits.length > 0 ? clientToolkits : undefined,
711
+ toolChoice: toolChoice?.toJson(),
556
712
  });
557
713
  this.localAgentMessageIds.add(resolvedMessageId);
558
714
  this.pendingLocalInputMessageIds.add(resolvedMessageId);
@@ -602,9 +758,9 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
602
758
  const message = event.message;
603
759
  const type = message.type;
604
760
  this.lastAgentMessageType = type;
605
- this.lastAgentMessageAt = new Date();
761
+ this.lastAgentMessageAt = event.createdAt;
606
762
  this.updateSessionState(message);
607
- this.updatePendingInputsForMessage(message);
763
+ this.updatePendingInputsForMessage(message, event.createdAt);
608
764
  this.appendRenderableMessage(event);
609
765
  this.notifyListeners();
610
766
  }
@@ -670,7 +826,7 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
670
826
  }), { notify: false });
671
827
  }
672
828
  }
673
- updatePendingInputsForMessage(message) {
829
+ updatePendingInputsForMessage(message, createdAt) {
674
830
  const type = message.type;
675
831
  const messageId = message.messageId;
676
832
  const sourceMessageId = sourceMessageIdFor(message);
@@ -684,7 +840,7 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
684
840
  messageType: type,
685
841
  threadPath: this.threadPath,
686
842
  payload: message,
687
- createdAt: new Date(),
843
+ createdAt,
688
844
  awaitingAcceptance: true,
689
845
  awaitingApplication: true,
690
846
  }));
@@ -723,6 +879,31 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
723
879
  }
724
880
  return;
725
881
  }
882
+ if (message.type === agent_messages_js_1.agentToolCallEndedType) {
883
+ const itemId = message.error == null ? undefined : normalizedString(message.itemId);
884
+ if (itemId != null) {
885
+ this.upsertItemMessage(`tool_call:${itemId}`, event);
886
+ }
887
+ else if (message.error != null) {
888
+ this.appendMessage(event);
889
+ }
890
+ return;
891
+ }
892
+ if (message.type === agent_messages_js_1.agentToolCallPendingType || message.type === agent_messages_js_1.agentToolCallInProgressType || message.type === agent_messages_js_1.agentToolCallStartedType) {
893
+ const itemId = normalizedString(message.itemId);
894
+ if (itemId != null) {
895
+ this.upsertItemMessage(`tool_call:${itemId}`, event);
896
+ }
897
+ return;
898
+ }
899
+ if (message.type === agent_messages_js_1.agentSecretRequestedType) {
900
+ this.appendMessage(event);
901
+ return;
902
+ }
903
+ if (message.type === agent_messages_js_1.agentModelChangedType) {
904
+ this.appendMessage(event);
905
+ return;
906
+ }
726
907
  if (message.type === agent_messages_js_1.agentThreadStartType || message.type === agent_messages_js_1.agentTurnStartType || message.type === agent_messages_js_1.agentTurnSteerType) {
727
908
  if (agentInputText(message.content).trim() !== "") {
728
909
  this.appendMessage(event);
@@ -738,6 +919,18 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
738
919
  if (agentInputText(message.content).trim() !== "") {
739
920
  this.appendMessage(event, { beforePendingLocalInputs: true });
740
921
  }
922
+ else {
923
+ this.appendMessage(event);
924
+ }
925
+ return;
926
+ }
927
+ if (message.type === agent_messages_js_1.agentTurnStartedType ||
928
+ message.type === agent_messages_js_1.agentTurnSteeredType ||
929
+ message.type === agent_messages_js_1.agentTurnStartRejectedType ||
930
+ message.type === agent_messages_js_1.agentTurnSteerRejectedType ||
931
+ message.type === agent_messages_js_1.agentTurnInterruptAcceptedType ||
932
+ message.type === agent_messages_js_1.agentTurnInterruptedType) {
933
+ this.appendMessage(event);
741
934
  return;
742
935
  }
743
936
  if (isMergeableDelta(message)) {
@@ -751,6 +944,10 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
751
944
  }
752
945
  return;
753
946
  }
947
+ if (message.type === agent_messages_js_1.agentUsageUpdatedType) {
948
+ this.appendMessage(event);
949
+ return;
950
+ }
754
951
  if (message instanceof agent_messages_js_1.AgentClientToolCallRequested) {
755
952
  this.appendMessage(event);
756
953
  }
@@ -803,7 +1000,7 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
803
1000
  const existing = this._messages[existingIndex].message;
804
1001
  const merged = mergeDeltaMessage(existing, message);
805
1002
  if (merged != null) {
806
- this._messages[existingIndex] = new AgentMessageEvent({ message: merged, attachment: event.attachment });
1003
+ this._messages[existingIndex] = new AgentMessageEvent({ message: merged, createdAt: event.createdAt, attachment: event.attachment });
807
1004
  }
808
1005
  }
809
1006
  indexMessagesFrom(start) {
@@ -968,6 +1165,16 @@ function normalizedString(value) {
968
1165
  const normalized = value?.trim();
969
1166
  return normalized == null || normalized === "" ? undefined : normalized;
970
1167
  }
1168
+ function dateOrNull(value) {
1169
+ if (value instanceof Date && !Number.isNaN(value.getTime())) {
1170
+ return value;
1171
+ }
1172
+ if (typeof value !== "string" || value.trim() === "") {
1173
+ return undefined;
1174
+ }
1175
+ const parsed = new Date(value);
1176
+ return Number.isNaN(parsed.getTime()) ? undefined : parsed;
1177
+ }
971
1178
  function nonEmptyTrimmed(value) {
972
1179
  const normalized = value?.trim();
973
1180
  return normalized == null || normalized === "" ? undefined : normalized;
@@ -93,6 +93,7 @@ export declare class AgentThreadStorageRepository extends ThreadStorageRepositor
93
93
  renameThread(threadPath: string, name: string): Promise<void>;
94
94
  private requestList;
95
95
  private handleEvent;
96
+ private reconnectWatch;
96
97
  private handleThreadsListed;
97
98
  private upsertThread;
98
99
  private entryFromAgentThread;