@meshagent/meshagent 0.46.3 → 0.47.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/browser/meshagent-client.d.ts +8 -0
- package/dist/browser/meshagent-client.js +27 -0
- package/dist/browser/messaging-client.d.ts +2 -0
- package/dist/browser/messaging-client.js +48 -27
- package/dist/browser/room-client.d.ts +3 -1
- package/dist/browser/room-client.js +4 -2
- package/dist/esm/meshagent-client.d.ts +8 -0
- package/dist/esm/meshagent-client.js +27 -0
- package/dist/esm/messaging-client.d.ts +2 -0
- package/dist/esm/messaging-client.js +48 -27
- package/dist/esm/room-client.d.ts +3 -1
- package/dist/esm/room-client.js +4 -2
- package/dist/node/meshagent-client.d.ts +8 -0
- package/dist/node/meshagent-client.js +27 -0
- package/dist/node/messaging-client.d.ts +2 -0
- package/dist/node/messaging-client.js +48 -27
- package/dist/node/room-client.d.ts +3 -1
- package/dist/node/room-client.js +4 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [0.47.0]
|
|
2
|
+
- Improved TypeScript messaging clients so room delivery order and startup/presence behavior stay consistent.
|
|
3
|
+
- Moved managed-agent client routing onto the Rust tunnel path and hardened agent chat-client event handling.
|
|
4
|
+
- Added a `test:rust-process-e2e` entry point for the agents-ts package and expanded live chat/process-agent coverage.
|
|
5
|
+
- Finished aligning CLI pagination behavior across feeds, rooms, mailboxes, scheduled tasks, and shared helpers.
|
|
6
|
+
|
|
1
7
|
## [0.46.3]
|
|
2
8
|
- `LivekitProtocolChannel.sendData` now clones outgoing `Uint8Array` payloads before publishing, avoiding shared-buffer mutation issues.
|
|
3
9
|
|
|
@@ -29,6 +29,12 @@ export interface RoomConnectionInfo {
|
|
|
29
29
|
projectId: string;
|
|
30
30
|
roomUrl: string;
|
|
31
31
|
}
|
|
32
|
+
export interface AgentConnectionInfo {
|
|
33
|
+
jwt: string;
|
|
34
|
+
agentName: string;
|
|
35
|
+
projectId: string;
|
|
36
|
+
agentUrl: string;
|
|
37
|
+
}
|
|
32
38
|
export declare class RoomSession {
|
|
33
39
|
readonly id: string;
|
|
34
40
|
readonly roomId?: string | null;
|
|
@@ -559,6 +565,7 @@ export declare class Meshagent {
|
|
|
559
565
|
private parseTransaction;
|
|
560
566
|
private parseOAuthClient;
|
|
561
567
|
private parseRoomConnectionInfo;
|
|
568
|
+
private parseAgentConnectionInfo;
|
|
562
569
|
private encodePathComponent;
|
|
563
570
|
upload({ projectId, path, data }: {
|
|
564
571
|
projectId: string;
|
|
@@ -908,6 +915,7 @@ export declare class Meshagent {
|
|
|
908
915
|
subjectId: string;
|
|
909
916
|
}): Promise<void>;
|
|
910
917
|
connectRoom(projectId: string, room: string): Promise<RoomConnectionInfo>;
|
|
918
|
+
connectAgent(projectId: string, agentName: string): Promise<AgentConnectionInfo>;
|
|
911
919
|
listRooms(projectId: string, options?: {
|
|
912
920
|
pageSize?: number;
|
|
913
921
|
continuationToken?: string;
|
|
@@ -822,6 +822,25 @@ class Meshagent {
|
|
|
822
822
|
}
|
|
823
823
|
return { jwt, roomName: roomNameValue, projectId: projectIdValue, roomUrl: roomUrlValue };
|
|
824
824
|
}
|
|
825
|
+
parseAgentConnectionInfo(data) {
|
|
826
|
+
if (!data || typeof data !== "object") {
|
|
827
|
+
throw new requirement_js_1.RoomException("Invalid agent connection payload");
|
|
828
|
+
}
|
|
829
|
+
const { jwt, agent_name: agentNameRaw, agentName, project_id: projectIdRaw, projectId, agent_url: agentUrlRaw, agentUrl } = data;
|
|
830
|
+
const agentNameValue = typeof agentName === "string" ? agentName : agentNameRaw;
|
|
831
|
+
const projectIdValue = typeof projectId === "string" ? projectId : projectIdRaw;
|
|
832
|
+
const agentUrlValue = typeof agentUrl === "string" ? agentUrl : agentUrlRaw;
|
|
833
|
+
if (typeof jwt !== "string" || typeof agentNameValue !== "string" || typeof projectIdValue !== "string" || typeof agentUrlValue !== "string") {
|
|
834
|
+
throw new requirement_js_1.RoomException("Invalid agent connection payload: missing fields");
|
|
835
|
+
}
|
|
836
|
+
const parsedUrl = new URL(agentUrlValue);
|
|
837
|
+
const legacySuffix = `/accounts/projects/${encodeURIComponent(projectIdValue)}/agents/${encodeURIComponent(agentNameValue)}/messages`;
|
|
838
|
+
if (parsedUrl.pathname.endsWith(legacySuffix)) {
|
|
839
|
+
const prefix = parsedUrl.pathname.slice(0, -legacySuffix.length);
|
|
840
|
+
parsedUrl.pathname = `${prefix}/agents/${encodeURIComponent(projectIdValue)}/${encodeURIComponent(agentNameValue)}/messages`;
|
|
841
|
+
}
|
|
842
|
+
return { jwt, agentName: agentNameValue, projectId: projectIdValue, agentUrl: parsedUrl.toString() };
|
|
843
|
+
}
|
|
825
844
|
encodePathComponent(value) {
|
|
826
845
|
return encodeURIComponent(value);
|
|
827
846
|
}
|
|
@@ -1847,6 +1866,14 @@ class Meshagent {
|
|
|
1847
1866
|
});
|
|
1848
1867
|
return this.parseRoomConnectionInfo(data);
|
|
1849
1868
|
}
|
|
1869
|
+
async connectAgent(projectId, agentName) {
|
|
1870
|
+
const data = await this.request(`/accounts/projects/${projectId}/agents/${encodeURIComponent(agentName)}/connect`, {
|
|
1871
|
+
method: "POST",
|
|
1872
|
+
json: {},
|
|
1873
|
+
action: "connect agent",
|
|
1874
|
+
});
|
|
1875
|
+
return this.parseAgentConnectionInfo(data);
|
|
1876
|
+
}
|
|
1850
1877
|
async listRooms(projectId, options = {}) {
|
|
1851
1878
|
const { pageSize = 50, continuationToken, filter, view } = options;
|
|
1852
1879
|
const data = await this.request(`/accounts/projects/${projectId}/rooms`, {
|
|
@@ -10,6 +10,7 @@ export declare class MessagingClient extends EventEmitter<RoomMessageEvent> {
|
|
|
10
10
|
private readonly _messageQueue;
|
|
11
11
|
private _messageQueued;
|
|
12
12
|
private _sendTask;
|
|
13
|
+
private readonly _sendOperations;
|
|
13
14
|
private _messageQueueClosed;
|
|
14
15
|
private _desiredEnabled;
|
|
15
16
|
private _online;
|
|
@@ -42,6 +43,7 @@ export declare class MessagingClient extends EventEmitter<RoomMessageEvent> {
|
|
|
42
43
|
private _dropQueuedMessage;
|
|
43
44
|
private _drainQueuedMessages;
|
|
44
45
|
private _sendMessages;
|
|
46
|
+
private _sendQueuedMessage;
|
|
45
47
|
sendMessage({ to, type, message, attachment, ignoreOffline, }: {
|
|
46
48
|
to: Participant;
|
|
47
49
|
type: string;
|
|
@@ -30,6 +30,7 @@ class MessagingClient extends event_emitter_js_1.EventEmitter {
|
|
|
30
30
|
this._messageQueue = [];
|
|
31
31
|
this._messageQueued = null;
|
|
32
32
|
this._sendTask = null;
|
|
33
|
+
this._sendOperations = new Set();
|
|
33
34
|
this._messageQueueClosed = false;
|
|
34
35
|
this._desiredEnabled = false;
|
|
35
36
|
this._online = false;
|
|
@@ -59,11 +60,12 @@ class MessagingClient extends event_emitter_js_1.EventEmitter {
|
|
|
59
60
|
}
|
|
60
61
|
return input;
|
|
61
62
|
}
|
|
62
|
-
async _invoke({ operation, input, }) {
|
|
63
|
+
async _invoke({ operation, input, afterSend, }) {
|
|
63
64
|
await this.client.invokeContent({
|
|
64
65
|
toolkit: "messaging",
|
|
65
66
|
tool: operation,
|
|
66
67
|
input: new response_js_1.JsonContent({ json: input }),
|
|
68
|
+
afterSend,
|
|
67
69
|
});
|
|
68
70
|
}
|
|
69
71
|
_invokeNowait({ operation, input, }) {
|
|
@@ -93,6 +95,7 @@ class MessagingClient extends event_emitter_js_1.EventEmitter {
|
|
|
93
95
|
if (sendTask != null) {
|
|
94
96
|
await sendTask;
|
|
95
97
|
}
|
|
98
|
+
await Promise.all(this._sendOperations);
|
|
96
99
|
this._desiredEnabled = false;
|
|
97
100
|
this._clearCurrentConnectionState();
|
|
98
101
|
}
|
|
@@ -238,34 +241,52 @@ class MessagingClient extends event_emitter_js_1.EventEmitter {
|
|
|
238
241
|
});
|
|
239
242
|
continue;
|
|
240
243
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
244
|
+
const dispatched = new completer_js_1.Completer();
|
|
245
|
+
const operation = this._sendQueuedMessage({
|
|
246
|
+
message,
|
|
247
|
+
resolvedTo,
|
|
248
|
+
afterSend: () => dispatched.resolve(),
|
|
249
|
+
});
|
|
250
|
+
this._sendOperations.add(operation);
|
|
251
|
+
void operation.then(() => {
|
|
252
|
+
this._sendOperations.delete(operation);
|
|
253
|
+
if (!dispatched.completed)
|
|
254
|
+
dispatched.resolve();
|
|
255
|
+
}, () => {
|
|
256
|
+
this._sendOperations.delete(operation);
|
|
257
|
+
if (!dispatched.completed)
|
|
258
|
+
dispatched.resolve();
|
|
259
|
+
});
|
|
260
|
+
await dispatched.fut;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
async _sendQueuedMessage({ message, resolvedTo, afterSend, }) {
|
|
264
|
+
try {
|
|
265
|
+
await this._invoke({
|
|
266
|
+
operation: "send",
|
|
267
|
+
input: this._messageInput({
|
|
268
|
+
toParticipantId: resolvedTo.id,
|
|
269
|
+
type: message.type,
|
|
270
|
+
message: message.message,
|
|
271
|
+
attachment: message.attachment,
|
|
272
|
+
}),
|
|
273
|
+
afterSend,
|
|
274
|
+
});
|
|
275
|
+
if (message.completer != null && !message.completer.completed) {
|
|
276
|
+
message.completer.complete();
|
|
254
277
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
continue;
|
|
262
|
-
}
|
|
263
|
-
this._dropQueuedMessage({ message, error: wrapped });
|
|
264
|
-
continue;
|
|
265
|
-
}
|
|
266
|
-
if (message.completer != null && !message.completer.completed) {
|
|
267
|
-
message.completer.completeError(error);
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
if (error instanceof room_server_client_js_1.RoomServerException) {
|
|
281
|
+
const wrapped = this.client._coerceMessageSendError(error);
|
|
282
|
+
if (wrapped.message === "the participant was not found") {
|
|
283
|
+
this._markParticipantOffline(message.to);
|
|
268
284
|
}
|
|
285
|
+
this._dropQueuedMessage({ message, error: wrapped });
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
if (message.completer != null && !message.completer.completed) {
|
|
289
|
+
message.completer.completeError(error);
|
|
269
290
|
}
|
|
270
291
|
}
|
|
271
292
|
}
|
|
@@ -189,7 +189,7 @@ export declare class RoomClient {
|
|
|
189
189
|
}): void;
|
|
190
190
|
_sendLocalAttributesNowait(attributes: Record<string, unknown>): void;
|
|
191
191
|
_resendLocalAttributesNowait(): void;
|
|
192
|
-
sendRequest(type: string, request: RequestHeader, data?: Uint8Array): Promise<Content>;
|
|
192
|
+
sendRequest(type: string, request: RequestHeader, data?: Uint8Array, afterSend?: () => void): Promise<Content>;
|
|
193
193
|
call(params: {
|
|
194
194
|
name: string;
|
|
195
195
|
url: string;
|
|
@@ -216,6 +216,7 @@ export declare class RoomClient {
|
|
|
216
216
|
input?: InvokeInput;
|
|
217
217
|
participantId?: string;
|
|
218
218
|
onBehalfOfId?: string;
|
|
219
|
+
afterSend?: () => void;
|
|
219
220
|
}): Promise<Content>;
|
|
220
221
|
invokeToolCall(params: {
|
|
221
222
|
toolkit: string;
|
|
@@ -224,6 +225,7 @@ export declare class RoomClient {
|
|
|
224
225
|
streamInput?: boolean;
|
|
225
226
|
participantId?: string;
|
|
226
227
|
onBehalfOfId?: string;
|
|
228
|
+
afterSend?: () => void;
|
|
227
229
|
}): Promise<{
|
|
228
230
|
kind: "content";
|
|
229
231
|
content: Content;
|
|
@@ -1146,7 +1146,7 @@ class RoomClient {
|
|
|
1146
1146
|
}
|
|
1147
1147
|
this._sendLocalAttributesNowait(attributes);
|
|
1148
1148
|
}
|
|
1149
|
-
async sendRequest(type, request, data) {
|
|
1149
|
+
async sendRequest(type, request, data, afterSend) {
|
|
1150
1150
|
this._raiseIfTerminal();
|
|
1151
1151
|
if (this._entered && !this._connected && !this._allowDisconnectedRequests) {
|
|
1152
1152
|
throw this._disconnectedError({ baseMessage: "room connection is disconnected" });
|
|
@@ -1156,6 +1156,7 @@ class RoomClient {
|
|
|
1156
1156
|
this._pendingRequests.set(requestId, completer);
|
|
1157
1157
|
try {
|
|
1158
1158
|
await this._protocolInstance.send(type, (0, utils_js_1.packMessage)(request, data), requestId);
|
|
1159
|
+
afterSend?.();
|
|
1159
1160
|
return await completer.fut;
|
|
1160
1161
|
}
|
|
1161
1162
|
catch (error) {
|
|
@@ -1239,6 +1240,7 @@ class RoomClient {
|
|
|
1239
1240
|
input: this._normalizeInvokeInput(params.input ?? params.arguments),
|
|
1240
1241
|
participantId: params.participantId,
|
|
1241
1242
|
onBehalfOfId: params.onBehalfOfId,
|
|
1243
|
+
afterSend: params.afterSend,
|
|
1242
1244
|
});
|
|
1243
1245
|
if (output.kind !== "content") {
|
|
1244
1246
|
throw new room_server_client_js_1.RoomServerException("unexpected streamed output from " + params.toolkit + "." + params.tool);
|
|
@@ -1280,7 +1282,7 @@ class RoomClient {
|
|
|
1280
1282
|
}
|
|
1281
1283
|
try {
|
|
1282
1284
|
const response = await Promise.race([
|
|
1283
|
-
this.sendRequest("room.invoke_tool", request, requestData),
|
|
1285
|
+
this.sendRequest("room.invoke_tool", request, requestData, params.afterSend),
|
|
1284
1286
|
preOpenError.fut,
|
|
1285
1287
|
]);
|
|
1286
1288
|
this._toolCallPreOpenErrors.delete(toolCallId);
|
|
@@ -29,6 +29,12 @@ export interface RoomConnectionInfo {
|
|
|
29
29
|
projectId: string;
|
|
30
30
|
roomUrl: string;
|
|
31
31
|
}
|
|
32
|
+
export interface AgentConnectionInfo {
|
|
33
|
+
jwt: string;
|
|
34
|
+
agentName: string;
|
|
35
|
+
projectId: string;
|
|
36
|
+
agentUrl: string;
|
|
37
|
+
}
|
|
32
38
|
export declare class RoomSession {
|
|
33
39
|
readonly id: string;
|
|
34
40
|
readonly roomId?: string | null;
|
|
@@ -559,6 +565,7 @@ export declare class Meshagent {
|
|
|
559
565
|
private parseTransaction;
|
|
560
566
|
private parseOAuthClient;
|
|
561
567
|
private parseRoomConnectionInfo;
|
|
568
|
+
private parseAgentConnectionInfo;
|
|
562
569
|
private encodePathComponent;
|
|
563
570
|
upload({ projectId, path, data }: {
|
|
564
571
|
projectId: string;
|
|
@@ -908,6 +915,7 @@ export declare class Meshagent {
|
|
|
908
915
|
subjectId: string;
|
|
909
916
|
}): Promise<void>;
|
|
910
917
|
connectRoom(projectId: string, room: string): Promise<RoomConnectionInfo>;
|
|
918
|
+
connectAgent(projectId: string, agentName: string): Promise<AgentConnectionInfo>;
|
|
911
919
|
listRooms(projectId: string, options?: {
|
|
912
920
|
pageSize?: number;
|
|
913
921
|
continuationToken?: string;
|
|
@@ -817,6 +817,25 @@ export class Meshagent {
|
|
|
817
817
|
}
|
|
818
818
|
return { jwt, roomName: roomNameValue, projectId: projectIdValue, roomUrl: roomUrlValue };
|
|
819
819
|
}
|
|
820
|
+
parseAgentConnectionInfo(data) {
|
|
821
|
+
if (!data || typeof data !== "object") {
|
|
822
|
+
throw new RoomException("Invalid agent connection payload");
|
|
823
|
+
}
|
|
824
|
+
const { jwt, agent_name: agentNameRaw, agentName, project_id: projectIdRaw, projectId, agent_url: agentUrlRaw, agentUrl } = data;
|
|
825
|
+
const agentNameValue = typeof agentName === "string" ? agentName : agentNameRaw;
|
|
826
|
+
const projectIdValue = typeof projectId === "string" ? projectId : projectIdRaw;
|
|
827
|
+
const agentUrlValue = typeof agentUrl === "string" ? agentUrl : agentUrlRaw;
|
|
828
|
+
if (typeof jwt !== "string" || typeof agentNameValue !== "string" || typeof projectIdValue !== "string" || typeof agentUrlValue !== "string") {
|
|
829
|
+
throw new RoomException("Invalid agent connection payload: missing fields");
|
|
830
|
+
}
|
|
831
|
+
const parsedUrl = new URL(agentUrlValue);
|
|
832
|
+
const legacySuffix = `/accounts/projects/${encodeURIComponent(projectIdValue)}/agents/${encodeURIComponent(agentNameValue)}/messages`;
|
|
833
|
+
if (parsedUrl.pathname.endsWith(legacySuffix)) {
|
|
834
|
+
const prefix = parsedUrl.pathname.slice(0, -legacySuffix.length);
|
|
835
|
+
parsedUrl.pathname = `${prefix}/agents/${encodeURIComponent(projectIdValue)}/${encodeURIComponent(agentNameValue)}/messages`;
|
|
836
|
+
}
|
|
837
|
+
return { jwt, agentName: agentNameValue, projectId: projectIdValue, agentUrl: parsedUrl.toString() };
|
|
838
|
+
}
|
|
820
839
|
encodePathComponent(value) {
|
|
821
840
|
return encodeURIComponent(value);
|
|
822
841
|
}
|
|
@@ -1842,6 +1861,14 @@ export class Meshagent {
|
|
|
1842
1861
|
});
|
|
1843
1862
|
return this.parseRoomConnectionInfo(data);
|
|
1844
1863
|
}
|
|
1864
|
+
async connectAgent(projectId, agentName) {
|
|
1865
|
+
const data = await this.request(`/accounts/projects/${projectId}/agents/${encodeURIComponent(agentName)}/connect`, {
|
|
1866
|
+
method: "POST",
|
|
1867
|
+
json: {},
|
|
1868
|
+
action: "connect agent",
|
|
1869
|
+
});
|
|
1870
|
+
return this.parseAgentConnectionInfo(data);
|
|
1871
|
+
}
|
|
1845
1872
|
async listRooms(projectId, options = {}) {
|
|
1846
1873
|
const { pageSize = 50, continuationToken, filter, view } = options;
|
|
1847
1874
|
const data = await this.request(`/accounts/projects/${projectId}/rooms`, {
|
|
@@ -10,6 +10,7 @@ export declare class MessagingClient extends EventEmitter<RoomMessageEvent> {
|
|
|
10
10
|
private readonly _messageQueue;
|
|
11
11
|
private _messageQueued;
|
|
12
12
|
private _sendTask;
|
|
13
|
+
private readonly _sendOperations;
|
|
13
14
|
private _messageQueueClosed;
|
|
14
15
|
private _desiredEnabled;
|
|
15
16
|
private _online;
|
|
@@ -42,6 +43,7 @@ export declare class MessagingClient extends EventEmitter<RoomMessageEvent> {
|
|
|
42
43
|
private _dropQueuedMessage;
|
|
43
44
|
private _drainQueuedMessages;
|
|
44
45
|
private _sendMessages;
|
|
46
|
+
private _sendQueuedMessage;
|
|
45
47
|
sendMessage({ to, type, message, attachment, ignoreOffline, }: {
|
|
46
48
|
to: Participant;
|
|
47
49
|
type: string;
|
|
@@ -27,6 +27,7 @@ export class MessagingClient extends EventEmitter {
|
|
|
27
27
|
this._messageQueue = [];
|
|
28
28
|
this._messageQueued = null;
|
|
29
29
|
this._sendTask = null;
|
|
30
|
+
this._sendOperations = new Set();
|
|
30
31
|
this._messageQueueClosed = false;
|
|
31
32
|
this._desiredEnabled = false;
|
|
32
33
|
this._online = false;
|
|
@@ -56,11 +57,12 @@ export class MessagingClient extends EventEmitter {
|
|
|
56
57
|
}
|
|
57
58
|
return input;
|
|
58
59
|
}
|
|
59
|
-
async _invoke({ operation, input, }) {
|
|
60
|
+
async _invoke({ operation, input, afterSend, }) {
|
|
60
61
|
await this.client.invokeContent({
|
|
61
62
|
toolkit: "messaging",
|
|
62
63
|
tool: operation,
|
|
63
64
|
input: new JsonContent({ json: input }),
|
|
65
|
+
afterSend,
|
|
64
66
|
});
|
|
65
67
|
}
|
|
66
68
|
_invokeNowait({ operation, input, }) {
|
|
@@ -90,6 +92,7 @@ export class MessagingClient extends EventEmitter {
|
|
|
90
92
|
if (sendTask != null) {
|
|
91
93
|
await sendTask;
|
|
92
94
|
}
|
|
95
|
+
await Promise.all(this._sendOperations);
|
|
93
96
|
this._desiredEnabled = false;
|
|
94
97
|
this._clearCurrentConnectionState();
|
|
95
98
|
}
|
|
@@ -235,34 +238,52 @@ export class MessagingClient extends EventEmitter {
|
|
|
235
238
|
});
|
|
236
239
|
continue;
|
|
237
240
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
241
|
+
const dispatched = new Completer();
|
|
242
|
+
const operation = this._sendQueuedMessage({
|
|
243
|
+
message,
|
|
244
|
+
resolvedTo,
|
|
245
|
+
afterSend: () => dispatched.resolve(),
|
|
246
|
+
});
|
|
247
|
+
this._sendOperations.add(operation);
|
|
248
|
+
void operation.then(() => {
|
|
249
|
+
this._sendOperations.delete(operation);
|
|
250
|
+
if (!dispatched.completed)
|
|
251
|
+
dispatched.resolve();
|
|
252
|
+
}, () => {
|
|
253
|
+
this._sendOperations.delete(operation);
|
|
254
|
+
if (!dispatched.completed)
|
|
255
|
+
dispatched.resolve();
|
|
256
|
+
});
|
|
257
|
+
await dispatched.fut;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
async _sendQueuedMessage({ message, resolvedTo, afterSend, }) {
|
|
261
|
+
try {
|
|
262
|
+
await this._invoke({
|
|
263
|
+
operation: "send",
|
|
264
|
+
input: this._messageInput({
|
|
265
|
+
toParticipantId: resolvedTo.id,
|
|
266
|
+
type: message.type,
|
|
267
|
+
message: message.message,
|
|
268
|
+
attachment: message.attachment,
|
|
269
|
+
}),
|
|
270
|
+
afterSend,
|
|
271
|
+
});
|
|
272
|
+
if (message.completer != null && !message.completer.completed) {
|
|
273
|
+
message.completer.complete();
|
|
251
274
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
continue;
|
|
259
|
-
}
|
|
260
|
-
this._dropQueuedMessage({ message, error: wrapped });
|
|
261
|
-
continue;
|
|
262
|
-
}
|
|
263
|
-
if (message.completer != null && !message.completer.completed) {
|
|
264
|
-
message.completer.completeError(error);
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
if (error instanceof RoomServerException) {
|
|
278
|
+
const wrapped = this.client._coerceMessageSendError(error);
|
|
279
|
+
if (wrapped.message === "the participant was not found") {
|
|
280
|
+
this._markParticipantOffline(message.to);
|
|
265
281
|
}
|
|
282
|
+
this._dropQueuedMessage({ message, error: wrapped });
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
if (message.completer != null && !message.completer.completed) {
|
|
286
|
+
message.completer.completeError(error);
|
|
266
287
|
}
|
|
267
288
|
}
|
|
268
289
|
}
|
|
@@ -189,7 +189,7 @@ export declare class RoomClient {
|
|
|
189
189
|
}): void;
|
|
190
190
|
_sendLocalAttributesNowait(attributes: Record<string, unknown>): void;
|
|
191
191
|
_resendLocalAttributesNowait(): void;
|
|
192
|
-
sendRequest(type: string, request: RequestHeader, data?: Uint8Array): Promise<Content>;
|
|
192
|
+
sendRequest(type: string, request: RequestHeader, data?: Uint8Array, afterSend?: () => void): Promise<Content>;
|
|
193
193
|
call(params: {
|
|
194
194
|
name: string;
|
|
195
195
|
url: string;
|
|
@@ -216,6 +216,7 @@ export declare class RoomClient {
|
|
|
216
216
|
input?: InvokeInput;
|
|
217
217
|
participantId?: string;
|
|
218
218
|
onBehalfOfId?: string;
|
|
219
|
+
afterSend?: () => void;
|
|
219
220
|
}): Promise<Content>;
|
|
220
221
|
invokeToolCall(params: {
|
|
221
222
|
toolkit: string;
|
|
@@ -224,6 +225,7 @@ export declare class RoomClient {
|
|
|
224
225
|
streamInput?: boolean;
|
|
225
226
|
participantId?: string;
|
|
226
227
|
onBehalfOfId?: string;
|
|
228
|
+
afterSend?: () => void;
|
|
227
229
|
}): Promise<{
|
|
228
230
|
kind: "content";
|
|
229
231
|
content: Content;
|
package/dist/esm/room-client.js
CHANGED
|
@@ -1142,7 +1142,7 @@ export class RoomClient {
|
|
|
1142
1142
|
}
|
|
1143
1143
|
this._sendLocalAttributesNowait(attributes);
|
|
1144
1144
|
}
|
|
1145
|
-
async sendRequest(type, request, data) {
|
|
1145
|
+
async sendRequest(type, request, data, afterSend) {
|
|
1146
1146
|
this._raiseIfTerminal();
|
|
1147
1147
|
if (this._entered && !this._connected && !this._allowDisconnectedRequests) {
|
|
1148
1148
|
throw this._disconnectedError({ baseMessage: "room connection is disconnected" });
|
|
@@ -1152,6 +1152,7 @@ export class RoomClient {
|
|
|
1152
1152
|
this._pendingRequests.set(requestId, completer);
|
|
1153
1153
|
try {
|
|
1154
1154
|
await this._protocolInstance.send(type, packMessage(request, data), requestId);
|
|
1155
|
+
afterSend?.();
|
|
1155
1156
|
return await completer.fut;
|
|
1156
1157
|
}
|
|
1157
1158
|
catch (error) {
|
|
@@ -1235,6 +1236,7 @@ export class RoomClient {
|
|
|
1235
1236
|
input: this._normalizeInvokeInput(params.input ?? params.arguments),
|
|
1236
1237
|
participantId: params.participantId,
|
|
1237
1238
|
onBehalfOfId: params.onBehalfOfId,
|
|
1239
|
+
afterSend: params.afterSend,
|
|
1238
1240
|
});
|
|
1239
1241
|
if (output.kind !== "content") {
|
|
1240
1242
|
throw new RoomServerException("unexpected streamed output from " + params.toolkit + "." + params.tool);
|
|
@@ -1276,7 +1278,7 @@ export class RoomClient {
|
|
|
1276
1278
|
}
|
|
1277
1279
|
try {
|
|
1278
1280
|
const response = await Promise.race([
|
|
1279
|
-
this.sendRequest("room.invoke_tool", request, requestData),
|
|
1281
|
+
this.sendRequest("room.invoke_tool", request, requestData, params.afterSend),
|
|
1280
1282
|
preOpenError.fut,
|
|
1281
1283
|
]);
|
|
1282
1284
|
this._toolCallPreOpenErrors.delete(toolCallId);
|
|
@@ -29,6 +29,12 @@ export interface RoomConnectionInfo {
|
|
|
29
29
|
projectId: string;
|
|
30
30
|
roomUrl: string;
|
|
31
31
|
}
|
|
32
|
+
export interface AgentConnectionInfo {
|
|
33
|
+
jwt: string;
|
|
34
|
+
agentName: string;
|
|
35
|
+
projectId: string;
|
|
36
|
+
agentUrl: string;
|
|
37
|
+
}
|
|
32
38
|
export declare class RoomSession {
|
|
33
39
|
readonly id: string;
|
|
34
40
|
readonly roomId?: string | null;
|
|
@@ -559,6 +565,7 @@ export declare class Meshagent {
|
|
|
559
565
|
private parseTransaction;
|
|
560
566
|
private parseOAuthClient;
|
|
561
567
|
private parseRoomConnectionInfo;
|
|
568
|
+
private parseAgentConnectionInfo;
|
|
562
569
|
private encodePathComponent;
|
|
563
570
|
upload({ projectId, path, data }: {
|
|
564
571
|
projectId: string;
|
|
@@ -908,6 +915,7 @@ export declare class Meshagent {
|
|
|
908
915
|
subjectId: string;
|
|
909
916
|
}): Promise<void>;
|
|
910
917
|
connectRoom(projectId: string, room: string): Promise<RoomConnectionInfo>;
|
|
918
|
+
connectAgent(projectId: string, agentName: string): Promise<AgentConnectionInfo>;
|
|
911
919
|
listRooms(projectId: string, options?: {
|
|
912
920
|
pageSize?: number;
|
|
913
921
|
continuationToken?: string;
|
|
@@ -822,6 +822,25 @@ class Meshagent {
|
|
|
822
822
|
}
|
|
823
823
|
return { jwt, roomName: roomNameValue, projectId: projectIdValue, roomUrl: roomUrlValue };
|
|
824
824
|
}
|
|
825
|
+
parseAgentConnectionInfo(data) {
|
|
826
|
+
if (!data || typeof data !== "object") {
|
|
827
|
+
throw new requirement_js_1.RoomException("Invalid agent connection payload");
|
|
828
|
+
}
|
|
829
|
+
const { jwt, agent_name: agentNameRaw, agentName, project_id: projectIdRaw, projectId, agent_url: agentUrlRaw, agentUrl } = data;
|
|
830
|
+
const agentNameValue = typeof agentName === "string" ? agentName : agentNameRaw;
|
|
831
|
+
const projectIdValue = typeof projectId === "string" ? projectId : projectIdRaw;
|
|
832
|
+
const agentUrlValue = typeof agentUrl === "string" ? agentUrl : agentUrlRaw;
|
|
833
|
+
if (typeof jwt !== "string" || typeof agentNameValue !== "string" || typeof projectIdValue !== "string" || typeof agentUrlValue !== "string") {
|
|
834
|
+
throw new requirement_js_1.RoomException("Invalid agent connection payload: missing fields");
|
|
835
|
+
}
|
|
836
|
+
const parsedUrl = new URL(agentUrlValue);
|
|
837
|
+
const legacySuffix = `/accounts/projects/${encodeURIComponent(projectIdValue)}/agents/${encodeURIComponent(agentNameValue)}/messages`;
|
|
838
|
+
if (parsedUrl.pathname.endsWith(legacySuffix)) {
|
|
839
|
+
const prefix = parsedUrl.pathname.slice(0, -legacySuffix.length);
|
|
840
|
+
parsedUrl.pathname = `${prefix}/agents/${encodeURIComponent(projectIdValue)}/${encodeURIComponent(agentNameValue)}/messages`;
|
|
841
|
+
}
|
|
842
|
+
return { jwt, agentName: agentNameValue, projectId: projectIdValue, agentUrl: parsedUrl.toString() };
|
|
843
|
+
}
|
|
825
844
|
encodePathComponent(value) {
|
|
826
845
|
return encodeURIComponent(value);
|
|
827
846
|
}
|
|
@@ -1847,6 +1866,14 @@ class Meshagent {
|
|
|
1847
1866
|
});
|
|
1848
1867
|
return this.parseRoomConnectionInfo(data);
|
|
1849
1868
|
}
|
|
1869
|
+
async connectAgent(projectId, agentName) {
|
|
1870
|
+
const data = await this.request(`/accounts/projects/${projectId}/agents/${encodeURIComponent(agentName)}/connect`, {
|
|
1871
|
+
method: "POST",
|
|
1872
|
+
json: {},
|
|
1873
|
+
action: "connect agent",
|
|
1874
|
+
});
|
|
1875
|
+
return this.parseAgentConnectionInfo(data);
|
|
1876
|
+
}
|
|
1850
1877
|
async listRooms(projectId, options = {}) {
|
|
1851
1878
|
const { pageSize = 50, continuationToken, filter, view } = options;
|
|
1852
1879
|
const data = await this.request(`/accounts/projects/${projectId}/rooms`, {
|
|
@@ -10,6 +10,7 @@ export declare class MessagingClient extends EventEmitter<RoomMessageEvent> {
|
|
|
10
10
|
private readonly _messageQueue;
|
|
11
11
|
private _messageQueued;
|
|
12
12
|
private _sendTask;
|
|
13
|
+
private readonly _sendOperations;
|
|
13
14
|
private _messageQueueClosed;
|
|
14
15
|
private _desiredEnabled;
|
|
15
16
|
private _online;
|
|
@@ -42,6 +43,7 @@ export declare class MessagingClient extends EventEmitter<RoomMessageEvent> {
|
|
|
42
43
|
private _dropQueuedMessage;
|
|
43
44
|
private _drainQueuedMessages;
|
|
44
45
|
private _sendMessages;
|
|
46
|
+
private _sendQueuedMessage;
|
|
45
47
|
sendMessage({ to, type, message, attachment, ignoreOffline, }: {
|
|
46
48
|
to: Participant;
|
|
47
49
|
type: string;
|
|
@@ -30,6 +30,7 @@ class MessagingClient extends event_emitter_js_1.EventEmitter {
|
|
|
30
30
|
this._messageQueue = [];
|
|
31
31
|
this._messageQueued = null;
|
|
32
32
|
this._sendTask = null;
|
|
33
|
+
this._sendOperations = new Set();
|
|
33
34
|
this._messageQueueClosed = false;
|
|
34
35
|
this._desiredEnabled = false;
|
|
35
36
|
this._online = false;
|
|
@@ -59,11 +60,12 @@ class MessagingClient extends event_emitter_js_1.EventEmitter {
|
|
|
59
60
|
}
|
|
60
61
|
return input;
|
|
61
62
|
}
|
|
62
|
-
async _invoke({ operation, input, }) {
|
|
63
|
+
async _invoke({ operation, input, afterSend, }) {
|
|
63
64
|
await this.client.invokeContent({
|
|
64
65
|
toolkit: "messaging",
|
|
65
66
|
tool: operation,
|
|
66
67
|
input: new response_js_1.JsonContent({ json: input }),
|
|
68
|
+
afterSend,
|
|
67
69
|
});
|
|
68
70
|
}
|
|
69
71
|
_invokeNowait({ operation, input, }) {
|
|
@@ -93,6 +95,7 @@ class MessagingClient extends event_emitter_js_1.EventEmitter {
|
|
|
93
95
|
if (sendTask != null) {
|
|
94
96
|
await sendTask;
|
|
95
97
|
}
|
|
98
|
+
await Promise.all(this._sendOperations);
|
|
96
99
|
this._desiredEnabled = false;
|
|
97
100
|
this._clearCurrentConnectionState();
|
|
98
101
|
}
|
|
@@ -238,34 +241,52 @@ class MessagingClient extends event_emitter_js_1.EventEmitter {
|
|
|
238
241
|
});
|
|
239
242
|
continue;
|
|
240
243
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
244
|
+
const dispatched = new completer_js_1.Completer();
|
|
245
|
+
const operation = this._sendQueuedMessage({
|
|
246
|
+
message,
|
|
247
|
+
resolvedTo,
|
|
248
|
+
afterSend: () => dispatched.resolve(),
|
|
249
|
+
});
|
|
250
|
+
this._sendOperations.add(operation);
|
|
251
|
+
void operation.then(() => {
|
|
252
|
+
this._sendOperations.delete(operation);
|
|
253
|
+
if (!dispatched.completed)
|
|
254
|
+
dispatched.resolve();
|
|
255
|
+
}, () => {
|
|
256
|
+
this._sendOperations.delete(operation);
|
|
257
|
+
if (!dispatched.completed)
|
|
258
|
+
dispatched.resolve();
|
|
259
|
+
});
|
|
260
|
+
await dispatched.fut;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
async _sendQueuedMessage({ message, resolvedTo, afterSend, }) {
|
|
264
|
+
try {
|
|
265
|
+
await this._invoke({
|
|
266
|
+
operation: "send",
|
|
267
|
+
input: this._messageInput({
|
|
268
|
+
toParticipantId: resolvedTo.id,
|
|
269
|
+
type: message.type,
|
|
270
|
+
message: message.message,
|
|
271
|
+
attachment: message.attachment,
|
|
272
|
+
}),
|
|
273
|
+
afterSend,
|
|
274
|
+
});
|
|
275
|
+
if (message.completer != null && !message.completer.completed) {
|
|
276
|
+
message.completer.complete();
|
|
254
277
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
continue;
|
|
262
|
-
}
|
|
263
|
-
this._dropQueuedMessage({ message, error: wrapped });
|
|
264
|
-
continue;
|
|
265
|
-
}
|
|
266
|
-
if (message.completer != null && !message.completer.completed) {
|
|
267
|
-
message.completer.completeError(error);
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
if (error instanceof room_server_client_js_1.RoomServerException) {
|
|
281
|
+
const wrapped = this.client._coerceMessageSendError(error);
|
|
282
|
+
if (wrapped.message === "the participant was not found") {
|
|
283
|
+
this._markParticipantOffline(message.to);
|
|
268
284
|
}
|
|
285
|
+
this._dropQueuedMessage({ message, error: wrapped });
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
if (message.completer != null && !message.completer.completed) {
|
|
289
|
+
message.completer.completeError(error);
|
|
269
290
|
}
|
|
270
291
|
}
|
|
271
292
|
}
|
|
@@ -189,7 +189,7 @@ export declare class RoomClient {
|
|
|
189
189
|
}): void;
|
|
190
190
|
_sendLocalAttributesNowait(attributes: Record<string, unknown>): void;
|
|
191
191
|
_resendLocalAttributesNowait(): void;
|
|
192
|
-
sendRequest(type: string, request: RequestHeader, data?: Uint8Array): Promise<Content>;
|
|
192
|
+
sendRequest(type: string, request: RequestHeader, data?: Uint8Array, afterSend?: () => void): Promise<Content>;
|
|
193
193
|
call(params: {
|
|
194
194
|
name: string;
|
|
195
195
|
url: string;
|
|
@@ -216,6 +216,7 @@ export declare class RoomClient {
|
|
|
216
216
|
input?: InvokeInput;
|
|
217
217
|
participantId?: string;
|
|
218
218
|
onBehalfOfId?: string;
|
|
219
|
+
afterSend?: () => void;
|
|
219
220
|
}): Promise<Content>;
|
|
220
221
|
invokeToolCall(params: {
|
|
221
222
|
toolkit: string;
|
|
@@ -224,6 +225,7 @@ export declare class RoomClient {
|
|
|
224
225
|
streamInput?: boolean;
|
|
225
226
|
participantId?: string;
|
|
226
227
|
onBehalfOfId?: string;
|
|
228
|
+
afterSend?: () => void;
|
|
227
229
|
}): Promise<{
|
|
228
230
|
kind: "content";
|
|
229
231
|
content: Content;
|
package/dist/node/room-client.js
CHANGED
|
@@ -1146,7 +1146,7 @@ class RoomClient {
|
|
|
1146
1146
|
}
|
|
1147
1147
|
this._sendLocalAttributesNowait(attributes);
|
|
1148
1148
|
}
|
|
1149
|
-
async sendRequest(type, request, data) {
|
|
1149
|
+
async sendRequest(type, request, data, afterSend) {
|
|
1150
1150
|
this._raiseIfTerminal();
|
|
1151
1151
|
if (this._entered && !this._connected && !this._allowDisconnectedRequests) {
|
|
1152
1152
|
throw this._disconnectedError({ baseMessage: "room connection is disconnected" });
|
|
@@ -1156,6 +1156,7 @@ class RoomClient {
|
|
|
1156
1156
|
this._pendingRequests.set(requestId, completer);
|
|
1157
1157
|
try {
|
|
1158
1158
|
await this._protocolInstance.send(type, (0, utils_js_1.packMessage)(request, data), requestId);
|
|
1159
|
+
afterSend?.();
|
|
1159
1160
|
return await completer.fut;
|
|
1160
1161
|
}
|
|
1161
1162
|
catch (error) {
|
|
@@ -1239,6 +1240,7 @@ class RoomClient {
|
|
|
1239
1240
|
input: this._normalizeInvokeInput(params.input ?? params.arguments),
|
|
1240
1241
|
participantId: params.participantId,
|
|
1241
1242
|
onBehalfOfId: params.onBehalfOfId,
|
|
1243
|
+
afterSend: params.afterSend,
|
|
1242
1244
|
});
|
|
1243
1245
|
if (output.kind !== "content") {
|
|
1244
1246
|
throw new room_server_client_js_1.RoomServerException("unexpected streamed output from " + params.toolkit + "." + params.tool);
|
|
@@ -1280,7 +1282,7 @@ class RoomClient {
|
|
|
1280
1282
|
}
|
|
1281
1283
|
try {
|
|
1282
1284
|
const response = await Promise.race([
|
|
1283
|
-
this.sendRequest("room.invoke_tool", request, requestData),
|
|
1285
|
+
this.sendRequest("room.invoke_tool", request, requestData, params.afterSend),
|
|
1284
1286
|
preOpenError.fut,
|
|
1285
1287
|
]);
|
|
1286
1288
|
this._toolCallPreOpenErrors.delete(toolCallId);
|