@meshagent/meshagent-agents 0.44.0 → 0.44.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/browser/chat-client.d.ts +11 -0
- package/dist/browser/chat-client.js +124 -16
- package/dist/browser/thread-storage.d.ts +1 -0
- package/dist/browser/thread-storage.js +13 -0
- package/dist/esm/chat-client.d.ts +11 -0
- package/dist/esm/chat-client.js +124 -16
- package/dist/esm/thread-storage.d.ts +1 -0
- package/dist/esm/thread-storage.js +13 -0
- package/dist/node/chat-client.d.ts +11 -0
- package/dist/node/chat-client.js +124 -16
- package/dist/node/thread-storage.d.ts +1 -0
- package/dist/node/thread-storage.js +13 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
## [0.44.2]
|
|
2
|
+
- Messaging chat clients now listen for participant add/remove and room status changes, emit accurate connected/disconnected/reconnecting/reconnected transitions, and reopen open thread sessions after reconnect.
|
|
3
|
+
- Sending agent messages can now skip waiting for an available participant when the caller opts into offline delivery.
|
|
4
|
+
- Thread storage now reissues watch and list requests after reconnect so watched thread state comes back automatically.
|
|
5
|
+
- Successful tool-call completions no longer create transient tool-call status entries, reducing status noise in threaded chat views.
|
|
6
|
+
|
|
7
|
+
## [0.44.1]
|
|
8
|
+
- Stability
|
|
9
|
+
|
|
1
10
|
## [0.44.0]
|
|
2
11
|
- TypeScript agent clients now support thread watch/unwatch, multiple thread storages, and richer start-thread payloads, including tool-choice metadata.
|
|
3
12
|
- Chat sessions now preserve event timestamps, reset replay state correctly, and handle more agent message types such as tool-call progress, secret requests, model changes, interrupts, and usage updates.
|
|
@@ -137,6 +137,11 @@ export declare class MessagingChatClient extends BaseChatClient {
|
|
|
137
137
|
readonly agentName?: string;
|
|
138
138
|
private readonly pendingParticipantWaits;
|
|
139
139
|
private started;
|
|
140
|
+
private agentParticipantId?;
|
|
141
|
+
private hasConnected;
|
|
142
|
+
private waitingForParticipant;
|
|
143
|
+
private roomAbortController?;
|
|
144
|
+
private messagingListenersAttached;
|
|
140
145
|
constructor({ room, agentName }: {
|
|
141
146
|
room: RoomClient;
|
|
142
147
|
agentName?: string;
|
|
@@ -144,6 +149,8 @@ export declare class MessagingChatClient extends BaseChatClient {
|
|
|
144
149
|
localParticipantName(): string | undefined;
|
|
145
150
|
start(): Promise<void>;
|
|
146
151
|
stop(): Promise<void>;
|
|
152
|
+
private attachMessagingListeners;
|
|
153
|
+
private detachMessagingListeners;
|
|
147
154
|
agentParticipant(): RemoteParticipant | null;
|
|
148
155
|
waitForAgentParticipant({ waitKey }?: {
|
|
149
156
|
waitKey?: string;
|
|
@@ -153,6 +160,10 @@ export declare class MessagingChatClient extends BaseChatClient {
|
|
|
153
160
|
ignoreOffline?: boolean;
|
|
154
161
|
}): Promise<void>;
|
|
155
162
|
private readonly onMessagingChanged;
|
|
163
|
+
private readonly onMessagingParticipantChanged;
|
|
164
|
+
private readonly onMessagingParticipantRemoved;
|
|
165
|
+
private startRoomStatusListener;
|
|
166
|
+
private reopenOpenSessions;
|
|
156
167
|
private readonly onMessagingMessage;
|
|
157
168
|
}
|
|
158
169
|
export declare class ChatThreadSession extends ChangeEmitter {
|
|
@@ -282,11 +282,6 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
|
|
|
282
282
|
handleAgentMessage(message, { createdAt, attachment } = {}) {
|
|
283
283
|
if (message.type === agent_messages_js_1.agentConnectionStatusType) {
|
|
284
284
|
this._connectionStatus = message;
|
|
285
|
-
for (const session of this.sessionsByPath.values()) {
|
|
286
|
-
if (session.isOpen) {
|
|
287
|
-
session.addAgentMessage(new AgentMessageEvent({ message, createdAt, attachment }));
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
285
|
}
|
|
291
286
|
this.eventQueue.add(new AgentMessageEvent({ message, createdAt, attachment }));
|
|
292
287
|
const sourceMessageId = sourceMessageIdFor(message);
|
|
@@ -324,11 +319,6 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
|
|
|
324
319
|
});
|
|
325
320
|
this._connectionStatus = event;
|
|
326
321
|
this.eventQueue.add(new AgentMessageEvent({ message: event }));
|
|
327
|
-
for (const session of this.sessionsByPath.values()) {
|
|
328
|
-
if (session.isOpen) {
|
|
329
|
-
session.addAgentMessage(new AgentMessageEvent({ message: event }));
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
322
|
this.notifyListeners();
|
|
333
323
|
}
|
|
334
324
|
removeThreadSession(threadPath) {
|
|
@@ -347,10 +337,50 @@ class MessagingChatClient extends BaseChatClient {
|
|
|
347
337
|
super();
|
|
348
338
|
this.pendingParticipantWaits = new Map();
|
|
349
339
|
this.started = false;
|
|
340
|
+
this.hasConnected = false;
|
|
341
|
+
this.waitingForParticipant = false;
|
|
342
|
+
this.messagingListenersAttached = false;
|
|
350
343
|
this.onMessagingChanged = () => {
|
|
351
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
|
+
}
|
|
352
383
|
if (participant != null) {
|
|
353
|
-
this.emitConnectionStatus({ status: "connected", message: "Agent messaging connected" });
|
|
354
384
|
for (const wait of this.pendingParticipantWaits.values()) {
|
|
355
385
|
if (!wait.completed) {
|
|
356
386
|
wait.complete(participant);
|
|
@@ -359,6 +389,12 @@ class MessagingChatClient extends BaseChatClient {
|
|
|
359
389
|
}
|
|
360
390
|
this.notifyListeners();
|
|
361
391
|
};
|
|
392
|
+
this.onMessagingParticipantChanged = () => {
|
|
393
|
+
this.onMessagingChanged();
|
|
394
|
+
};
|
|
395
|
+
this.onMessagingParticipantRemoved = () => {
|
|
396
|
+
this.onMessagingChanged();
|
|
397
|
+
};
|
|
362
398
|
this.onMessagingMessage = (event) => {
|
|
363
399
|
this.onMessagingChanged();
|
|
364
400
|
const roomMessage = agentRoomMessageFromEvent(event);
|
|
@@ -378,7 +414,7 @@ class MessagingChatClient extends BaseChatClient {
|
|
|
378
414
|
};
|
|
379
415
|
this.room = room;
|
|
380
416
|
this.agentName = agentName;
|
|
381
|
-
this.
|
|
417
|
+
this.attachMessagingListeners();
|
|
382
418
|
}
|
|
383
419
|
localParticipantName() {
|
|
384
420
|
const name = this.room.localParticipant?.getAttribute("name");
|
|
@@ -389,12 +425,18 @@ class MessagingChatClient extends BaseChatClient {
|
|
|
389
425
|
return;
|
|
390
426
|
}
|
|
391
427
|
this.started = true;
|
|
428
|
+
this.attachMessagingListeners();
|
|
392
429
|
this.room.messaging.start();
|
|
393
|
-
this.
|
|
430
|
+
this.startRoomStatusListener();
|
|
431
|
+
await this.room.messaging.enable();
|
|
432
|
+
this.waitingForParticipant = true;
|
|
433
|
+
this.onMessagingChanged();
|
|
394
434
|
}
|
|
395
435
|
async stop() {
|
|
396
436
|
this.started = false;
|
|
397
|
-
this.
|
|
437
|
+
this.roomAbortController?.abort();
|
|
438
|
+
this.roomAbortController = undefined;
|
|
439
|
+
this.detachMessagingListeners();
|
|
398
440
|
for (const wait of this.pendingParticipantWaits.values()) {
|
|
399
441
|
if (!wait.completed) {
|
|
400
442
|
wait.completeError(new Error("Chat client stopped while waiting for an agent participant."));
|
|
@@ -402,12 +444,35 @@ class MessagingChatClient extends BaseChatClient {
|
|
|
402
444
|
}
|
|
403
445
|
this.pendingParticipantWaits.clear();
|
|
404
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
|
+
}
|
|
405
467
|
agentParticipant() {
|
|
406
468
|
const normalizedAgentName = this.agentName?.trim();
|
|
407
469
|
for (const participant of this.room.messaging.remoteParticipants) {
|
|
408
470
|
if (normalizedAgentName != null && normalizedAgentName !== "" && participant.getAttribute("name") !== normalizedAgentName) {
|
|
409
471
|
continue;
|
|
410
472
|
}
|
|
473
|
+
if (normalizedAgentName != null && normalizedAgentName !== "") {
|
|
474
|
+
return participant;
|
|
475
|
+
}
|
|
411
476
|
if (participant.getAttribute("supports_agent_messages") === true) {
|
|
412
477
|
return participant;
|
|
413
478
|
}
|
|
@@ -432,7 +497,13 @@ class MessagingChatClient extends BaseChatClient {
|
|
|
432
497
|
}
|
|
433
498
|
async sendAgentMessage(message, { attachment, ignoreOffline = false } = {}) {
|
|
434
499
|
await this.start();
|
|
435
|
-
|
|
500
|
+
let participant = this.agentParticipant();
|
|
501
|
+
if (participant == null) {
|
|
502
|
+
if (ignoreOffline) {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
participant = await this.waitForAgentParticipant({ waitKey: message.messageId });
|
|
506
|
+
}
|
|
436
507
|
await this.room.messaging.sendMessage({
|
|
437
508
|
to: participant,
|
|
438
509
|
type: agent_messages_js_1.agentRoomMessageType,
|
|
@@ -441,6 +512,43 @@ class MessagingChatClient extends BaseChatClient {
|
|
|
441
512
|
ignoreOffline,
|
|
442
513
|
});
|
|
443
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
|
+
}
|
|
444
552
|
}
|
|
445
553
|
exports.MessagingChatClient = MessagingChatClient;
|
|
446
554
|
function isThreadListMessage(message) {
|
|
@@ -772,7 +880,7 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
|
|
|
772
880
|
return;
|
|
773
881
|
}
|
|
774
882
|
if (message.type === agent_messages_js_1.agentToolCallEndedType) {
|
|
775
|
-
const itemId = normalizedString(message.itemId);
|
|
883
|
+
const itemId = message.error == null ? undefined : normalizedString(message.itemId);
|
|
776
884
|
if (itemId != null) {
|
|
777
885
|
this.upsertItemMessage(`tool_call:${itemId}`, event);
|
|
778
886
|
}
|
|
@@ -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;
|
|
@@ -367,6 +367,12 @@ class AgentThreadStorageRepository extends ThreadStorageRepository {
|
|
|
367
367
|
}
|
|
368
368
|
handleEvent(event) {
|
|
369
369
|
const message = event.message;
|
|
370
|
+
if (message.type === "meshagent.agent.connection.status") {
|
|
371
|
+
if (String(message.status ?? "").trim().toLowerCase() === "reconnected") {
|
|
372
|
+
void this.reconnectWatch();
|
|
373
|
+
}
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
370
376
|
if (message.type === "meshagent.agent.thread.listed") {
|
|
371
377
|
this.handleThreadsListed(message);
|
|
372
378
|
return;
|
|
@@ -386,6 +392,13 @@ class AgentThreadStorageRepository extends ThreadStorageRepository {
|
|
|
386
392
|
}
|
|
387
393
|
}
|
|
388
394
|
}
|
|
395
|
+
async reconnectWatch() {
|
|
396
|
+
if (this.closed) {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
await this.chatClient.sendAgentMessage(new agent_messages_js_1.WatchThreads(), { ignoreOffline: true });
|
|
400
|
+
await this.requestList();
|
|
401
|
+
}
|
|
389
402
|
handleThreadsListed(message) {
|
|
390
403
|
const nextEntries = new Map();
|
|
391
404
|
for (const thread of message.threads) {
|
|
@@ -137,6 +137,11 @@ export declare class MessagingChatClient extends BaseChatClient {
|
|
|
137
137
|
readonly agentName?: string;
|
|
138
138
|
private readonly pendingParticipantWaits;
|
|
139
139
|
private started;
|
|
140
|
+
private agentParticipantId?;
|
|
141
|
+
private hasConnected;
|
|
142
|
+
private waitingForParticipant;
|
|
143
|
+
private roomAbortController?;
|
|
144
|
+
private messagingListenersAttached;
|
|
140
145
|
constructor({ room, agentName }: {
|
|
141
146
|
room: RoomClient;
|
|
142
147
|
agentName?: string;
|
|
@@ -144,6 +149,8 @@ export declare class MessagingChatClient extends BaseChatClient {
|
|
|
144
149
|
localParticipantName(): string | undefined;
|
|
145
150
|
start(): Promise<void>;
|
|
146
151
|
stop(): Promise<void>;
|
|
152
|
+
private attachMessagingListeners;
|
|
153
|
+
private detachMessagingListeners;
|
|
147
154
|
agentParticipant(): RemoteParticipant | null;
|
|
148
155
|
waitForAgentParticipant({ waitKey }?: {
|
|
149
156
|
waitKey?: string;
|
|
@@ -153,6 +160,10 @@ export declare class MessagingChatClient extends BaseChatClient {
|
|
|
153
160
|
ignoreOffline?: boolean;
|
|
154
161
|
}): Promise<void>;
|
|
155
162
|
private readonly onMessagingChanged;
|
|
163
|
+
private readonly onMessagingParticipantChanged;
|
|
164
|
+
private readonly onMessagingParticipantRemoved;
|
|
165
|
+
private startRoomStatusListener;
|
|
166
|
+
private reopenOpenSessions;
|
|
156
167
|
private readonly onMessagingMessage;
|
|
157
168
|
}
|
|
158
169
|
export declare class ChatThreadSession extends ChangeEmitter {
|
package/dist/esm/chat-client.js
CHANGED
|
@@ -275,11 +275,6 @@ export class BaseChatClient extends ChangeEmitter {
|
|
|
275
275
|
handleAgentMessage(message, { createdAt, attachment } = {}) {
|
|
276
276
|
if (message.type === agentConnectionStatusType) {
|
|
277
277
|
this._connectionStatus = message;
|
|
278
|
-
for (const session of this.sessionsByPath.values()) {
|
|
279
|
-
if (session.isOpen) {
|
|
280
|
-
session.addAgentMessage(new AgentMessageEvent({ message, createdAt, attachment }));
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
278
|
}
|
|
284
279
|
this.eventQueue.add(new AgentMessageEvent({ message, createdAt, attachment }));
|
|
285
280
|
const sourceMessageId = sourceMessageIdFor(message);
|
|
@@ -317,11 +312,6 @@ export class BaseChatClient extends ChangeEmitter {
|
|
|
317
312
|
});
|
|
318
313
|
this._connectionStatus = event;
|
|
319
314
|
this.eventQueue.add(new AgentMessageEvent({ message: event }));
|
|
320
|
-
for (const session of this.sessionsByPath.values()) {
|
|
321
|
-
if (session.isOpen) {
|
|
322
|
-
session.addAgentMessage(new AgentMessageEvent({ message: event }));
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
315
|
this.notifyListeners();
|
|
326
316
|
}
|
|
327
317
|
removeThreadSession(threadPath) {
|
|
@@ -339,10 +329,50 @@ export class MessagingChatClient extends BaseChatClient {
|
|
|
339
329
|
super();
|
|
340
330
|
this.pendingParticipantWaits = new Map();
|
|
341
331
|
this.started = false;
|
|
332
|
+
this.hasConnected = false;
|
|
333
|
+
this.waitingForParticipant = false;
|
|
334
|
+
this.messagingListenersAttached = false;
|
|
342
335
|
this.onMessagingChanged = () => {
|
|
343
336
|
const participant = this.agentParticipant();
|
|
337
|
+
const participantId = participant?.id;
|
|
338
|
+
if (participantId !== this.agentParticipantId) {
|
|
339
|
+
if (participantId == null) {
|
|
340
|
+
if (this.agentParticipantId != null) {
|
|
341
|
+
this.waitingForParticipant = true;
|
|
342
|
+
this.emitConnectionStatus({
|
|
343
|
+
status: "disconnected",
|
|
344
|
+
message: "Agent messaging disconnected",
|
|
345
|
+
reason: "participant_disconnected",
|
|
346
|
+
});
|
|
347
|
+
this.emitConnectionStatus({
|
|
348
|
+
status: "reconnecting",
|
|
349
|
+
message: "Waiting for agent messaging",
|
|
350
|
+
reason: "participant_disconnected",
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
else if (this.started && this.waitingForParticipant) {
|
|
354
|
+
this.emitConnectionStatus({
|
|
355
|
+
status: "reconnecting",
|
|
356
|
+
message: "Waiting for agent messaging",
|
|
357
|
+
reason: "participant_offline",
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
const status = this.hasConnected ? "reconnected" : "connected";
|
|
363
|
+
this.hasConnected = true;
|
|
364
|
+
this.waitingForParticipant = false;
|
|
365
|
+
this.emitConnectionStatus({
|
|
366
|
+
status,
|
|
367
|
+
message: status === "reconnected" ? "Agent messaging reconnected" : "Agent messaging connected",
|
|
368
|
+
});
|
|
369
|
+
if (status === "reconnected") {
|
|
370
|
+
void this.reopenOpenSessions();
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
this.agentParticipantId = participantId;
|
|
374
|
+
}
|
|
344
375
|
if (participant != null) {
|
|
345
|
-
this.emitConnectionStatus({ status: "connected", message: "Agent messaging connected" });
|
|
346
376
|
for (const wait of this.pendingParticipantWaits.values()) {
|
|
347
377
|
if (!wait.completed) {
|
|
348
378
|
wait.complete(participant);
|
|
@@ -351,6 +381,12 @@ export class MessagingChatClient extends BaseChatClient {
|
|
|
351
381
|
}
|
|
352
382
|
this.notifyListeners();
|
|
353
383
|
};
|
|
384
|
+
this.onMessagingParticipantChanged = () => {
|
|
385
|
+
this.onMessagingChanged();
|
|
386
|
+
};
|
|
387
|
+
this.onMessagingParticipantRemoved = () => {
|
|
388
|
+
this.onMessagingChanged();
|
|
389
|
+
};
|
|
354
390
|
this.onMessagingMessage = (event) => {
|
|
355
391
|
this.onMessagingChanged();
|
|
356
392
|
const roomMessage = agentRoomMessageFromEvent(event);
|
|
@@ -370,7 +406,7 @@ export class MessagingChatClient extends BaseChatClient {
|
|
|
370
406
|
};
|
|
371
407
|
this.room = room;
|
|
372
408
|
this.agentName = agentName;
|
|
373
|
-
this.
|
|
409
|
+
this.attachMessagingListeners();
|
|
374
410
|
}
|
|
375
411
|
localParticipantName() {
|
|
376
412
|
const name = this.room.localParticipant?.getAttribute("name");
|
|
@@ -381,12 +417,18 @@ export class MessagingChatClient extends BaseChatClient {
|
|
|
381
417
|
return;
|
|
382
418
|
}
|
|
383
419
|
this.started = true;
|
|
420
|
+
this.attachMessagingListeners();
|
|
384
421
|
this.room.messaging.start();
|
|
385
|
-
this.
|
|
422
|
+
this.startRoomStatusListener();
|
|
423
|
+
await this.room.messaging.enable();
|
|
424
|
+
this.waitingForParticipant = true;
|
|
425
|
+
this.onMessagingChanged();
|
|
386
426
|
}
|
|
387
427
|
async stop() {
|
|
388
428
|
this.started = false;
|
|
389
|
-
this.
|
|
429
|
+
this.roomAbortController?.abort();
|
|
430
|
+
this.roomAbortController = undefined;
|
|
431
|
+
this.detachMessagingListeners();
|
|
390
432
|
for (const wait of this.pendingParticipantWaits.values()) {
|
|
391
433
|
if (!wait.completed) {
|
|
392
434
|
wait.completeError(new Error("Chat client stopped while waiting for an agent participant."));
|
|
@@ -394,12 +436,35 @@ export class MessagingChatClient extends BaseChatClient {
|
|
|
394
436
|
}
|
|
395
437
|
this.pendingParticipantWaits.clear();
|
|
396
438
|
}
|
|
439
|
+
attachMessagingListeners() {
|
|
440
|
+
if (this.messagingListenersAttached) {
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
this.room.messaging.addListener("message", this.onMessagingMessage);
|
|
444
|
+
this.room.messaging.addListener("participant_added", this.onMessagingParticipantChanged);
|
|
445
|
+
this.room.messaging.addListener("participant_removed", this.onMessagingParticipantRemoved);
|
|
446
|
+
this.room.messaging.addListener("messaging_enabled", this.onMessagingParticipantChanged);
|
|
447
|
+
this.messagingListenersAttached = true;
|
|
448
|
+
}
|
|
449
|
+
detachMessagingListeners() {
|
|
450
|
+
if (!this.messagingListenersAttached) {
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
this.room.messaging.removeListener("messaging_enabled", this.onMessagingParticipantChanged);
|
|
454
|
+
this.room.messaging.removeListener("participant_removed", this.onMessagingParticipantRemoved);
|
|
455
|
+
this.room.messaging.removeListener("participant_added", this.onMessagingParticipantChanged);
|
|
456
|
+
this.room.messaging.removeListener("message", this.onMessagingMessage);
|
|
457
|
+
this.messagingListenersAttached = false;
|
|
458
|
+
}
|
|
397
459
|
agentParticipant() {
|
|
398
460
|
const normalizedAgentName = this.agentName?.trim();
|
|
399
461
|
for (const participant of this.room.messaging.remoteParticipants) {
|
|
400
462
|
if (normalizedAgentName != null && normalizedAgentName !== "" && participant.getAttribute("name") !== normalizedAgentName) {
|
|
401
463
|
continue;
|
|
402
464
|
}
|
|
465
|
+
if (normalizedAgentName != null && normalizedAgentName !== "") {
|
|
466
|
+
return participant;
|
|
467
|
+
}
|
|
403
468
|
if (participant.getAttribute("supports_agent_messages") === true) {
|
|
404
469
|
return participant;
|
|
405
470
|
}
|
|
@@ -424,7 +489,13 @@ export class MessagingChatClient extends BaseChatClient {
|
|
|
424
489
|
}
|
|
425
490
|
async sendAgentMessage(message, { attachment, ignoreOffline = false } = {}) {
|
|
426
491
|
await this.start();
|
|
427
|
-
|
|
492
|
+
let participant = this.agentParticipant();
|
|
493
|
+
if (participant == null) {
|
|
494
|
+
if (ignoreOffline) {
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
participant = await this.waitForAgentParticipant({ waitKey: message.messageId });
|
|
498
|
+
}
|
|
428
499
|
await this.room.messaging.sendMessage({
|
|
429
500
|
to: participant,
|
|
430
501
|
type: agentRoomMessageType,
|
|
@@ -433,6 +504,43 @@ export class MessagingChatClient extends BaseChatClient {
|
|
|
433
504
|
ignoreOffline,
|
|
434
505
|
});
|
|
435
506
|
}
|
|
507
|
+
startRoomStatusListener() {
|
|
508
|
+
if (this.roomAbortController != null) {
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
511
|
+
const controller = new AbortController();
|
|
512
|
+
this.roomAbortController = controller;
|
|
513
|
+
void (async () => {
|
|
514
|
+
for await (const event of this.room.listen({ abortSignal: controller.signal })) {
|
|
515
|
+
if (controller.signal.aborted || event.name !== "room.status") {
|
|
516
|
+
continue;
|
|
517
|
+
}
|
|
518
|
+
const status = String(event.status ?? "").trim().toLowerCase();
|
|
519
|
+
const message = String(event.message ?? "").trim();
|
|
520
|
+
if (status === "connected" || status === "ready" || status === "reconnected") {
|
|
521
|
+
this.waitingForParticipant = true;
|
|
522
|
+
this.onMessagingChanged();
|
|
523
|
+
}
|
|
524
|
+
else if (status === "disconnected" || status === "reconnecting" || status === "connecting") {
|
|
525
|
+
this.agentParticipantId = undefined;
|
|
526
|
+
this.waitingForParticipant = true;
|
|
527
|
+
this.emitConnectionStatus({
|
|
528
|
+
status: status === "disconnected" ? "disconnected" : "reconnecting",
|
|
529
|
+
message: message !== "" ? message : status === "disconnected" ? "Agent messaging disconnected" : "Waiting for agent messaging",
|
|
530
|
+
reason: message !== "" ? message : undefined,
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
})().catch(() => undefined);
|
|
535
|
+
}
|
|
536
|
+
async reopenOpenSessions() {
|
|
537
|
+
for (const session of this.sessions) {
|
|
538
|
+
if (!session.isOpen) {
|
|
539
|
+
continue;
|
|
540
|
+
}
|
|
541
|
+
await session.open({ load: true, sinceTurn: session.lastCompletedTurnId });
|
|
542
|
+
}
|
|
543
|
+
}
|
|
436
544
|
}
|
|
437
545
|
function isThreadListMessage(message) {
|
|
438
546
|
return message.type === agentThreadListedType
|
|
@@ -763,7 +871,7 @@ export class ChatThreadSession extends ChangeEmitter {
|
|
|
763
871
|
return;
|
|
764
872
|
}
|
|
765
873
|
if (message.type === agentToolCallEndedType) {
|
|
766
|
-
const itemId = normalizedString(message.itemId);
|
|
874
|
+
const itemId = message.error == null ? undefined : normalizedString(message.itemId);
|
|
767
875
|
if (itemId != null) {
|
|
768
876
|
this.upsertItemMessage(`tool_call:${itemId}`, event);
|
|
769
877
|
}
|
|
@@ -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;
|
|
@@ -358,6 +358,12 @@ export class AgentThreadStorageRepository extends ThreadStorageRepository {
|
|
|
358
358
|
}
|
|
359
359
|
handleEvent(event) {
|
|
360
360
|
const message = event.message;
|
|
361
|
+
if (message.type === "meshagent.agent.connection.status") {
|
|
362
|
+
if (String(message.status ?? "").trim().toLowerCase() === "reconnected") {
|
|
363
|
+
void this.reconnectWatch();
|
|
364
|
+
}
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
361
367
|
if (message.type === "meshagent.agent.thread.listed") {
|
|
362
368
|
this.handleThreadsListed(message);
|
|
363
369
|
return;
|
|
@@ -377,6 +383,13 @@ export class AgentThreadStorageRepository extends ThreadStorageRepository {
|
|
|
377
383
|
}
|
|
378
384
|
}
|
|
379
385
|
}
|
|
386
|
+
async reconnectWatch() {
|
|
387
|
+
if (this.closed) {
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
await this.chatClient.sendAgentMessage(new WatchThreads(), { ignoreOffline: true });
|
|
391
|
+
await this.requestList();
|
|
392
|
+
}
|
|
380
393
|
handleThreadsListed(message) {
|
|
381
394
|
const nextEntries = new Map();
|
|
382
395
|
for (const thread of message.threads) {
|
|
@@ -137,6 +137,11 @@ export declare class MessagingChatClient extends BaseChatClient {
|
|
|
137
137
|
readonly agentName?: string;
|
|
138
138
|
private readonly pendingParticipantWaits;
|
|
139
139
|
private started;
|
|
140
|
+
private agentParticipantId?;
|
|
141
|
+
private hasConnected;
|
|
142
|
+
private waitingForParticipant;
|
|
143
|
+
private roomAbortController?;
|
|
144
|
+
private messagingListenersAttached;
|
|
140
145
|
constructor({ room, agentName }: {
|
|
141
146
|
room: RoomClient;
|
|
142
147
|
agentName?: string;
|
|
@@ -144,6 +149,8 @@ export declare class MessagingChatClient extends BaseChatClient {
|
|
|
144
149
|
localParticipantName(): string | undefined;
|
|
145
150
|
start(): Promise<void>;
|
|
146
151
|
stop(): Promise<void>;
|
|
152
|
+
private attachMessagingListeners;
|
|
153
|
+
private detachMessagingListeners;
|
|
147
154
|
agentParticipant(): RemoteParticipant | null;
|
|
148
155
|
waitForAgentParticipant({ waitKey }?: {
|
|
149
156
|
waitKey?: string;
|
|
@@ -153,6 +160,10 @@ export declare class MessagingChatClient extends BaseChatClient {
|
|
|
153
160
|
ignoreOffline?: boolean;
|
|
154
161
|
}): Promise<void>;
|
|
155
162
|
private readonly onMessagingChanged;
|
|
163
|
+
private readonly onMessagingParticipantChanged;
|
|
164
|
+
private readonly onMessagingParticipantRemoved;
|
|
165
|
+
private startRoomStatusListener;
|
|
166
|
+
private reopenOpenSessions;
|
|
156
167
|
private readonly onMessagingMessage;
|
|
157
168
|
}
|
|
158
169
|
export declare class ChatThreadSession extends ChangeEmitter {
|
package/dist/node/chat-client.js
CHANGED
|
@@ -282,11 +282,6 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
|
|
|
282
282
|
handleAgentMessage(message, { createdAt, attachment } = {}) {
|
|
283
283
|
if (message.type === agent_messages_js_1.agentConnectionStatusType) {
|
|
284
284
|
this._connectionStatus = message;
|
|
285
|
-
for (const session of this.sessionsByPath.values()) {
|
|
286
|
-
if (session.isOpen) {
|
|
287
|
-
session.addAgentMessage(new AgentMessageEvent({ message, createdAt, attachment }));
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
285
|
}
|
|
291
286
|
this.eventQueue.add(new AgentMessageEvent({ message, createdAt, attachment }));
|
|
292
287
|
const sourceMessageId = sourceMessageIdFor(message);
|
|
@@ -324,11 +319,6 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
|
|
|
324
319
|
});
|
|
325
320
|
this._connectionStatus = event;
|
|
326
321
|
this.eventQueue.add(new AgentMessageEvent({ message: event }));
|
|
327
|
-
for (const session of this.sessionsByPath.values()) {
|
|
328
|
-
if (session.isOpen) {
|
|
329
|
-
session.addAgentMessage(new AgentMessageEvent({ message: event }));
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
322
|
this.notifyListeners();
|
|
333
323
|
}
|
|
334
324
|
removeThreadSession(threadPath) {
|
|
@@ -347,10 +337,50 @@ class MessagingChatClient extends BaseChatClient {
|
|
|
347
337
|
super();
|
|
348
338
|
this.pendingParticipantWaits = new Map();
|
|
349
339
|
this.started = false;
|
|
340
|
+
this.hasConnected = false;
|
|
341
|
+
this.waitingForParticipant = false;
|
|
342
|
+
this.messagingListenersAttached = false;
|
|
350
343
|
this.onMessagingChanged = () => {
|
|
351
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
|
+
}
|
|
352
383
|
if (participant != null) {
|
|
353
|
-
this.emitConnectionStatus({ status: "connected", message: "Agent messaging connected" });
|
|
354
384
|
for (const wait of this.pendingParticipantWaits.values()) {
|
|
355
385
|
if (!wait.completed) {
|
|
356
386
|
wait.complete(participant);
|
|
@@ -359,6 +389,12 @@ class MessagingChatClient extends BaseChatClient {
|
|
|
359
389
|
}
|
|
360
390
|
this.notifyListeners();
|
|
361
391
|
};
|
|
392
|
+
this.onMessagingParticipantChanged = () => {
|
|
393
|
+
this.onMessagingChanged();
|
|
394
|
+
};
|
|
395
|
+
this.onMessagingParticipantRemoved = () => {
|
|
396
|
+
this.onMessagingChanged();
|
|
397
|
+
};
|
|
362
398
|
this.onMessagingMessage = (event) => {
|
|
363
399
|
this.onMessagingChanged();
|
|
364
400
|
const roomMessage = agentRoomMessageFromEvent(event);
|
|
@@ -378,7 +414,7 @@ class MessagingChatClient extends BaseChatClient {
|
|
|
378
414
|
};
|
|
379
415
|
this.room = room;
|
|
380
416
|
this.agentName = agentName;
|
|
381
|
-
this.
|
|
417
|
+
this.attachMessagingListeners();
|
|
382
418
|
}
|
|
383
419
|
localParticipantName() {
|
|
384
420
|
const name = this.room.localParticipant?.getAttribute("name");
|
|
@@ -389,12 +425,18 @@ class MessagingChatClient extends BaseChatClient {
|
|
|
389
425
|
return;
|
|
390
426
|
}
|
|
391
427
|
this.started = true;
|
|
428
|
+
this.attachMessagingListeners();
|
|
392
429
|
this.room.messaging.start();
|
|
393
|
-
this.
|
|
430
|
+
this.startRoomStatusListener();
|
|
431
|
+
await this.room.messaging.enable();
|
|
432
|
+
this.waitingForParticipant = true;
|
|
433
|
+
this.onMessagingChanged();
|
|
394
434
|
}
|
|
395
435
|
async stop() {
|
|
396
436
|
this.started = false;
|
|
397
|
-
this.
|
|
437
|
+
this.roomAbortController?.abort();
|
|
438
|
+
this.roomAbortController = undefined;
|
|
439
|
+
this.detachMessagingListeners();
|
|
398
440
|
for (const wait of this.pendingParticipantWaits.values()) {
|
|
399
441
|
if (!wait.completed) {
|
|
400
442
|
wait.completeError(new Error("Chat client stopped while waiting for an agent participant."));
|
|
@@ -402,12 +444,35 @@ class MessagingChatClient extends BaseChatClient {
|
|
|
402
444
|
}
|
|
403
445
|
this.pendingParticipantWaits.clear();
|
|
404
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
|
+
}
|
|
405
467
|
agentParticipant() {
|
|
406
468
|
const normalizedAgentName = this.agentName?.trim();
|
|
407
469
|
for (const participant of this.room.messaging.remoteParticipants) {
|
|
408
470
|
if (normalizedAgentName != null && normalizedAgentName !== "" && participant.getAttribute("name") !== normalizedAgentName) {
|
|
409
471
|
continue;
|
|
410
472
|
}
|
|
473
|
+
if (normalizedAgentName != null && normalizedAgentName !== "") {
|
|
474
|
+
return participant;
|
|
475
|
+
}
|
|
411
476
|
if (participant.getAttribute("supports_agent_messages") === true) {
|
|
412
477
|
return participant;
|
|
413
478
|
}
|
|
@@ -432,7 +497,13 @@ class MessagingChatClient extends BaseChatClient {
|
|
|
432
497
|
}
|
|
433
498
|
async sendAgentMessage(message, { attachment, ignoreOffline = false } = {}) {
|
|
434
499
|
await this.start();
|
|
435
|
-
|
|
500
|
+
let participant = this.agentParticipant();
|
|
501
|
+
if (participant == null) {
|
|
502
|
+
if (ignoreOffline) {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
participant = await this.waitForAgentParticipant({ waitKey: message.messageId });
|
|
506
|
+
}
|
|
436
507
|
await this.room.messaging.sendMessage({
|
|
437
508
|
to: participant,
|
|
438
509
|
type: agent_messages_js_1.agentRoomMessageType,
|
|
@@ -441,6 +512,43 @@ class MessagingChatClient extends BaseChatClient {
|
|
|
441
512
|
ignoreOffline,
|
|
442
513
|
});
|
|
443
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
|
+
}
|
|
444
552
|
}
|
|
445
553
|
exports.MessagingChatClient = MessagingChatClient;
|
|
446
554
|
function isThreadListMessage(message) {
|
|
@@ -772,7 +880,7 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
|
|
|
772
880
|
return;
|
|
773
881
|
}
|
|
774
882
|
if (message.type === agent_messages_js_1.agentToolCallEndedType) {
|
|
775
|
-
const itemId = normalizedString(message.itemId);
|
|
883
|
+
const itemId = message.error == null ? undefined : normalizedString(message.itemId);
|
|
776
884
|
if (itemId != null) {
|
|
777
885
|
this.upsertItemMessage(`tool_call:${itemId}`, event);
|
|
778
886
|
}
|
|
@@ -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;
|
|
@@ -367,6 +367,12 @@ class AgentThreadStorageRepository extends ThreadStorageRepository {
|
|
|
367
367
|
}
|
|
368
368
|
handleEvent(event) {
|
|
369
369
|
const message = event.message;
|
|
370
|
+
if (message.type === "meshagent.agent.connection.status") {
|
|
371
|
+
if (String(message.status ?? "").trim().toLowerCase() === "reconnected") {
|
|
372
|
+
void this.reconnectWatch();
|
|
373
|
+
}
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
370
376
|
if (message.type === "meshagent.agent.thread.listed") {
|
|
371
377
|
this.handleThreadsListed(message);
|
|
372
378
|
return;
|
|
@@ -386,6 +392,13 @@ class AgentThreadStorageRepository extends ThreadStorageRepository {
|
|
|
386
392
|
}
|
|
387
393
|
}
|
|
388
394
|
}
|
|
395
|
+
async reconnectWatch() {
|
|
396
|
+
if (this.closed) {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
await this.chatClient.sendAgentMessage(new agent_messages_js_1.WatchThreads(), { ignoreOffline: true });
|
|
400
|
+
await this.requestList();
|
|
401
|
+
}
|
|
389
402
|
handleThreadsListed(message) {
|
|
390
403
|
const nextEntries = new Map();
|
|
391
404
|
for (const thread of message.threads) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meshagent/meshagent-agents",
|
|
3
|
-
"version": "0.44.
|
|
3
|
+
"version": "0.44.2",
|
|
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": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"typescript": "^5.8.2"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@meshagent/meshagent": "^0.44.
|
|
50
|
+
"@meshagent/meshagent": "^0.44.2",
|
|
51
51
|
"apache-arrow": "^21.0.0",
|
|
52
52
|
"uuid": "^14.0.0"
|
|
53
53
|
},
|