@meshagent/meshagent 0.44.11 → 0.44.13

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.
Files changed (68) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/browser/agent-client.js +1 -1
  3. package/dist/browser/containers-client.js +1 -1
  4. package/dist/browser/datasets-client.d.ts +1 -1
  5. package/dist/browser/datasets-client.js +15 -15
  6. package/dist/browser/developer-client.js +1 -1
  7. package/dist/browser/entrypoint.js +5 -1
  8. package/dist/browser/memory-client.js +1 -1
  9. package/dist/browser/meshagent-client.d.ts +123 -7
  10. package/dist/browser/meshagent-client.js +357 -10
  11. package/dist/browser/messaging-client.js +1 -1
  12. package/dist/browser/queues-client.js +1 -1
  13. package/dist/browser/requirement.d.ts +21 -0
  14. package/dist/browser/requirement.js +87 -1
  15. package/dist/browser/room-client.d.ts +12 -1
  16. package/dist/browser/room-client.js +91 -31
  17. package/dist/browser/secrets-client.js +1 -1
  18. package/dist/browser/services-client.js +2 -2
  19. package/dist/browser/storage-client.d.ts +1 -1
  20. package/dist/browser/storage-client.js +1 -1
  21. package/dist/browser/stream-controller.d.ts +1 -0
  22. package/dist/browser/stream-controller.js +27 -7
  23. package/dist/browser/sync-client.js +1 -1
  24. package/dist/esm/agent-client.js +1 -1
  25. package/dist/esm/containers-client.js +1 -1
  26. package/dist/esm/datasets-client.d.ts +1 -1
  27. package/dist/esm/datasets-client.js +15 -15
  28. package/dist/esm/developer-client.js +1 -1
  29. package/dist/esm/entrypoint.js +6 -1
  30. package/dist/esm/memory-client.js +1 -1
  31. package/dist/esm/meshagent-client.d.ts +123 -7
  32. package/dist/esm/meshagent-client.js +353 -10
  33. package/dist/esm/messaging-client.js +1 -1
  34. package/dist/esm/queues-client.js +1 -1
  35. package/dist/esm/requirement.d.ts +21 -0
  36. package/dist/esm/requirement.js +84 -0
  37. package/dist/esm/room-client.d.ts +12 -1
  38. package/dist/esm/room-client.js +92 -32
  39. package/dist/esm/secrets-client.js +1 -1
  40. package/dist/esm/services-client.js +2 -2
  41. package/dist/esm/storage-client.d.ts +1 -1
  42. package/dist/esm/storage-client.js +1 -1
  43. package/dist/esm/stream-controller.d.ts +1 -0
  44. package/dist/esm/stream-controller.js +27 -7
  45. package/dist/esm/sync-client.js +1 -1
  46. package/dist/node/agent-client.js +1 -1
  47. package/dist/node/containers-client.js +1 -1
  48. package/dist/node/datasets-client.d.ts +1 -1
  49. package/dist/node/datasets-client.js +15 -15
  50. package/dist/node/developer-client.js +1 -1
  51. package/dist/node/entrypoint.js +6 -1
  52. package/dist/node/memory-client.js +1 -1
  53. package/dist/node/meshagent-client.d.ts +123 -7
  54. package/dist/node/meshagent-client.js +357 -10
  55. package/dist/node/messaging-client.js +1 -1
  56. package/dist/node/queues-client.js +1 -1
  57. package/dist/node/requirement.d.ts +21 -0
  58. package/dist/node/requirement.js +87 -1
  59. package/dist/node/room-client.d.ts +12 -1
  60. package/dist/node/room-client.js +91 -31
  61. package/dist/node/secrets-client.js +1 -1
  62. package/dist/node/services-client.js +2 -2
  63. package/dist/node/storage-client.d.ts +1 -1
  64. package/dist/node/storage-client.js +1 -1
  65. package/dist/node/stream-controller.d.ts +1 -0
  66. package/dist/node/stream-controller.js +27 -7
  67. package/dist/node/sync-client.js +1 -1
  68. package/package.json +1 -1
@@ -1,10 +1,260 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Meshagent = void 0;
3
+ exports.Meshagent = exports.ManagedAgentGrant = exports.ServiceTemplateSpec = exports.RoomSession = void 0;
4
+ exports.normalizeServiceSpec = normalizeServiceSpec;
4
5
  const helpers_js_1 = require("./helpers.js");
5
6
  const requirement_js_1 = require("./requirement.js");
6
7
  const participant_token_js_1 = require("./participant-token.js");
7
8
  const utils_js_1 = require("./utils.js");
9
+ class RoomSession {
10
+ constructor({ id, roomId, roomName, createdAt, isActive, participants, kind = "room", agentId, agentName, }) {
11
+ this.id = id;
12
+ this.roomId = roomId;
13
+ this.roomName = roomName;
14
+ this.createdAt = createdAt;
15
+ this.isActive = isActive;
16
+ this.participants = participants;
17
+ this.kind = kind;
18
+ this.agentId = agentId;
19
+ this.agentName = agentName;
20
+ }
21
+ toJson() {
22
+ return {
23
+ id: this.id,
24
+ room_id: this.roomId ?? null,
25
+ room_name: this.roomName,
26
+ started_at: this.createdAt.toISOString(),
27
+ is_active: this.isActive,
28
+ kind: this.kind,
29
+ ...(this.agentId != null ? { agent_id: this.agentId } : {}),
30
+ ...(this.agentName != null ? { agent_name: this.agentName } : {}),
31
+ };
32
+ }
33
+ }
34
+ exports.RoomSession = RoomSession;
35
+ function cloneJsonValue(value) {
36
+ if (Array.isArray(value)) {
37
+ return value.map((item) => cloneJsonValue(item));
38
+ }
39
+ if (value != null && typeof value === "object") {
40
+ const result = {};
41
+ for (const [key, item] of Object.entries(value)) {
42
+ result[key] = cloneJsonValue(item);
43
+ }
44
+ return result;
45
+ }
46
+ return value;
47
+ }
48
+ function formatTemplateString(value, values) {
49
+ return value.replace(/\{([A-Za-z_][A-Za-z0-9_]*)\}/g, (token, key) => values[key] ?? token);
50
+ }
51
+ function formatJsonValue(value, values) {
52
+ if (typeof value === "string") {
53
+ return formatTemplateString(value, values);
54
+ }
55
+ if (Array.isArray(value)) {
56
+ return value.map((item) => formatJsonValue(item, values));
57
+ }
58
+ if (value != null && typeof value === "object") {
59
+ const result = {};
60
+ for (const [key, item] of Object.entries(value)) {
61
+ result[key] = formatJsonValue(item, values);
62
+ }
63
+ return result;
64
+ }
65
+ return value;
66
+ }
67
+ function objectOrUndefined(value) {
68
+ return value != null && typeof value === "object" && !Array.isArray(value)
69
+ ? value
70
+ : undefined;
71
+ }
72
+ function objectArray(value) {
73
+ return Array.isArray(value)
74
+ ? value.filter((item) => objectOrUndefined(item) !== undefined)
75
+ : undefined;
76
+ }
77
+ function stringValue(value) {
78
+ return typeof value === "string" ? value : undefined;
79
+ }
80
+ function booleanValue(value) {
81
+ return typeof value === "boolean" ? value : undefined;
82
+ }
83
+ function normalizeRoomMount(value) {
84
+ return {
85
+ path: stringValue(value.path) ?? "",
86
+ ...(stringValue(value.subpath) !== undefined ? { subpath: stringValue(value.subpath) } : {}),
87
+ ...(booleanValue(value.read_only) !== undefined ? { read_only: booleanValue(value.read_only) } : {}),
88
+ };
89
+ }
90
+ function normalizeProjectMount(value) {
91
+ return {
92
+ path: stringValue(value.path) ?? "",
93
+ ...(stringValue(value.subpath) !== undefined ? { subpath: stringValue(value.subpath) } : {}),
94
+ read_only: booleanValue(value.read_only) ?? true,
95
+ };
96
+ }
97
+ function normalizeImageMount(value) {
98
+ return {
99
+ path: stringValue(value.path) ?? "",
100
+ ...(stringValue(value.subpath) !== undefined ? { subpath: stringValue(value.subpath) } : {}),
101
+ read_only: booleanValue(value.read_only) ?? true,
102
+ image: stringValue(value.image) ?? "",
103
+ };
104
+ }
105
+ function normalizeFileMount(value) {
106
+ return {
107
+ path: stringValue(value.path) ?? "",
108
+ ...(stringValue(value.subpath) !== undefined ? { subpath: stringValue(value.subpath) } : {}),
109
+ read_only: booleanValue(value.read_only) ?? true,
110
+ text: stringValue(value.text) ?? "",
111
+ };
112
+ }
113
+ function normalizeEmptyDirMount(value) {
114
+ return {
115
+ path: stringValue(value.path) ?? "",
116
+ read_only: booleanValue(value.read_only) ?? false,
117
+ };
118
+ }
119
+ function normalizeConfigMount(value) {
120
+ return {
121
+ path: stringValue(value.path) ?? "/var/run/meshagent",
122
+ };
123
+ }
124
+ function normalizeContainerMountSpec(value) {
125
+ const source = objectOrUndefined(value) ?? {};
126
+ const room = objectArray(source.room)?.map(normalizeRoomMount);
127
+ const project = objectArray(source.project)?.map(normalizeProjectMount);
128
+ const images = objectArray(source.images)?.map(normalizeImageMount);
129
+ const files = objectArray(source.files)?.map(normalizeFileMount);
130
+ const emptyDirs = objectArray(source.empty_dirs)?.map(normalizeEmptyDirMount);
131
+ const configs = objectArray(source.configs)?.map(normalizeConfigMount);
132
+ return {
133
+ ...(room !== undefined ? { room } : {}),
134
+ ...(project !== undefined ? { project } : {}),
135
+ ...(images !== undefined ? { images } : {}),
136
+ ...(files !== undefined ? { files } : {}),
137
+ ...(emptyDirs !== undefined ? { empty_dirs: emptyDirs } : {}),
138
+ ...(configs !== undefined ? { configs } : {}),
139
+ };
140
+ }
141
+ function normalizeAgentSpec(agent, values) {
142
+ const formatted = formatJsonValue(agent, values);
143
+ const spec = cloneJsonValue(formatted);
144
+ if (spec.email != null && spec.email.public == null) {
145
+ spec.email = { ...spec.email, public: false };
146
+ }
147
+ if (spec.channels?.email) {
148
+ spec.channels = {
149
+ ...spec.channels,
150
+ email: spec.channels.email.map((channel) => ({
151
+ ...channel,
152
+ private: channel.private ?? false,
153
+ })),
154
+ };
155
+ }
156
+ if (spec.channels?.messaging) {
157
+ spec.channels = {
158
+ ...spec.channels,
159
+ messaging: spec.channels.messaging.map((channel) => ({
160
+ ...channel,
161
+ protocol: channel.protocol ?? "meshagent.agent-message.v1",
162
+ })),
163
+ };
164
+ }
165
+ return spec;
166
+ }
167
+ function normalizeServiceSpec(service) {
168
+ const normalized = cloneJsonValue(service);
169
+ if (normalized.container?.storage != null) {
170
+ normalized.container = {
171
+ ...normalized.container,
172
+ storage: normalizeContainerMountSpec(normalized.container.storage),
173
+ };
174
+ }
175
+ return normalized;
176
+ }
177
+ class ServiceTemplateSpec {
178
+ constructor({ version = "v1", kind = "ServiceTemplate", variables, metadata, ports = [], container, external, agents = [], }) {
179
+ this.version = version;
180
+ this.kind = kind;
181
+ this.variables = variables;
182
+ this.metadata = metadata;
183
+ this.ports = ports;
184
+ this.container = container;
185
+ this.external = external;
186
+ this.agents = agents;
187
+ }
188
+ static fromJson(json) {
189
+ const metadata = objectOrUndefined(json.metadata);
190
+ if (metadata === undefined || typeof metadata.name !== "string") {
191
+ throw new requirement_js_1.RoomException("Invalid service template payload: missing metadata.name");
192
+ }
193
+ return new ServiceTemplateSpec({
194
+ version: stringValue(json.version) ?? "v1",
195
+ kind: stringValue(json.kind) ?? "ServiceTemplate",
196
+ variables: objectArray(json.variables),
197
+ metadata: cloneJsonValue(metadata),
198
+ ports: (objectArray(json.ports) ?? []),
199
+ container: objectOrUndefined(json.container),
200
+ external: objectOrUndefined(json.external),
201
+ agents: objectArray(json.agents) ?? [],
202
+ });
203
+ }
204
+ toJson() {
205
+ return {
206
+ version: this.version,
207
+ kind: this.kind,
208
+ ...(this.variables != null ? { variables: cloneJsonValue(this.variables) } : {}),
209
+ metadata: cloneJsonValue(this.metadata),
210
+ ...(this.ports.length > 0 ? { ports: cloneJsonValue(this.ports) } : {}),
211
+ ...(this.container != null ? { container: cloneJsonValue(this.container) } : {}),
212
+ ...(this.external != null ? { external: cloneJsonValue(this.external) } : {}),
213
+ ...(this.agents.length > 0 ? { agents: cloneJsonValue(this.agents) } : {}),
214
+ };
215
+ }
216
+ toServiceSpec({ values = {} } = {}) {
217
+ const service = {
218
+ version: "v1",
219
+ kind: "Service",
220
+ metadata: cloneJsonValue(this.metadata),
221
+ agents: this.agents.map((agent) => normalizeAgentSpec(agent, values)),
222
+ ports: cloneJsonValue(this.ports),
223
+ };
224
+ if (this.container != null) {
225
+ const formattedContainer = formatJsonValue(this.container, values);
226
+ const image = stringValue(formattedContainer.image);
227
+ if (image === undefined || image.length === 0) {
228
+ throw new requirement_js_1.RoomException("ServiceTemplateSpec.image is required to build a ServiceSpec");
229
+ }
230
+ service.container = {
231
+ ...(booleanValue(formattedContainer.private) !== undefined ? { private: booleanValue(formattedContainer.private) } : {}),
232
+ ...(stringValue(formattedContainer.command) !== undefined ? { command: stringValue(formattedContainer.command) } : {}),
233
+ ...(stringValue(formattedContainer.working_dir) !== undefined ? { working_dir: stringValue(formattedContainer.working_dir) } : {}),
234
+ image,
235
+ ...(Array.isArray(formattedContainer.environment)
236
+ ? { environment: formattedContainer.environment }
237
+ : {}),
238
+ ...(objectOrUndefined(formattedContainer.storage) !== undefined
239
+ ? { storage: normalizeContainerMountSpec(formattedContainer.storage) }
240
+ : {}),
241
+ ...(booleanValue(formattedContainer.on_demand) !== undefined ? { on_demand: booleanValue(formattedContainer.on_demand) } : {}),
242
+ ...(booleanValue(formattedContainer.writable_root_fs) !== undefined
243
+ ? { writable_root_fs: booleanValue(formattedContainer.writable_root_fs) }
244
+ : {}),
245
+ };
246
+ }
247
+ if (this.external != null) {
248
+ const formattedExternal = formatJsonValue(this.external, values);
249
+ const url = stringValue(formattedExternal.url);
250
+ if (url !== undefined) {
251
+ service.external = { url };
252
+ }
253
+ }
254
+ return normalizeServiceSpec(service);
255
+ }
256
+ }
257
+ exports.ServiceTemplateSpec = ServiceTemplateSpec;
8
258
  function pruneUndefinedValues(value) {
9
259
  if (Array.isArray(value)) {
10
260
  const prunedItems = value
@@ -27,6 +277,27 @@ function pruneUndefinedValues(value) {
27
277
  }
28
278
  return value;
29
279
  }
280
+ function pruneNullishValues(value) {
281
+ if (Array.isArray(value)) {
282
+ return value
283
+ .map((item) => pruneNullishValues(item))
284
+ .filter((item) => item !== undefined);
285
+ }
286
+ if (value === null || value === undefined) {
287
+ return undefined;
288
+ }
289
+ if (typeof value === "object") {
290
+ const result = {};
291
+ for (const [key, entryValue] of Object.entries(value)) {
292
+ const normalized = pruneNullishValues(entryValue);
293
+ if (normalized !== undefined) {
294
+ result[key] = normalized;
295
+ }
296
+ }
297
+ return result;
298
+ }
299
+ return value;
300
+ }
30
301
  function serializeServiceSpec(service) {
31
302
  const agents = service.agents?.map((agent) => ({
32
303
  ...agent,
@@ -50,6 +321,18 @@ function serializeCreateServiceSpec(service) {
50
321
  delete payload.id;
51
322
  return payload;
52
323
  }
324
+ class ManagedAgentGrant {
325
+ constructor({ admin = false } = {}) {
326
+ this.admin = admin;
327
+ }
328
+ static fromJson(json) {
329
+ return new ManagedAgentGrant({ admin: json["admin"] === true });
330
+ }
331
+ toJson() {
332
+ return { admin: this.admin };
333
+ }
334
+ }
335
+ exports.ManagedAgentGrant = ManagedAgentGrant;
53
336
  const globalScope = globalThis;
54
337
  function bytesToBase64(bytes) {
55
338
  if (globalScope.Buffer) {
@@ -152,7 +435,11 @@ class Meshagent {
152
435
  catch {
153
436
  message = "<unable to read body>";
154
437
  }
155
- throw new requirement_js_1.RoomException(`Failed to ${action}. Status code: ${response.status}, body: ${message}`);
438
+ const errorMessage = `Failed to ${action}. Status code: ${response.status}, body: ${message}`;
439
+ if (response.status === 403) {
440
+ throw new requirement_js_1.ForbiddenException(errorMessage);
441
+ }
442
+ throw new requirement_js_1.RoomException(errorMessage);
156
443
  }
157
444
  switch (responseType) {
158
445
  case "json":
@@ -191,7 +478,7 @@ class Meshagent {
191
478
  if (!data || typeof data !== "object") {
192
479
  throw new requirement_js_1.RoomException("Invalid room session payload");
193
480
  }
194
- const { id, room_id: roomIdRaw, roomId, room_name: roomNameRaw, roomName, created_at: createdRaw, createdAt, is_active: isActiveRaw, isActive, participants } = data;
481
+ const { id, room_id: roomIdRaw, roomId, room_name: roomNameRaw, roomName, created_at: createdRaw, createdAt, is_active: isActiveRaw, isActive, participants, kind, agent_id: agentIdRaw, agentId, agent_name: agentNameRaw, agentName, } = data;
195
482
  if (typeof id !== "string") {
196
483
  throw new requirement_js_1.RoomException("Invalid room session payload: missing id");
197
484
  }
@@ -207,13 +494,32 @@ class Meshagent {
207
494
  if (typeof isActiveValue !== "boolean") {
208
495
  throw new requirement_js_1.RoomException("Invalid room session payload: missing is_active");
209
496
  }
210
- return {
497
+ return new RoomSession({
211
498
  id,
212
499
  roomId: typeof roomId === "string" ? roomId : typeof roomIdRaw === "string" ? roomIdRaw : undefined,
213
500
  roomName: roomNameValue,
214
501
  createdAt: new Date(created),
215
502
  isActive: isActiveValue,
216
503
  participants: participants && typeof participants === "object" ? participants : undefined,
504
+ kind: typeof kind === "string" ? kind : "room",
505
+ agentId: typeof agentId === "string" ? agentId : typeof agentIdRaw === "string" ? agentIdRaw : undefined,
506
+ agentName: typeof agentName === "string" ? agentName : typeof agentNameRaw === "string" ? agentNameRaw : undefined,
507
+ });
508
+ }
509
+ parseManagedAgent(data) {
510
+ if (!data || typeof data !== "object") {
511
+ throw new requirement_js_1.RoomException("Invalid managed agent payload");
512
+ }
513
+ const { id, name, configuration } = data;
514
+ if (typeof id !== "string" || typeof name !== "string") {
515
+ throw new requirement_js_1.RoomException("Invalid managed agent payload: missing id or name");
516
+ }
517
+ return {
518
+ id,
519
+ name,
520
+ configuration: configuration && typeof configuration === "object" && !Array.isArray(configuration)
521
+ ? configuration
522
+ : {},
217
523
  };
218
524
  }
219
525
  parseRoom(data) {
@@ -779,7 +1085,7 @@ class Meshagent {
779
1085
  });
780
1086
  }
781
1087
  async addUserToProject(projectId, userId, options = {}) {
782
- const { isAdmin, isDeveloper, canCreateRooms } = options;
1088
+ const { isAdmin, isDeveloper, canCreateRooms, inviteRedirectUrl } = options;
783
1089
  return await this.request(`/accounts/projects/${projectId}/users`, {
784
1090
  method: "POST",
785
1091
  json: {
@@ -790,6 +1096,28 @@ class Meshagent {
790
1096
  ...(canCreateRooms !== undefined
791
1097
  ? { can_create_rooms: canCreateRooms }
792
1098
  : {}),
1099
+ ...(inviteRedirectUrl !== undefined
1100
+ ? { invite_redirect_url: inviteRedirectUrl }
1101
+ : {}),
1102
+ },
1103
+ action: "add user to project",
1104
+ });
1105
+ }
1106
+ async addUserToProjectByEmail(projectId, email, options = {}) {
1107
+ const { isAdmin, isDeveloper, canCreateRooms, inviteRedirectUrl } = options;
1108
+ return await this.request(`/accounts/projects/${projectId}/users`, {
1109
+ method: "POST",
1110
+ json: {
1111
+ project_id: projectId,
1112
+ email,
1113
+ ...(isAdmin !== undefined ? { is_admin: isAdmin } : {}),
1114
+ ...(isDeveloper !== undefined ? { is_developer: isDeveloper } : {}),
1115
+ ...(canCreateRooms !== undefined
1116
+ ? { can_create_rooms: canCreateRooms }
1117
+ : {}),
1118
+ ...(inviteRedirectUrl !== undefined
1119
+ ? { invite_redirect_url: inviteRedirectUrl }
1120
+ : {}),
793
1121
  },
794
1122
  action: "add user to project",
795
1123
  });
@@ -847,6 +1175,22 @@ class Meshagent {
847
1175
  action: "get project by key",
848
1176
  });
849
1177
  }
1178
+ async createAgent(params) {
1179
+ const { projectId, configuration, ifNotExists = false, permissions } = params;
1180
+ const permissionsJson = permissions == null
1181
+ ? undefined
1182
+ : Object.fromEntries(Object.entries(permissions).map(([userId, grant]) => [userId, grant.toJson()]));
1183
+ const data = await this.request(`/accounts/projects/${this.encodePathComponent(projectId)}/agents`, {
1184
+ method: "POST",
1185
+ json: {
1186
+ configuration: pruneNullishValues(configuration),
1187
+ if_not_exists: ifNotExists,
1188
+ ...(permissionsJson !== undefined ? { permissions: permissionsJson } : {}),
1189
+ },
1190
+ action: "create agent",
1191
+ });
1192
+ return this.parseManagedAgent(data);
1193
+ }
850
1194
  async createApiKey(projectId, name, description) {
851
1195
  return await this.request(`/accounts/projects/${projectId}/api-keys`, {
852
1196
  method: "POST",
@@ -1338,14 +1682,14 @@ class Meshagent {
1338
1682
  const data = await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/services/${serviceId}`, {
1339
1683
  action: "fetch room service",
1340
1684
  });
1341
- return data;
1685
+ return normalizeServiceSpec(data);
1342
1686
  }
1343
1687
  async listRoomServices(projectId, roomName) {
1344
1688
  const data = await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/services`, {
1345
1689
  action: "list room services",
1346
1690
  });
1347
1691
  const services = Array.isArray(data?.services) ? data.services : [];
1348
- return services;
1692
+ return services.map((service) => normalizeServiceSpec(service));
1349
1693
  }
1350
1694
  async deleteRoomService(projectId, roomName, serviceId) {
1351
1695
  await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/services/${serviceId}`, {
@@ -1369,14 +1713,14 @@ class Meshagent {
1369
1713
  const data = await this.request(`/accounts/projects/${projectId}/services/${serviceId}`, {
1370
1714
  action: "fetch service",
1371
1715
  });
1372
- return data;
1716
+ return normalizeServiceSpec(data);
1373
1717
  }
1374
1718
  async listServices(projectId) {
1375
1719
  const data = await this.request(`/accounts/projects/${projectId}/services`, {
1376
1720
  action: "list services",
1377
1721
  });
1378
1722
  const services = Array.isArray(data?.services) ? data.services : [];
1379
- return services;
1723
+ return services.map((service) => normalizeServiceSpec(service));
1380
1724
  }
1381
1725
  async deleteService(projectId, serviceId) {
1382
1726
  await this.request(`/accounts/projects/${projectId}/services/${serviceId}`, {
@@ -1715,13 +2059,16 @@ class Meshagent {
1715
2059
  });
1716
2060
  }
1717
2061
  async createRoomGrantByEmail(params) {
1718
- const { projectId, roomId, email, permissions } = params;
2062
+ const { projectId, roomId, email, permissions, inviteRedirectUrl } = params;
1719
2063
  await this.request(`/accounts/projects/${projectId}/room-grants`, {
1720
2064
  method: "POST",
1721
2065
  json: {
1722
2066
  room_id: roomId,
1723
2067
  email,
1724
2068
  permissions: permissions.toJSON(),
2069
+ ...(inviteRedirectUrl !== undefined
2070
+ ? { invite_redirect_url: inviteRedirectUrl }
2071
+ : {}),
1725
2072
  },
1726
2073
  action: "create room grant",
1727
2074
  responseType: "void",
@@ -60,7 +60,7 @@ class MessagingClient extends event_emitter_js_1.EventEmitter {
60
60
  return input;
61
61
  }
62
62
  async _invoke({ operation, input, }) {
63
- await this.client.invoke({
63
+ await this.client.invokeContent({
64
64
  toolkit: "messaging",
65
65
  tool: operation,
66
66
  input: new response_js_1.JsonContent({ json: input }),
@@ -18,7 +18,7 @@ class QueuesClient {
18
18
  return new room_server_client_js_1.RoomServerException(`unexpected return type from queues.${operation}`);
19
19
  }
20
20
  async _invoke(operation, arguments_) {
21
- return await this.client.invoke({
21
+ return await this.client.invokeContent({
22
22
  toolkit: "queues",
23
23
  tool: operation,
24
24
  arguments: arguments_,
@@ -1,6 +1,10 @@
1
+ import { Schema } from "apache-arrow";
1
2
  export declare class RoomException extends Error {
2
3
  constructor(message: string);
3
4
  }
5
+ export declare class ForbiddenException extends RoomException {
6
+ constructor(message: string);
7
+ }
4
8
  export declare abstract class Requirement {
5
9
  readonly name: string;
6
10
  constructor({ name }: {
@@ -25,3 +29,20 @@ export declare class RequiredSchema extends Requirement {
25
29
  });
26
30
  toJson(): Record<string, any>;
27
31
  }
32
+ export declare class RequiredTable extends Requirement {
33
+ readonly schema: Schema;
34
+ readonly namespace?: string[];
35
+ readonly scalarIndexes?: string[];
36
+ readonly fullTextSearchIndexes?: string[];
37
+ readonly vectorIndexes?: string[];
38
+ constructor({ name, schema, namespace, scalarIndexes, fullTextSearchIndexes, vectorIndexes, }: {
39
+ name: string;
40
+ schema: Schema;
41
+ namespace?: string[];
42
+ scalarIndexes?: string[];
43
+ fullTextSearchIndexes?: string[];
44
+ vectorIndexes?: string[];
45
+ });
46
+ static fromJson(r: Record<string, any>): RequiredTable;
47
+ toJson(): Record<string, any>;
48
+ }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RequiredSchema = exports.RequiredToolkit = exports.Requirement = exports.RoomException = void 0;
3
+ exports.RequiredTable = exports.RequiredSchema = exports.RequiredToolkit = exports.Requirement = exports.ForbiddenException = exports.RoomException = void 0;
4
+ const apache_arrow_1 = require("apache-arrow");
4
5
  class RoomException extends Error {
5
6
  constructor(message) {
6
7
  super(message);
@@ -8,6 +9,51 @@ class RoomException extends Error {
8
9
  }
9
10
  }
10
11
  exports.RoomException = RoomException;
12
+ class ForbiddenException extends RoomException {
13
+ constructor(message) {
14
+ super(message);
15
+ this.name = "ForbiddenException";
16
+ }
17
+ }
18
+ exports.ForbiddenException = ForbiddenException;
19
+ const globalScope = globalThis;
20
+ function bytesToBase64(bytes) {
21
+ if (globalScope.Buffer) {
22
+ return globalScope.Buffer.from(bytes).toString("base64");
23
+ }
24
+ if (!globalScope.btoa) {
25
+ throw new Error("base64 encoding is not available in this runtime");
26
+ }
27
+ let binary = "";
28
+ for (const byte of bytes) {
29
+ binary += String.fromCharCode(byte);
30
+ }
31
+ return globalScope.btoa(binary);
32
+ }
33
+ function base64ToBytes(base64) {
34
+ if (globalScope.Buffer) {
35
+ return Uint8Array.from(globalScope.Buffer.from(base64, "base64"));
36
+ }
37
+ if (!globalScope.atob) {
38
+ throw new Error("base64 decoding is not available in this runtime");
39
+ }
40
+ const binary = globalScope.atob(base64);
41
+ const bytes = new Uint8Array(binary.length);
42
+ for (let index = 0; index < binary.length; index += 1) {
43
+ bytes[index] = binary.charCodeAt(index);
44
+ }
45
+ return bytes;
46
+ }
47
+ function schemaToIPC(schema) {
48
+ return (0, apache_arrow_1.tableToIPC)(new apache_arrow_1.Table(schema, []), "stream");
49
+ }
50
+ function schemaFromIPCBytes(data) {
51
+ const table = (0, apache_arrow_1.tableFromIPC)(data);
52
+ if (table instanceof Promise) {
53
+ throw new RoomException("unexpected async Arrow IPC result");
54
+ }
55
+ return table.schema;
56
+ }
11
57
  class Requirement {
12
58
  constructor({ name }) {
13
59
  this.name = name;
@@ -20,6 +66,9 @@ class Requirement {
20
66
  participantName: r["participant_name"],
21
67
  });
22
68
  }
69
+ if ("table" in r) {
70
+ return RequiredTable.fromJson(r);
71
+ }
23
72
  if ("schema" in r) {
24
73
  return new RequiredSchema({ name: r["schema"] });
25
74
  }
@@ -53,3 +102,40 @@ class RequiredSchema extends Requirement {
53
102
  }
54
103
  }
55
104
  exports.RequiredSchema = RequiredSchema;
105
+ class RequiredTable extends Requirement {
106
+ constructor({ name, schema, namespace, scalarIndexes, fullTextSearchIndexes, vectorIndexes, }) {
107
+ super({ name });
108
+ this.schema = schema;
109
+ this.namespace = namespace;
110
+ this.scalarIndexes = scalarIndexes;
111
+ this.fullTextSearchIndexes = fullTextSearchIndexes;
112
+ this.vectorIndexes = vectorIndexes;
113
+ }
114
+ static fromJson(r) {
115
+ if (typeof r["table"] !== "string") {
116
+ throw new RoomException("required table name must be a string");
117
+ }
118
+ if (typeof r["schema"] !== "string") {
119
+ throw new RoomException("required table schema must be a base64 Arrow IPC schema");
120
+ }
121
+ return new RequiredTable({
122
+ name: r["table"],
123
+ schema: schemaFromIPCBytes(base64ToBytes(r["schema"])),
124
+ namespace: Array.isArray(r["namespace"]) ? r["namespace"].map(String) : undefined,
125
+ scalarIndexes: Array.isArray(r["scalar_indexes"]) ? r["scalar_indexes"].map(String) : undefined,
126
+ fullTextSearchIndexes: Array.isArray(r["full_text_search_indexes"]) ? r["full_text_search_indexes"].map(String) : undefined,
127
+ vectorIndexes: Array.isArray(r["vector_indexes"]) ? r["vector_indexes"].map(String) : undefined,
128
+ });
129
+ }
130
+ toJson() {
131
+ return {
132
+ table: this.name,
133
+ schema: bytesToBase64(schemaToIPC(this.schema)),
134
+ namespace: this.namespace,
135
+ scalar_indexes: this.scalarIndexes,
136
+ full_text_search_indexes: this.fullTextSearchIndexes,
137
+ vector_indexes: this.vectorIndexes,
138
+ };
139
+ }
140
+ }
141
+ exports.RequiredTable = RequiredTable;
@@ -18,6 +18,7 @@ import { ContainersClient } from "./containers-client.js";
18
18
  interface RequestHeader {
19
19
  [key: string]: unknown;
20
20
  }
21
+ export type InvokeInput = Record<string, unknown> | Content;
21
22
  export declare class RoomProtocolProxy {
22
23
  private readonly _room;
23
24
  private readonly _handlers;
@@ -67,6 +68,7 @@ export declare class RoomClient {
67
68
  private readonly _eventEmitter;
68
69
  private readonly _pendingRequests;
69
70
  private readonly _toolCallStreams;
71
+ private readonly _toolCallPreOpenErrors;
70
72
  private readonly _ignoredResponseLabels;
71
73
  private readonly _ready;
72
74
  private readonly _roomClosed;
@@ -202,11 +204,20 @@ export declare class RoomClient {
202
204
  participantName?: string;
203
205
  timeout?: number;
204
206
  }): Promise<ToolkitDescription[]>;
207
+ private _normalizeInvokeInput;
205
208
  invoke(params: {
206
209
  toolkit: string;
207
210
  tool: string;
208
211
  arguments?: Record<string, unknown>;
209
- input?: Record<string, unknown> | Content;
212
+ input?: InvokeInput;
213
+ participantId?: string;
214
+ onBehalfOfId?: string;
215
+ }): AsyncIterable<Content>;
216
+ invokeContent(params: {
217
+ toolkit: string;
218
+ tool: string;
219
+ arguments?: Record<string, unknown>;
220
+ input?: InvokeInput;
210
221
  participantId?: string;
211
222
  onBehalfOfId?: string;
212
223
  }): Promise<Content>;