@meshagent/meshagent-agents 0.47.0 → 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.
- package/CHANGELOG.md +5 -0
- package/dist/browser/chat-client.d.ts +36 -2
- package/dist/browser/chat-client.js +153 -2
- package/dist/esm/chat-client.d.ts +36 -2
- package/dist/esm/chat-client.js +150 -2
- package/dist/node/chat-client.d.ts +36 -2
- package/dist/node/chat-client.js +153 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## [0.47.1]
|
|
2
|
+
- Added duplex messaging stream subscriptions and replay-state alignment in the TypeScript chat clients, bringing the NodeJS SDK in line with the new streaming model.
|
|
3
|
+
- Reworked messaging and room client flow control so dispatch ordering, close behavior, and presence updates stay consistent under streaming loads.
|
|
4
|
+
- Expanded stream and presence test coverage for the new messaging behavior.
|
|
5
|
+
|
|
1
6
|
## [0.47.0]
|
|
2
7
|
- Improved TypeScript messaging clients so room delivery order and startup/presence behavior stay consistent.
|
|
3
8
|
- Moved managed-agent client routing onto the Rust tunnel path and hardened agent chat-client event handling.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RemoteParticipant } from "@meshagent/meshagent";
|
|
1
|
+
import { MessagingStream, RemoteParticipant } from "@meshagent/meshagent";
|
|
2
2
|
import type { RoomClient, Content } from "@meshagent/meshagent";
|
|
3
3
|
import { AgentMessage, AgentModelChanged, AgentThreadStatus, ModelsResponse, ToolChoice, AgentConnectionStatus, AgentClientToolCallRequested } from "./agent-messages.js";
|
|
4
4
|
import type { AgentPayload, JsonMap, ClientToolkitDescription } from "./agent-messages.js";
|
|
@@ -133,7 +133,30 @@ export declare abstract class BaseChatClient extends ChangeEmitter {
|
|
|
133
133
|
}): void;
|
|
134
134
|
removeThreadSession(threadPath: string): void;
|
|
135
135
|
}
|
|
136
|
-
export declare
|
|
136
|
+
export declare const messagingChatThreadSubscribeType = "meshagent.chat.thread.subscribe";
|
|
137
|
+
export declare const messagingChatThreadListSubscribeType = "meshagent.chat.thread_list.subscribe";
|
|
138
|
+
export declare class ThreadSubscribe {
|
|
139
|
+
readonly threadId: string;
|
|
140
|
+
readonly stream: MessagingStream;
|
|
141
|
+
constructor({ threadId, stream }: {
|
|
142
|
+
threadId: string;
|
|
143
|
+
stream: MessagingStream;
|
|
144
|
+
});
|
|
145
|
+
get closed(): boolean;
|
|
146
|
+
send(message: AgentMessage, { attachment }?: {
|
|
147
|
+
attachment?: Uint8Array;
|
|
148
|
+
}): Promise<void>;
|
|
149
|
+
close(): Promise<void>;
|
|
150
|
+
}
|
|
151
|
+
export declare class ThreadListSubscribe {
|
|
152
|
+
readonly stream: MessagingStream;
|
|
153
|
+
constructor({ stream }: {
|
|
154
|
+
stream: MessagingStream;
|
|
155
|
+
});
|
|
156
|
+
get closed(): boolean;
|
|
157
|
+
close(): Promise<void>;
|
|
158
|
+
}
|
|
159
|
+
export declare class BaseMessagingChatClient extends BaseChatClient {
|
|
137
160
|
readonly room: RoomClient;
|
|
138
161
|
readonly agentName?: string;
|
|
139
162
|
private readonly pendingParticipantWaits;
|
|
@@ -167,6 +190,17 @@ export declare class MessagingChatClient extends BaseChatClient {
|
|
|
167
190
|
private reopenOpenSessions;
|
|
168
191
|
private readonly onMessagingMessage;
|
|
169
192
|
}
|
|
193
|
+
export declare class MessagingChatClient extends BaseMessagingChatClient {
|
|
194
|
+
private readonly threadSubscriptions;
|
|
195
|
+
private threadListSubscription?;
|
|
196
|
+
private readonly streamTasks;
|
|
197
|
+
stop(): Promise<void>;
|
|
198
|
+
private supportsThreadSubscriptions;
|
|
199
|
+
private trackStream;
|
|
200
|
+
sendAgentMessage(message: AgentMessage, { attachment }?: {
|
|
201
|
+
attachment?: Uint8Array;
|
|
202
|
+
}): Promise<void>;
|
|
203
|
+
}
|
|
170
204
|
export declare class ChatThreadSession extends ChangeEmitter {
|
|
171
205
|
private readonly client;
|
|
172
206
|
readonly threadPath: string;
|
|
@@ -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");
|
|
@@ -343,7 +343,41 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
|
|
|
343
343
|
}
|
|
344
344
|
}
|
|
345
345
|
exports.BaseChatClient = BaseChatClient;
|
|
346
|
-
|
|
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 {
|
|
347
381
|
constructor({ room, agentName }) {
|
|
348
382
|
super();
|
|
349
383
|
this.pendingParticipantWaits = new Map();
|
|
@@ -560,6 +594,123 @@ class MessagingChatClient extends BaseChatClient {
|
|
|
560
594
|
}
|
|
561
595
|
}
|
|
562
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
|
+
}
|
|
563
714
|
exports.MessagingChatClient = MessagingChatClient;
|
|
564
715
|
function isThreadListMessage(message) {
|
|
565
716
|
return message.type === agent_messages_js_1.agentThreadListedType
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RemoteParticipant } from "@meshagent/meshagent";
|
|
1
|
+
import { MessagingStream, RemoteParticipant } from "@meshagent/meshagent";
|
|
2
2
|
import type { RoomClient, Content } from "@meshagent/meshagent";
|
|
3
3
|
import { AgentMessage, AgentModelChanged, AgentThreadStatus, ModelsResponse, ToolChoice, AgentConnectionStatus, AgentClientToolCallRequested } from "./agent-messages.js";
|
|
4
4
|
import type { AgentPayload, JsonMap, ClientToolkitDescription } from "./agent-messages.js";
|
|
@@ -133,7 +133,30 @@ export declare abstract class BaseChatClient extends ChangeEmitter {
|
|
|
133
133
|
}): void;
|
|
134
134
|
removeThreadSession(threadPath: string): void;
|
|
135
135
|
}
|
|
136
|
-
export declare
|
|
136
|
+
export declare const messagingChatThreadSubscribeType = "meshagent.chat.thread.subscribe";
|
|
137
|
+
export declare const messagingChatThreadListSubscribeType = "meshagent.chat.thread_list.subscribe";
|
|
138
|
+
export declare class ThreadSubscribe {
|
|
139
|
+
readonly threadId: string;
|
|
140
|
+
readonly stream: MessagingStream;
|
|
141
|
+
constructor({ threadId, stream }: {
|
|
142
|
+
threadId: string;
|
|
143
|
+
stream: MessagingStream;
|
|
144
|
+
});
|
|
145
|
+
get closed(): boolean;
|
|
146
|
+
send(message: AgentMessage, { attachment }?: {
|
|
147
|
+
attachment?: Uint8Array;
|
|
148
|
+
}): Promise<void>;
|
|
149
|
+
close(): Promise<void>;
|
|
150
|
+
}
|
|
151
|
+
export declare class ThreadListSubscribe {
|
|
152
|
+
readonly stream: MessagingStream;
|
|
153
|
+
constructor({ stream }: {
|
|
154
|
+
stream: MessagingStream;
|
|
155
|
+
});
|
|
156
|
+
get closed(): boolean;
|
|
157
|
+
close(): Promise<void>;
|
|
158
|
+
}
|
|
159
|
+
export declare class BaseMessagingChatClient extends BaseChatClient {
|
|
137
160
|
readonly room: RoomClient;
|
|
138
161
|
readonly agentName?: string;
|
|
139
162
|
private readonly pendingParticipantWaits;
|
|
@@ -167,6 +190,17 @@ export declare class MessagingChatClient extends BaseChatClient {
|
|
|
167
190
|
private reopenOpenSessions;
|
|
168
191
|
private readonly onMessagingMessage;
|
|
169
192
|
}
|
|
193
|
+
export declare class MessagingChatClient extends BaseMessagingChatClient {
|
|
194
|
+
private readonly threadSubscriptions;
|
|
195
|
+
private threadListSubscription?;
|
|
196
|
+
private readonly streamTasks;
|
|
197
|
+
stop(): Promise<void>;
|
|
198
|
+
private supportsThreadSubscriptions;
|
|
199
|
+
private trackStream;
|
|
200
|
+
sendAgentMessage(message: AgentMessage, { attachment }?: {
|
|
201
|
+
attachment?: Uint8Array;
|
|
202
|
+
}): Promise<void>;
|
|
203
|
+
}
|
|
170
204
|
export declare class ChatThreadSession extends ChangeEmitter {
|
|
171
205
|
private readonly client;
|
|
172
206
|
readonly threadPath: string;
|
package/dist/esm/chat-client.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Completer, } from "@meshagent/meshagent";
|
|
2
2
|
import { v4 as uuidv4 } from "uuid";
|
|
3
|
-
import { AgentMessage as AgentMessageFactory, AgentAudioGenerationDelta, AgentAudioTranscriptionDelta, AgentRealtimeAudioChunk, AgentRealtimeAudioCommit, AgentFileContentDelta, AgentModelChanged, AgentReasoningContentDelta, AgentTextContentDelta, AgentThreadStatus, AgentToolCallArgumentsDelta, AgentToolCallLogDelta, ChangeModel, CloseThread, DeleteThread, ModelsResponse, ModelsRequest, OpenThread, RenameThread, StartThread, AgentConnectionStatus, TurnInterrupt, TurnStart, TurnSteer, AgentClientToolCallRequested, AgentClientToolCallResponse, agentInputContent, agentAudioGenerationDeltaType, agentAudioTranscriptionDeltaType, agentFileContentDeltaType, agentImageGenerationCompletedType, agentImageGenerationPartialType, agentModelChangedType, agentModelsResponseType, agentReasoningContentDeltaType, agentRoomMessageType, agentTextContentDeltaType, agentThreadClearedType, agentThreadCreatedType, agentThreadDeletedType, agentThreadLoadedType, agentThreadListedType, agentThreadUpdatedType, agentConnectionStatusType, agentThreadStatusType, agentThreadStartType, agentThreadStartRejectedType, agentThreadStartedType, agentToolCallArgumentsDeltaType, agentToolCallLogDeltaType, agentToolCallEndedType, agentToolCallInProgressType, agentToolCallPendingType, agentToolCallStartedType, agentSecretRequestedType, agentTurnEndedType, agentTurnInterruptAcceptedType, agentTurnInterruptedType, agentTurnStartAcceptedType, agentTurnStartRejectedType, agentTurnStartType, agentTurnStartedType, agentTurnSteerAcceptedType, agentTurnSteerRejectedType, agentTurnSteerType, agentTurnSteeredType, agentUsageUpdatedType, } from "./agent-messages.js";
|
|
3
|
+
import { AgentMessage as AgentMessageFactory, AgentAudioGenerationDelta, AgentAudioTranscriptionDelta, AgentRealtimeAudioChunk, AgentRealtimeAudioCommit, AgentFileContentDelta, AgentModelChanged, AgentReasoningContentDelta, AgentTextContentDelta, AgentThreadStatus, AgentToolCallArgumentsDelta, AgentToolCallLogDelta, ChangeModel, CloseThread, DeleteThread, ModelsResponse, ModelsRequest, OpenThread, RenameThread, StartThread, AgentConnectionStatus, TurnInterrupt, TurnStart, TurnSteer, AgentClientToolCallRequested, AgentClientToolCallResponse, agentInputContent, agentAudioGenerationDeltaType, agentAudioTranscriptionDeltaType, agentFileContentDeltaType, agentImageGenerationCompletedType, agentImageGenerationPartialType, agentModelChangedType, agentModelsResponseType, agentReasoningContentDeltaType, agentRoomMessageType, agentTextContentDeltaType, agentThreadClearedType, agentThreadCreatedType, agentThreadDeletedType, agentThreadLoadedType, agentThreadListedType, agentThreadCloseType, agentThreadOpenType, agentThreadUnwatchType, agentThreadUpdatedType, agentThreadWatchType, agentConnectionStatusType, agentThreadStatusType, agentThreadStartType, agentThreadStartRejectedType, agentThreadStartedType, agentToolCallArgumentsDeltaType, agentToolCallLogDeltaType, agentToolCallEndedType, agentToolCallInProgressType, agentToolCallPendingType, agentToolCallStartedType, agentSecretRequestedType, agentTurnEndedType, agentTurnInterruptAcceptedType, agentTurnInterruptedType, agentTurnStartAcceptedType, agentTurnStartRejectedType, agentTurnStartType, agentTurnStartedType, agentTurnSteerAcceptedType, agentTurnSteerRejectedType, agentTurnSteerType, agentTurnSteeredType, agentUsageUpdatedType, } from "./agent-messages.js";
|
|
4
4
|
import { ChangeEmitter } from "./change-emitter.js";
|
|
5
5
|
export class AgentMessageEvent {
|
|
6
6
|
constructor({ message, createdAt, attachment }) {
|
|
@@ -335,7 +335,39 @@ export class BaseChatClient extends ChangeEmitter {
|
|
|
335
335
|
}
|
|
336
336
|
}
|
|
337
337
|
}
|
|
338
|
-
export
|
|
338
|
+
export const messagingChatThreadSubscribeType = "meshagent.chat.thread.subscribe";
|
|
339
|
+
export const messagingChatThreadListSubscribeType = "meshagent.chat.thread_list.subscribe";
|
|
340
|
+
export class ThreadSubscribe {
|
|
341
|
+
constructor({ threadId, stream }) {
|
|
342
|
+
this.threadId = threadId;
|
|
343
|
+
this.stream = stream;
|
|
344
|
+
}
|
|
345
|
+
get closed() {
|
|
346
|
+
return this.stream.closed;
|
|
347
|
+
}
|
|
348
|
+
async send(message, { attachment } = {}) {
|
|
349
|
+
await this.stream.sendMessage({
|
|
350
|
+
type: agentRoomMessageType,
|
|
351
|
+
message: message.toJson(),
|
|
352
|
+
attachment,
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
async close() {
|
|
356
|
+
await this.stream.close();
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
export class ThreadListSubscribe {
|
|
360
|
+
constructor({ stream }) {
|
|
361
|
+
this.stream = stream;
|
|
362
|
+
}
|
|
363
|
+
get closed() {
|
|
364
|
+
return this.stream.closed;
|
|
365
|
+
}
|
|
366
|
+
async close() {
|
|
367
|
+
await this.stream.close();
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
export class BaseMessagingChatClient extends BaseChatClient {
|
|
339
371
|
constructor({ room, agentName }) {
|
|
340
372
|
super();
|
|
341
373
|
this.pendingParticipantWaits = new Map();
|
|
@@ -552,6 +584,122 @@ export class MessagingChatClient extends BaseChatClient {
|
|
|
552
584
|
}
|
|
553
585
|
}
|
|
554
586
|
}
|
|
587
|
+
export class MessagingChatClient extends BaseMessagingChatClient {
|
|
588
|
+
constructor() {
|
|
589
|
+
super(...arguments);
|
|
590
|
+
this.threadSubscriptions = new Map();
|
|
591
|
+
this.streamTasks = new Set();
|
|
592
|
+
}
|
|
593
|
+
async stop() {
|
|
594
|
+
const subscriptions = [
|
|
595
|
+
...this.threadSubscriptions.values(),
|
|
596
|
+
];
|
|
597
|
+
if (this.threadListSubscription != null) {
|
|
598
|
+
subscriptions.push(this.threadListSubscription);
|
|
599
|
+
}
|
|
600
|
+
this.threadSubscriptions.clear();
|
|
601
|
+
this.threadListSubscription = undefined;
|
|
602
|
+
await Promise.all(subscriptions.map(async (subscription) => subscription.close()));
|
|
603
|
+
await Promise.all(this.streamTasks);
|
|
604
|
+
await super.stop();
|
|
605
|
+
}
|
|
606
|
+
supportsThreadSubscriptions(participant) {
|
|
607
|
+
return participant.getAttribute("supports_messaging_streams") === true;
|
|
608
|
+
}
|
|
609
|
+
trackStream(subscription) {
|
|
610
|
+
const task = (async () => {
|
|
611
|
+
try {
|
|
612
|
+
for await (const event of subscription.stream) {
|
|
613
|
+
if (event.kind !== "message" || event.message.type !== agentRoomMessageType) {
|
|
614
|
+
continue;
|
|
615
|
+
}
|
|
616
|
+
const raw = event.message.message;
|
|
617
|
+
if (typeof raw["type"] !== "string") {
|
|
618
|
+
continue;
|
|
619
|
+
}
|
|
620
|
+
this.handleAgentMessage(AgentMessageFactory.fromJson(raw), {
|
|
621
|
+
createdAt: dateOrNull(raw["created_at"]),
|
|
622
|
+
attachment: event.message.attachment,
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
finally {
|
|
627
|
+
if (subscription instanceof ThreadSubscribe) {
|
|
628
|
+
if (this.threadSubscriptions.get(subscription.threadId) === subscription) {
|
|
629
|
+
this.threadSubscriptions.delete(subscription.threadId);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
else if (this.threadListSubscription === subscription) {
|
|
633
|
+
this.threadListSubscription = undefined;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
})();
|
|
637
|
+
this.streamTasks.add(task);
|
|
638
|
+
void task.finally(() => this.streamTasks.delete(task));
|
|
639
|
+
}
|
|
640
|
+
async sendAgentMessage(message, { attachment } = {}) {
|
|
641
|
+
await this.start();
|
|
642
|
+
const participant = this.agentParticipant();
|
|
643
|
+
if (participant == null) {
|
|
644
|
+
throw new Error("Agent messaging participant is not available.");
|
|
645
|
+
}
|
|
646
|
+
if (!this.supportsThreadSubscriptions(participant)) {
|
|
647
|
+
await super.sendAgentMessage(message, { attachment });
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
if (message.type === agentThreadOpenType) {
|
|
651
|
+
const previous = this.threadSubscriptions.get(message.threadId);
|
|
652
|
+
if (previous != null) {
|
|
653
|
+
await previous.close();
|
|
654
|
+
}
|
|
655
|
+
const stream = await this.room.messaging.stream({
|
|
656
|
+
to: participant,
|
|
657
|
+
type: messagingChatThreadSubscribeType,
|
|
658
|
+
message: message.toJson(),
|
|
659
|
+
attachment,
|
|
660
|
+
});
|
|
661
|
+
const subscription = new ThreadSubscribe({ threadId: message.threadId, stream });
|
|
662
|
+
this.threadSubscriptions.set(message.threadId, subscription);
|
|
663
|
+
this.trackStream(subscription);
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
if (message.type === agentThreadCloseType) {
|
|
667
|
+
const subscription = this.threadSubscriptions.get(message.threadId);
|
|
668
|
+
if (subscription != null) {
|
|
669
|
+
this.threadSubscriptions.delete(message.threadId);
|
|
670
|
+
await subscription.close();
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
if (message.type === agentThreadWatchType) {
|
|
675
|
+
await this.threadListSubscription?.close();
|
|
676
|
+
const stream = await this.room.messaging.stream({
|
|
677
|
+
to: participant,
|
|
678
|
+
type: messagingChatThreadListSubscribeType,
|
|
679
|
+
message: message.toJson(),
|
|
680
|
+
attachment,
|
|
681
|
+
});
|
|
682
|
+
const subscription = new ThreadListSubscribe({ stream });
|
|
683
|
+
this.threadListSubscription = subscription;
|
|
684
|
+
this.trackStream(subscription);
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
if (message.type === agentThreadUnwatchType && this.threadListSubscription != null) {
|
|
688
|
+
const subscription = this.threadListSubscription;
|
|
689
|
+
this.threadListSubscription = undefined;
|
|
690
|
+
await subscription.close();
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
if ("threadId" in message && typeof message.threadId === "string") {
|
|
694
|
+
const subscription = this.threadSubscriptions.get(message.threadId);
|
|
695
|
+
if (subscription != null) {
|
|
696
|
+
await subscription.send(message, { attachment });
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
await super.sendAgentMessage(message, { attachment });
|
|
701
|
+
}
|
|
702
|
+
}
|
|
555
703
|
function isThreadListMessage(message) {
|
|
556
704
|
return message.type === agentThreadListedType
|
|
557
705
|
|| message.type === agentThreadCreatedType
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RemoteParticipant } from "@meshagent/meshagent";
|
|
1
|
+
import { MessagingStream, RemoteParticipant } from "@meshagent/meshagent";
|
|
2
2
|
import type { RoomClient, Content } from "@meshagent/meshagent";
|
|
3
3
|
import { AgentMessage, AgentModelChanged, AgentThreadStatus, ModelsResponse, ToolChoice, AgentConnectionStatus, AgentClientToolCallRequested } from "./agent-messages.js";
|
|
4
4
|
import type { AgentPayload, JsonMap, ClientToolkitDescription } from "./agent-messages.js";
|
|
@@ -133,7 +133,30 @@ export declare abstract class BaseChatClient extends ChangeEmitter {
|
|
|
133
133
|
}): void;
|
|
134
134
|
removeThreadSession(threadPath: string): void;
|
|
135
135
|
}
|
|
136
|
-
export declare
|
|
136
|
+
export declare const messagingChatThreadSubscribeType = "meshagent.chat.thread.subscribe";
|
|
137
|
+
export declare const messagingChatThreadListSubscribeType = "meshagent.chat.thread_list.subscribe";
|
|
138
|
+
export declare class ThreadSubscribe {
|
|
139
|
+
readonly threadId: string;
|
|
140
|
+
readonly stream: MessagingStream;
|
|
141
|
+
constructor({ threadId, stream }: {
|
|
142
|
+
threadId: string;
|
|
143
|
+
stream: MessagingStream;
|
|
144
|
+
});
|
|
145
|
+
get closed(): boolean;
|
|
146
|
+
send(message: AgentMessage, { attachment }?: {
|
|
147
|
+
attachment?: Uint8Array;
|
|
148
|
+
}): Promise<void>;
|
|
149
|
+
close(): Promise<void>;
|
|
150
|
+
}
|
|
151
|
+
export declare class ThreadListSubscribe {
|
|
152
|
+
readonly stream: MessagingStream;
|
|
153
|
+
constructor({ stream }: {
|
|
154
|
+
stream: MessagingStream;
|
|
155
|
+
});
|
|
156
|
+
get closed(): boolean;
|
|
157
|
+
close(): Promise<void>;
|
|
158
|
+
}
|
|
159
|
+
export declare class BaseMessagingChatClient extends BaseChatClient {
|
|
137
160
|
readonly room: RoomClient;
|
|
138
161
|
readonly agentName?: string;
|
|
139
162
|
private readonly pendingParticipantWaits;
|
|
@@ -167,6 +190,17 @@ export declare class MessagingChatClient extends BaseChatClient {
|
|
|
167
190
|
private reopenOpenSessions;
|
|
168
191
|
private readonly onMessagingMessage;
|
|
169
192
|
}
|
|
193
|
+
export declare class MessagingChatClient extends BaseMessagingChatClient {
|
|
194
|
+
private readonly threadSubscriptions;
|
|
195
|
+
private threadListSubscription?;
|
|
196
|
+
private readonly streamTasks;
|
|
197
|
+
stop(): Promise<void>;
|
|
198
|
+
private supportsThreadSubscriptions;
|
|
199
|
+
private trackStream;
|
|
200
|
+
sendAgentMessage(message: AgentMessage, { attachment }?: {
|
|
201
|
+
attachment?: Uint8Array;
|
|
202
|
+
}): Promise<void>;
|
|
203
|
+
}
|
|
170
204
|
export declare class ChatThreadSession extends ChangeEmitter {
|
|
171
205
|
private readonly client;
|
|
172
206
|
readonly threadPath: string;
|
package/dist/node/chat-client.js
CHANGED
|
@@ -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");
|
|
@@ -343,7 +343,41 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
|
|
|
343
343
|
}
|
|
344
344
|
}
|
|
345
345
|
exports.BaseChatClient = BaseChatClient;
|
|
346
|
-
|
|
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 {
|
|
347
381
|
constructor({ room, agentName }) {
|
|
348
382
|
super();
|
|
349
383
|
this.pendingParticipantWaits = new Map();
|
|
@@ -560,6 +594,123 @@ class MessagingChatClient extends BaseChatClient {
|
|
|
560
594
|
}
|
|
561
595
|
}
|
|
562
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
|
+
}
|
|
563
714
|
exports.MessagingChatClient = MessagingChatClient;
|
|
564
715
|
function isThreadListMessage(message) {
|
|
565
716
|
return message.type === agent_messages_js_1.agentThreadListedType
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meshagent/meshagent-agents",
|
|
3
|
-
"version": "0.47.
|
|
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": {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"typescript": "^5.8.2"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@meshagent/meshagent": "^0.47.
|
|
51
|
+
"@meshagent/meshagent": "^0.47.1",
|
|
52
52
|
"apache-arrow": "^21.0.0",
|
|
53
53
|
"uuid": "^14.0.0"
|
|
54
54
|
},
|