@meshagent/meshagent 0.46.4 → 0.47.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MessagingClient = void 0;
3
+ exports.MessagingClient = exports.MessagingStream = void 0;
4
4
  const completer_js_1 = require("./completer.js");
5
5
  const event_emitter_js_1 = require("./event-emitter.js");
6
6
  const participant_js_1 = require("./participant.js");
@@ -22,6 +22,256 @@ function bytesToBase64(bytes) {
22
22
  }
23
23
  return globalScope.btoa(binary);
24
24
  }
25
+ function base64ToBytes(value) {
26
+ if (globalScope.Buffer != null) {
27
+ return new Uint8Array(globalScope.Buffer.from(value, "base64"));
28
+ }
29
+ const atob = globalThis.atob;
30
+ if (atob == null) {
31
+ throw new Error("base64 decoding is not available in this runtime");
32
+ }
33
+ const binary = atob(value);
34
+ return Uint8Array.from(binary, (character) => character.charCodeAt(0));
35
+ }
36
+ class MessagingStreamInput {
37
+ constructor() {
38
+ this.items = [];
39
+ this.signal = null;
40
+ this.active = null;
41
+ this.closed = false;
42
+ this.error = null;
43
+ }
44
+ enqueue(content, { wait = false } = {}) {
45
+ if (this.closed) {
46
+ return Promise.reject(this.error ?? new room_server_client_js_1.RoomServerException("the messaging stream is closed"));
47
+ }
48
+ const sent = wait ? new completer_js_1.Completer() : undefined;
49
+ this.items.push({ content, sent });
50
+ this.signal?.resolve();
51
+ this.signal = null;
52
+ return sent?.fut ?? Promise.resolve();
53
+ }
54
+ close(error = new room_server_client_js_1.RoomServerException("the messaging stream is closed")) {
55
+ if (this.closed) {
56
+ return;
57
+ }
58
+ this.closed = true;
59
+ this.error = error;
60
+ this.active?.sent?.reject(error);
61
+ this.active = null;
62
+ for (const item of this.items.splice(0)) {
63
+ item.sent?.reject(error);
64
+ }
65
+ this.signal?.resolve();
66
+ this.signal = null;
67
+ }
68
+ fail(error) {
69
+ this.close(error);
70
+ }
71
+ async *stream() {
72
+ try {
73
+ while (true) {
74
+ while (this.items.length === 0 && !this.closed) {
75
+ this.signal ?? (this.signal = new completer_js_1.Completer());
76
+ await this.signal.fut;
77
+ }
78
+ const item = this.items.shift();
79
+ if (item == null) {
80
+ return;
81
+ }
82
+ this.active = item;
83
+ yield item.content;
84
+ item.sent?.resolve();
85
+ this.active = null;
86
+ }
87
+ }
88
+ finally {
89
+ if (this.active != null && this.closed) {
90
+ this.active.sent?.reject(this.error ?? new room_server_client_js_1.RoomServerException("the messaging stream is closed"));
91
+ this.active = null;
92
+ }
93
+ }
94
+ }
95
+ }
96
+ class MessagingStream {
97
+ constructor({ streamId, remoteParticipantId, input, output, inputClosed, onClosed, }) {
98
+ this.events = [];
99
+ this.eventSignal = null;
100
+ this.state = "accepted";
101
+ this.streamId = streamId;
102
+ this.remoteParticipantId = remoteParticipantId;
103
+ this.input = input;
104
+ this.output = output;
105
+ this.inputDone = Promise.resolve(inputClosed).catch((error) => {
106
+ this.input.fail(error);
107
+ this.push({
108
+ kind: "closed",
109
+ streamId: this.streamId,
110
+ reason: "error",
111
+ message: error instanceof Error ? error.message : String(error),
112
+ });
113
+ void this.output.return?.();
114
+ this.finish();
115
+ });
116
+ this.onClosed = onClosed;
117
+ void this.consumeOutput();
118
+ }
119
+ get closed() {
120
+ return this.state === "terminal";
121
+ }
122
+ push(event) {
123
+ if (this.state !== "accepted") {
124
+ return;
125
+ }
126
+ this.events.push(event);
127
+ this.eventSignal?.resolve();
128
+ this.eventSignal = null;
129
+ }
130
+ finish() {
131
+ if (this.state === "terminal") {
132
+ return;
133
+ }
134
+ this.state = "terminal";
135
+ this.input.close();
136
+ this.eventSignal?.resolve();
137
+ this.eventSignal = null;
138
+ void this.inputDone.finally(this.onClosed);
139
+ }
140
+ async consumeOutput() {
141
+ try {
142
+ while (true) {
143
+ const next = await this.output.next();
144
+ if (next.done) {
145
+ return;
146
+ }
147
+ if (next.value instanceof response_js_1.ControlContent && next.value.method === "close") {
148
+ this.push({
149
+ kind: "client_disconnected",
150
+ streamId: this.streamId,
151
+ participantId: this.remoteParticipantId,
152
+ });
153
+ return;
154
+ }
155
+ if (!(next.value instanceof response_js_1.JsonContent)) {
156
+ throw new room_server_client_js_1.RoomServerException("unexpected chunk from messaging.stream");
157
+ }
158
+ const value = next.value.json;
159
+ const kind = value["kind"];
160
+ if (kind === "message") {
161
+ const type = value["type"];
162
+ const message = value["message"];
163
+ if (typeof type !== "string" || typeof message !== "object" || message == null || Array.isArray(message)) {
164
+ throw new room_server_client_js_1.RoomServerException("invalid message chunk from messaging.stream");
165
+ }
166
+ const encodedAttachment = value["attachment_base64"];
167
+ this.push({
168
+ kind: "message",
169
+ message: new room_event_js_1.RoomMessage({
170
+ fromParticipantId: this.remoteParticipantId,
171
+ type,
172
+ message: message,
173
+ attachment: typeof encodedAttachment === "string" && encodedAttachment !== ""
174
+ ? base64ToBytes(encodedAttachment)
175
+ : undefined,
176
+ }),
177
+ });
178
+ }
179
+ else if (kind === "client_disconnected" && typeof value["participant_id"] === "string") {
180
+ this.push({
181
+ kind,
182
+ streamId: this.streamId,
183
+ participantId: value["participant_id"],
184
+ });
185
+ return;
186
+ }
187
+ else if (kind === "closed") {
188
+ this.push({
189
+ kind,
190
+ streamId: this.streamId,
191
+ reason: typeof value["reason"] === "string" ? value["reason"] : "closed",
192
+ message: typeof value["message"] === "string" ? value["message"] : undefined,
193
+ });
194
+ return;
195
+ }
196
+ else {
197
+ throw new room_server_client_js_1.RoomServerException("unexpected chunk from messaging.stream");
198
+ }
199
+ }
200
+ }
201
+ catch (error) {
202
+ this.input.fail(error);
203
+ this.push({
204
+ kind: "closed",
205
+ streamId: this.streamId,
206
+ reason: "error",
207
+ message: error instanceof Error ? error.message : String(error),
208
+ });
209
+ }
210
+ finally {
211
+ this.finish();
212
+ }
213
+ }
214
+ content({ type, message, attachment, }) {
215
+ return new response_js_1.JsonContent({
216
+ json: {
217
+ type,
218
+ message_json: JSON.stringify(message),
219
+ ...(attachment == null ? {} : { attachment_base64: bytesToBase64(attachment) }),
220
+ },
221
+ });
222
+ }
223
+ sendMessageNowait(params) {
224
+ if (this.state !== "accepted") {
225
+ throw new room_server_client_js_1.RoomServerException("the messaging stream is closed");
226
+ }
227
+ void this.input.enqueue(this.content(params));
228
+ }
229
+ async sendMessage(params) {
230
+ if (this.state !== "accepted") {
231
+ throw new room_server_client_js_1.RoomServerException("the messaging stream is closed");
232
+ }
233
+ await this.input.enqueue(this.content(params), { wait: true });
234
+ }
235
+ async close() {
236
+ if (this.state === "terminal") {
237
+ await this.inputDone;
238
+ return;
239
+ }
240
+ this.input.close();
241
+ try {
242
+ await this.inputDone;
243
+ }
244
+ finally {
245
+ await this.output.return?.();
246
+ this.finish();
247
+ }
248
+ }
249
+ clientDisconnected(participantId) {
250
+ if (this.state === "terminal") {
251
+ return;
252
+ }
253
+ this.push({
254
+ kind: "client_disconnected",
255
+ streamId: this.streamId,
256
+ participantId,
257
+ });
258
+ this.finish();
259
+ }
260
+ async *[Symbol.asyncIterator]() {
261
+ while (true) {
262
+ while (this.events.length === 0 && this.state !== "terminal") {
263
+ this.eventSignal ?? (this.eventSignal = new completer_js_1.Completer());
264
+ await this.eventSignal.fut;
265
+ }
266
+ const event = this.events.shift();
267
+ if (event == null) {
268
+ return;
269
+ }
270
+ yield event;
271
+ }
272
+ }
273
+ }
274
+ exports.MessagingStream = MessagingStream;
25
275
  class MessagingClient extends event_emitter_js_1.EventEmitter {
26
276
  constructor({ room }) {
27
277
  super();
@@ -30,6 +280,8 @@ class MessagingClient extends event_emitter_js_1.EventEmitter {
30
280
  this._messageQueue = [];
31
281
  this._messageQueued = null;
32
282
  this._sendTask = null;
283
+ this._sendOperations = new Set();
284
+ this._streams = new Set();
33
285
  this._messageQueueClosed = false;
34
286
  this._desiredEnabled = false;
35
287
  this._online = false;
@@ -59,11 +311,12 @@ class MessagingClient extends event_emitter_js_1.EventEmitter {
59
311
  }
60
312
  return input;
61
313
  }
62
- async _invoke({ operation, input, }) {
314
+ async _invoke({ operation, input, afterSend, }) {
63
315
  await this.client.invokeContent({
64
316
  toolkit: "messaging",
65
317
  tool: operation,
66
318
  input: new response_js_1.JsonContent({ json: input }),
319
+ afterSend,
67
320
  });
68
321
  }
69
322
  _invokeNowait({ operation, input, }) {
@@ -93,6 +346,8 @@ class MessagingClient extends event_emitter_js_1.EventEmitter {
93
346
  if (sendTask != null) {
94
347
  await sendTask;
95
348
  }
349
+ await Promise.all(this._sendOperations);
350
+ await Promise.all([...this._streams].map(async (stream) => stream.close()));
96
351
  this._desiredEnabled = false;
97
352
  this._clearCurrentConnectionState();
98
353
  }
@@ -156,6 +411,9 @@ class MessagingClient extends event_emitter_js_1.EventEmitter {
156
411
  }
157
412
  }
158
413
  _onRoomDisconnect({ reason: _reason }) {
414
+ for (const stream of [...this._streams]) {
415
+ stream.clientDisconnected(this.client.localParticipant?.id ?? stream.remoteParticipantId);
416
+ }
159
417
  this._clearCurrentConnectionState();
160
418
  }
161
419
  _onRoomReconnect() {
@@ -238,34 +496,52 @@ class MessagingClient extends event_emitter_js_1.EventEmitter {
238
496
  });
239
497
  continue;
240
498
  }
241
- try {
242
- await this._invoke({
243
- operation: "send",
244
- input: this._messageInput({
245
- toParticipantId: resolvedTo.id,
246
- type: message.type,
247
- message: message.message,
248
- attachment: message.attachment,
249
- }),
250
- });
251
- if (message.completer != null && !message.completer.completed) {
252
- message.completer.complete();
253
- }
499
+ const dispatched = new completer_js_1.Completer();
500
+ const operation = this._sendQueuedMessage({
501
+ message,
502
+ resolvedTo,
503
+ afterSend: () => dispatched.resolve(),
504
+ });
505
+ this._sendOperations.add(operation);
506
+ void operation.then(() => {
507
+ this._sendOperations.delete(operation);
508
+ if (!dispatched.completed)
509
+ dispatched.resolve();
510
+ }, () => {
511
+ this._sendOperations.delete(operation);
512
+ if (!dispatched.completed)
513
+ dispatched.resolve();
514
+ });
515
+ await dispatched.fut;
516
+ }
517
+ }
518
+ async _sendQueuedMessage({ message, resolvedTo, afterSend, }) {
519
+ try {
520
+ await this._invoke({
521
+ operation: "send",
522
+ input: this._messageInput({
523
+ toParticipantId: resolvedTo.id,
524
+ type: message.type,
525
+ message: message.message,
526
+ attachment: message.attachment,
527
+ }),
528
+ afterSend,
529
+ });
530
+ if (message.completer != null && !message.completer.completed) {
531
+ message.completer.complete();
254
532
  }
255
- catch (error) {
256
- if (error instanceof room_server_client_js_1.RoomServerException) {
257
- const wrapped = this.client._coerceMessageSendError(error);
258
- if (wrapped.message === "the participant was not found") {
259
- this._markParticipantOffline(message.to);
260
- this._dropQueuedMessage({ message, error: wrapped });
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);
533
+ }
534
+ catch (error) {
535
+ if (error instanceof room_server_client_js_1.RoomServerException) {
536
+ const wrapped = this.client._coerceMessageSendError(error);
537
+ if (wrapped.message === "the participant was not found") {
538
+ this._markParticipantOffline(message.to);
268
539
  }
540
+ this._dropQueuedMessage({ message, error: wrapped });
541
+ return;
542
+ }
543
+ if (message.completer != null && !message.completer.completed) {
544
+ message.completer.completeError(error);
269
545
  }
270
546
  }
271
547
  }
@@ -330,6 +606,49 @@ class MessagingClient extends event_emitter_js_1.EventEmitter {
330
606
  throw error;
331
607
  }
332
608
  }
609
+ async stream({ to, type, message, attachment, }) {
610
+ const input = new MessagingStreamInput();
611
+ void input.enqueue(new response_js_1.JsonContent({
612
+ json: {
613
+ to_participant_id: to.id,
614
+ type,
615
+ message_json: JSON.stringify(message),
616
+ ...(attachment == null ? {} : { attachment_base64: bytesToBase64(attachment) }),
617
+ },
618
+ }));
619
+ const outputResult = await this.client.invokeToolCall({
620
+ toolkit: "messaging",
621
+ tool: "stream",
622
+ input: input.stream(),
623
+ streamInput: true,
624
+ });
625
+ if (outputResult.kind !== "stream") {
626
+ input.close();
627
+ throw new room_server_client_js_1.RoomServerException("unexpected return type from messaging.stream");
628
+ }
629
+ const outputIterable = outputResult.stream;
630
+ const output = outputIterable[Symbol.asyncIterator]();
631
+ const accepted = await output.next();
632
+ if (accepted.done
633
+ || !(accepted.value instanceof response_js_1.JsonContent)
634
+ || accepted.value.json["kind"] !== "accepted"
635
+ || typeof accepted.value.json["stream_id"] !== "string") {
636
+ input.close();
637
+ await output.return?.();
638
+ throw new room_server_client_js_1.RoomServerException("messaging.stream did not acknowledge acceptance");
639
+ }
640
+ let stream;
641
+ stream = new MessagingStream({
642
+ streamId: accepted.value.json["stream_id"],
643
+ remoteParticipantId: to.id,
644
+ input,
645
+ output,
646
+ inputClosed: outputResult.inputClosed,
647
+ onClosed: () => this._streams.delete(stream),
648
+ });
649
+ this._streams.add(stream);
650
+ return stream;
651
+ }
333
652
  getParticipants() {
334
653
  return this.remoteParticipants;
335
654
  }
@@ -423,6 +742,9 @@ class MessagingClient extends event_emitter_js_1.EventEmitter {
423
742
  this._wakeMessageQueue();
424
743
  this._drainQueuedMessages({ error });
425
744
  this._desiredEnabled = false;
745
+ for (const stream of [...this._streams]) {
746
+ stream.clientDisconnected(this.client.localParticipant?.id ?? stream.remoteParticipantId);
747
+ }
426
748
  this._clearCurrentConnectionState();
427
749
  this.client.protocol.removeHandler("messaging.send", this._messageHandler);
428
750
  super.dispose();
@@ -404,6 +404,7 @@ export declare class ParticipantToken {
404
404
  addTunnelGrant(ports: number[]): void;
405
405
  addRoleGrant(role: string): void;
406
406
  addRoomGrant(roomName: string): void;
407
+ addSiteGrant(roomName: string): void;
407
408
  addApiGrant(grant: ApiScope): void;
408
409
  grantScope(name: string): string | ApiScope | undefined;
409
410
  getApiGrant(): ApiScope | undefined;
@@ -1323,6 +1323,9 @@ class ParticipantToken {
1323
1323
  addRoomGrant(roomName) {
1324
1324
  this.grants.push(new ParticipantGrant({ name: "room", scope: roomName }));
1325
1325
  }
1326
+ addSiteGrant(roomName) {
1327
+ this.grants.push(new ParticipantGrant({ name: "site", scope: roomName }));
1328
+ }
1326
1329
  addApiGrant(grant) {
1327
1330
  for (const existingGrant of this.grants) {
1328
1331
  if (existingGrant.name === "api") {
@@ -189,7 +189,8 @@ 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
+ private _dispatchRequest;
193
194
  call(params: {
194
195
  name: string;
195
196
  url: string;
@@ -216,6 +217,7 @@ export declare class RoomClient {
216
217
  input?: InvokeInput;
217
218
  participantId?: string;
218
219
  onBehalfOfId?: string;
220
+ afterSend?: () => void;
219
221
  }): Promise<Content>;
220
222
  invokeToolCall(params: {
221
223
  toolkit: string;
@@ -224,6 +226,7 @@ export declare class RoomClient {
224
226
  streamInput?: boolean;
225
227
  participantId?: string;
226
228
  onBehalfOfId?: string;
229
+ afterSend?: () => void;
227
230
  }): Promise<{
228
231
  kind: "content";
229
232
  content: Content;
@@ -247,7 +250,7 @@ export declare class RoomClient {
247
250
  participantId?: string;
248
251
  onBehalfOfId?: string;
249
252
  }): Promise<AsyncIterable<Content>>;
250
- private _sendToolCallRequestChunk;
253
+ private _dispatchToolCallRequestChunk;
251
254
  private _streamInvokeToolRequestChunks;
252
255
  private _decodeToolCallContent;
253
256
  private _handleToolCallResponseChunk;
@@ -1146,7 +1146,12 @@ 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
+ const response = this._dispatchRequest(type, request, data);
1151
+ afterSend?.();
1152
+ return await response;
1153
+ }
1154
+ _dispatchRequest(type, request, data) {
1150
1155
  this._raiseIfTerminal();
1151
1156
  if (this._entered && !this._connected && !this._allowDisconnectedRequests) {
1152
1157
  throw this._disconnectedError({ baseMessage: "room connection is disconnected" });
@@ -1155,8 +1160,8 @@ class RoomClient {
1155
1160
  const completer = new completer_js_1.Completer();
1156
1161
  this._pendingRequests.set(requestId, completer);
1157
1162
  try {
1158
- await this._protocolInstance.send(type, (0, utils_js_1.packMessage)(request, data), requestId);
1159
- return await completer.fut;
1163
+ this._protocolInstance.sendNowait(type, (0, utils_js_1.packMessage)(request, data), { id: requestId });
1164
+ return completer.fut;
1160
1165
  }
1161
1166
  catch (error) {
1162
1167
  this._pendingRequests.delete(requestId);
@@ -1239,6 +1244,7 @@ class RoomClient {
1239
1244
  input: this._normalizeInvokeInput(params.input ?? params.arguments),
1240
1245
  participantId: params.participantId,
1241
1246
  onBehalfOfId: params.onBehalfOfId,
1247
+ afterSend: params.afterSend,
1242
1248
  });
1243
1249
  if (output.kind !== "content") {
1244
1250
  throw new room_server_client_js_1.RoomServerException("unexpected streamed output from " + params.toolkit + "." + params.tool);
@@ -1261,7 +1267,6 @@ class RoomClient {
1261
1267
  let requestTask;
1262
1268
  if (params.streamInput === true) {
1263
1269
  request["arguments"] = { type: "control", method: "open" };
1264
- requestTask = this._streamInvokeToolRequestChunks(toolCallId, params.input);
1265
1270
  }
1266
1271
  else {
1267
1272
  const input = params.input;
@@ -1278,9 +1283,14 @@ class RoomClient {
1278
1283
  if (params.onBehalfOfId != null) {
1279
1284
  request["on_behalf_of_id"] = params.onBehalfOfId;
1280
1285
  }
1286
+ const responseRequest = this._dispatchRequest("room.invoke_tool", request, requestData);
1287
+ params.afterSend?.();
1288
+ if (params.streamInput === true) {
1289
+ requestTask = this._streamInvokeToolRequestChunks(toolCallId, params.input);
1290
+ }
1281
1291
  try {
1282
1292
  const response = await Promise.race([
1283
- this.sendRequest("room.invoke_tool", request, requestData),
1293
+ responseRequest,
1284
1294
  preOpenError.fut,
1285
1295
  ]);
1286
1296
  this._toolCallPreOpenErrors.delete(toolCallId);
@@ -1335,9 +1345,10 @@ class RoomClient {
1335
1345
  if (params.onBehalfOfId != null) {
1336
1346
  request["on_behalf_of_id"] = params.onBehalfOfId;
1337
1347
  }
1348
+ const responseRequest = this._dispatchRequest("room.invoke_tool", request);
1338
1349
  const requestTask = this._streamInvokeToolRequestChunks(toolCallId, params.input);
1339
1350
  try {
1340
- const response = await this.sendRequest("room.invoke_tool", request);
1351
+ const response = await responseRequest;
1341
1352
  await requestTask;
1342
1353
  if (response instanceof response_js_1.ControlContent && response.method === "open") {
1343
1354
  throw new room_server_client_js_1.RoomServerException(`unexpected return type from ${params.toolkit}.${params.tool}`);
@@ -1368,6 +1379,7 @@ class RoomClient {
1368
1379
  if (params.onBehalfOfId != null) {
1369
1380
  request["on_behalf_of_id"] = params.onBehalfOfId;
1370
1381
  }
1382
+ const responseRequest = this._dispatchRequest("room.invoke_tool", request);
1371
1383
  const requestTask = this._streamInvokeToolRequestChunks(toolCallId, params.input);
1372
1384
  void requestTask.catch((error) => {
1373
1385
  const stream = this._toolCallStreams.get(toolCallId);
@@ -1381,7 +1393,7 @@ class RoomClient {
1381
1393
  let response;
1382
1394
  try {
1383
1395
  response = await Promise.race([
1384
- this.sendRequest("room.invoke_tool", request),
1396
+ responseRequest,
1385
1397
  preOpenError.fut,
1386
1398
  ]);
1387
1399
  }
@@ -1403,24 +1415,27 @@ class RoomClient {
1403
1415
  },
1404
1416
  };
1405
1417
  }
1406
- async _sendToolCallRequestChunk(toolCallId, chunk) {
1418
+ _dispatchToolCallRequestChunk(toolCallId, chunk) {
1419
+ this._raiseIfTerminal();
1420
+ if (this._entered && !this._connected && !this._allowDisconnectedRequests) {
1421
+ throw this._disconnectedError({ baseMessage: "room connection is disconnected" });
1422
+ }
1407
1423
  const packed = chunk.pack();
1408
1424
  const request = {
1409
1425
  tool_call_id: toolCallId,
1410
1426
  chunk: JSON.parse((0, utils_js_1.splitMessageHeader)(packed)),
1411
1427
  };
1412
1428
  const payload = (0, utils_js_1.splitMessagePayload)(packed);
1413
- await this.sendRequest("room.tool_call_request_chunk", request, payload.length > 0 ? payload : undefined);
1429
+ this._protocolInstance.sendNowait("room.tool_call_request_chunk", (0, utils_js_1.packMessage)(request, payload.length > 0 ? payload : undefined));
1414
1430
  }
1415
1431
  async _streamInvokeToolRequestChunks(toolCallId, input) {
1416
- await Promise.resolve();
1417
1432
  try {
1418
1433
  for await (const item of input) {
1419
- await this._sendToolCallRequestChunk(toolCallId, item);
1434
+ this._dispatchToolCallRequestChunk(toolCallId, item);
1420
1435
  }
1421
1436
  }
1422
1437
  finally {
1423
- await this._sendToolCallRequestChunk(toolCallId, new response_js_1.ControlContent({ method: "close" }));
1438
+ this._dispatchToolCallRequestChunk(toolCallId, new response_js_1.ControlContent({ method: "close" }));
1424
1439
  }
1425
1440
  }
1426
1441
  _decodeToolCallContent(params) {
package/dist/esm/agent.js CHANGED
@@ -511,10 +511,10 @@ class _RemoteToolkitWrapper {
511
511
  return false;
512
512
  }
513
513
  }
514
- async _sendToolCallResponseChunk(messageId, toolCallId, chunk) {
514
+ _sendToolCallResponseChunk(messageId, toolCallId, chunk) {
515
515
  const [header, payload] = unpackMessage(chunk.pack());
516
516
  try {
517
- await this.client.protocol.send("room.tool_call_response_chunk", packMessage({ tool_call_id: toolCallId, chunk: header }, payload.length > 0 ? payload : undefined), { id: messageId });
517
+ this.client.protocol.sendNowait("room.tool_call_response_chunk", packMessage({ tool_call_id: toolCallId, chunk: header }, payload.length > 0 ? payload : undefined), { id: messageId });
518
518
  return true;
519
519
  }
520
520
  catch (error) {
@@ -615,10 +615,10 @@ class _RemoteToolkitWrapper {
615
615
  return;
616
616
  for await (const chunk of output.stream) {
617
617
  this.toolkit.validateOutputContent(tool, chunk);
618
- if (!await this._sendToolCallResponseChunk(messageId, toolCallId, chunk))
618
+ if (!this._sendToolCallResponseChunk(messageId, toolCallId, chunk))
619
619
  return;
620
620
  }
621
- await this._sendToolCallResponseChunk(messageId, toolCallId, new ControlContent({ method: "close" }));
621
+ this._sendToolCallResponseChunk(messageId, toolCallId, new ControlContent({ method: "close" }));
622
622
  return;
623
623
  }
624
624
  throw new Error(`tool ${toolName} returned unsupported output`);
@@ -629,9 +629,9 @@ class _RemoteToolkitWrapper {
629
629
  return;
630
630
  }
631
631
  if (!(error instanceof InvalidToolDataException)) {
632
- await this._sendToolCallResponseChunk(messageId, toolCallId, new ErrorContent({ text: String(error) }));
632
+ this._sendToolCallResponseChunk(messageId, toolCallId, new ErrorContent({ text: String(error) }));
633
633
  }
634
- await this._sendToolCallResponseChunk(messageId, toolCallId, new ControlContent({
634
+ this._sendToolCallResponseChunk(messageId, toolCallId, new ControlContent({
635
635
  method: "close",
636
636
  statusCode: error instanceof InvalidToolDataException ? ControlCloseStatus.INVALID_DATA : undefined,
637
637
  message: error instanceof InvalidToolDataException ? error.message : undefined,