@meshagent/meshagent 0.44.11 → 0.44.12

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 +6 -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
@@ -11,13 +11,28 @@ export interface RoomConnectionInfo {
11
11
  projectId: string;
12
12
  roomUrl: string;
13
13
  }
14
- export interface RoomSession {
15
- id: string;
16
- roomId?: string | null;
17
- roomName: string;
18
- createdAt: Date;
19
- isActive: boolean;
20
- participants?: Record<string, number>;
14
+ export declare class RoomSession {
15
+ readonly id: string;
16
+ readonly roomId?: string | null;
17
+ readonly roomName: string;
18
+ readonly createdAt: Date;
19
+ readonly isActive: boolean;
20
+ readonly participants?: Record<string, number> | null;
21
+ readonly kind: string;
22
+ readonly agentId?: string | null;
23
+ readonly agentName?: string | null;
24
+ constructor({ id, roomId, roomName, createdAt, isActive, participants, kind, agentId, agentName, }: {
25
+ id: string;
26
+ roomId?: string | null;
27
+ roomName: string;
28
+ createdAt: Date;
29
+ isActive: boolean;
30
+ participants?: Record<string, number> | null;
31
+ kind?: string;
32
+ agentId?: string | null;
33
+ agentName?: string | null;
34
+ });
35
+ toJson(): Record<string, unknown>;
21
36
  }
22
37
  export interface RoomInfo {
23
38
  id: string;
@@ -63,6 +78,18 @@ export interface ProjectStorageMountSpec {
63
78
  subpath?: string | null;
64
79
  read_only?: boolean;
65
80
  }
81
+ export interface ImageStorageMountSpec {
82
+ path: string;
83
+ subpath?: string | null;
84
+ read_only?: boolean;
85
+ image: string;
86
+ }
87
+ export interface FileStorageMountSpec {
88
+ path: string;
89
+ subpath?: string | null;
90
+ read_only?: boolean;
91
+ text: string;
92
+ }
66
93
  export interface EmptyDirMountSpec {
67
94
  path: string;
68
95
  read_only?: boolean;
@@ -73,6 +100,8 @@ export interface ConfigMountSpec {
73
100
  export interface ContainerMountSpec {
74
101
  room?: RoomStorageMountSpec[];
75
102
  project?: ProjectStorageMountSpec[];
103
+ images?: ImageStorageMountSpec[];
104
+ files?: FileStorageMountSpec[];
76
105
  empty_dirs?: EmptyDirMountSpec[];
77
106
  configs?: ConfigMountSpec[];
78
107
  }
@@ -212,6 +241,65 @@ export interface ServiceSpec {
212
241
  container?: ContainerSpec | null;
213
242
  external?: ExternalServiceSpec | null;
214
243
  }
244
+ export interface TemplateEnvironmentVariable {
245
+ name: string;
246
+ value?: string | null;
247
+ token?: Record<string, unknown> | null;
248
+ }
249
+ export interface ServiceTemplateContainerMountSpec {
250
+ room?: RoomStorageMountSpec[] | null;
251
+ project?: ProjectStorageMountSpec[] | null;
252
+ images?: ImageStorageMountSpec[] | null;
253
+ files?: FileStorageMountSpec[] | null;
254
+ empty_dirs?: EmptyDirMountSpec[] | null;
255
+ configs?: ConfigMountSpec[] | null;
256
+ }
257
+ export interface ContainerTemplateSpec {
258
+ private?: boolean | null;
259
+ command?: string | null;
260
+ working_dir?: string | null;
261
+ image?: string | null;
262
+ environment?: TemplateEnvironmentVariable[] | null;
263
+ storage?: ServiceTemplateContainerMountSpec | null;
264
+ on_demand?: boolean | null;
265
+ writable_root_fs?: boolean | null;
266
+ }
267
+ export interface ExternalServiceTemplateSpec {
268
+ url: string;
269
+ }
270
+ export interface ServiceTemplateVariable {
271
+ name: string;
272
+ label?: string | null;
273
+ description?: string | null;
274
+ default?: string | null;
275
+ required?: boolean | null;
276
+ }
277
+ export declare function normalizeServiceSpec(service: ServiceSpec | Record<string, unknown>): ServiceSpec;
278
+ export declare class ServiceTemplateSpec {
279
+ readonly version: string;
280
+ readonly kind: string;
281
+ readonly variables?: ServiceTemplateVariable[] | null;
282
+ readonly metadata: ServiceMetadata;
283
+ readonly ports: PortSpec[];
284
+ readonly container?: ContainerTemplateSpec | null;
285
+ readonly external?: ExternalServiceTemplateSpec | null;
286
+ readonly agents: Record<string, unknown>[];
287
+ constructor({ version, kind, variables, metadata, ports, container, external, agents, }: {
288
+ version?: string;
289
+ kind?: string;
290
+ variables?: ServiceTemplateVariable[] | null;
291
+ metadata: ServiceMetadata;
292
+ ports?: PortSpec[];
293
+ container?: ContainerTemplateSpec | null;
294
+ external?: ExternalServiceTemplateSpec | null;
295
+ agents?: Record<string, unknown>[];
296
+ });
297
+ static fromJson(json: Record<string, unknown>): ServiceTemplateSpec;
298
+ toJson(): Record<string, unknown>;
299
+ toServiceSpec({ values }?: {
300
+ values?: Record<string, string>;
301
+ }): ServiceSpec;
302
+ }
215
303
  export interface RouteMetadata {
216
304
  name: string;
217
305
  annotations?: Record<string, string>;
@@ -370,6 +458,19 @@ export interface ExternalOAuthClientRegistration {
370
458
  clientId: string;
371
459
  clientSecret?: string | null;
372
460
  }
461
+ export interface ManagedAgent {
462
+ id: string;
463
+ name: string;
464
+ configuration: Record<string, unknown>;
465
+ }
466
+ export declare class ManagedAgentGrant {
467
+ readonly admin: boolean;
468
+ constructor({ admin }?: {
469
+ admin?: boolean;
470
+ });
471
+ static fromJson(json: Record<string, unknown>): ManagedAgentGrant;
472
+ toJson(): Record<string, unknown>;
473
+ }
373
474
  type JsonRequest = Record<string, unknown> | Array<unknown> | string | number | boolean | null;
374
475
  export declare class Meshagent {
375
476
  private readonly baseUrl;
@@ -382,6 +483,7 @@ export declare class Meshagent {
382
483
  private request;
383
484
  private parseRoomShare;
384
485
  private parseRoomSession;
486
+ private parseManagedAgent;
385
487
  private parseRoom;
386
488
  private parseRoute;
387
489
  private parseFeed;
@@ -425,6 +527,13 @@ export declare class Meshagent {
425
527
  isAdmin?: boolean;
426
528
  isDeveloper?: boolean;
427
529
  canCreateRooms?: boolean;
530
+ inviteRedirectUrl?: string;
531
+ }): Promise<Record<string, unknown>>;
532
+ addUserToProjectByEmail(projectId: string, email: string, options?: {
533
+ isAdmin?: boolean;
534
+ isDeveloper?: boolean;
535
+ canCreateRooms?: boolean;
536
+ inviteRedirectUrl?: string;
428
537
  }): Promise<Record<string, unknown>>;
429
538
  removeUserFromProject(projectId: string, userId: string): Promise<Record<string, unknown>>;
430
539
  updateProjectSettings(projectId: string, settings: Record<string, unknown>): Promise<Record<string, unknown>>;
@@ -439,6 +548,12 @@ export declare class Meshagent {
439
548
  listProjects(): Promise<Record<string, unknown>>;
440
549
  getProject(projectId: string): Promise<Record<string, unknown>>;
441
550
  getProjectByKey(projectKey: string): Promise<Record<string, unknown>>;
551
+ createAgent(params: {
552
+ projectId: string;
553
+ configuration: Record<string, unknown>;
554
+ ifNotExists?: boolean;
555
+ permissions?: Record<string, ManagedAgentGrant> | null;
556
+ }): Promise<ManagedAgent>;
442
557
  createApiKey(projectId: string, name: string, description: string): Promise<Record<string, unknown>>;
443
558
  deleteApiKey(projectId: string, id: string): Promise<void>;
444
559
  listApiKeys(projectId: string): Promise<Record<string, unknown>>;
@@ -780,6 +895,7 @@ export declare class Meshagent {
780
895
  roomId: string;
781
896
  email: string;
782
897
  permissions: ApiScope;
898
+ inviteRedirectUrl?: string;
783
899
  }): Promise<void>;
784
900
  updateRoomGrant(params: {
785
901
  projectId: string;
@@ -1,7 +1,254 @@
1
1
  import { meshagentBaseUrl } from "./helpers.js";
2
- import { RoomException } from "./requirement.js";
2
+ import { ForbiddenException, RoomException } from "./requirement.js";
3
3
  import { ApiScope } from "./participant-token.js";
4
4
  import { decoder, encoder } from "./utils.js";
5
+ export class RoomSession {
6
+ constructor({ id, roomId, roomName, createdAt, isActive, participants, kind = "room", agentId, agentName, }) {
7
+ this.id = id;
8
+ this.roomId = roomId;
9
+ this.roomName = roomName;
10
+ this.createdAt = createdAt;
11
+ this.isActive = isActive;
12
+ this.participants = participants;
13
+ this.kind = kind;
14
+ this.agentId = agentId;
15
+ this.agentName = agentName;
16
+ }
17
+ toJson() {
18
+ return {
19
+ id: this.id,
20
+ room_id: this.roomId ?? null,
21
+ room_name: this.roomName,
22
+ started_at: this.createdAt.toISOString(),
23
+ is_active: this.isActive,
24
+ kind: this.kind,
25
+ ...(this.agentId != null ? { agent_id: this.agentId } : {}),
26
+ ...(this.agentName != null ? { agent_name: this.agentName } : {}),
27
+ };
28
+ }
29
+ }
30
+ function cloneJsonValue(value) {
31
+ if (Array.isArray(value)) {
32
+ return value.map((item) => cloneJsonValue(item));
33
+ }
34
+ if (value != null && typeof value === "object") {
35
+ const result = {};
36
+ for (const [key, item] of Object.entries(value)) {
37
+ result[key] = cloneJsonValue(item);
38
+ }
39
+ return result;
40
+ }
41
+ return value;
42
+ }
43
+ function formatTemplateString(value, values) {
44
+ return value.replace(/\{([A-Za-z_][A-Za-z0-9_]*)\}/g, (token, key) => values[key] ?? token);
45
+ }
46
+ function formatJsonValue(value, values) {
47
+ if (typeof value === "string") {
48
+ return formatTemplateString(value, values);
49
+ }
50
+ if (Array.isArray(value)) {
51
+ return value.map((item) => formatJsonValue(item, values));
52
+ }
53
+ if (value != null && typeof value === "object") {
54
+ const result = {};
55
+ for (const [key, item] of Object.entries(value)) {
56
+ result[key] = formatJsonValue(item, values);
57
+ }
58
+ return result;
59
+ }
60
+ return value;
61
+ }
62
+ function objectOrUndefined(value) {
63
+ return value != null && typeof value === "object" && !Array.isArray(value)
64
+ ? value
65
+ : undefined;
66
+ }
67
+ function objectArray(value) {
68
+ return Array.isArray(value)
69
+ ? value.filter((item) => objectOrUndefined(item) !== undefined)
70
+ : undefined;
71
+ }
72
+ function stringValue(value) {
73
+ return typeof value === "string" ? value : undefined;
74
+ }
75
+ function booleanValue(value) {
76
+ return typeof value === "boolean" ? value : undefined;
77
+ }
78
+ function normalizeRoomMount(value) {
79
+ return {
80
+ path: stringValue(value.path) ?? "",
81
+ ...(stringValue(value.subpath) !== undefined ? { subpath: stringValue(value.subpath) } : {}),
82
+ ...(booleanValue(value.read_only) !== undefined ? { read_only: booleanValue(value.read_only) } : {}),
83
+ };
84
+ }
85
+ function normalizeProjectMount(value) {
86
+ return {
87
+ path: stringValue(value.path) ?? "",
88
+ ...(stringValue(value.subpath) !== undefined ? { subpath: stringValue(value.subpath) } : {}),
89
+ read_only: booleanValue(value.read_only) ?? true,
90
+ };
91
+ }
92
+ function normalizeImageMount(value) {
93
+ return {
94
+ path: stringValue(value.path) ?? "",
95
+ ...(stringValue(value.subpath) !== undefined ? { subpath: stringValue(value.subpath) } : {}),
96
+ read_only: booleanValue(value.read_only) ?? true,
97
+ image: stringValue(value.image) ?? "",
98
+ };
99
+ }
100
+ function normalizeFileMount(value) {
101
+ return {
102
+ path: stringValue(value.path) ?? "",
103
+ ...(stringValue(value.subpath) !== undefined ? { subpath: stringValue(value.subpath) } : {}),
104
+ read_only: booleanValue(value.read_only) ?? true,
105
+ text: stringValue(value.text) ?? "",
106
+ };
107
+ }
108
+ function normalizeEmptyDirMount(value) {
109
+ return {
110
+ path: stringValue(value.path) ?? "",
111
+ read_only: booleanValue(value.read_only) ?? false,
112
+ };
113
+ }
114
+ function normalizeConfigMount(value) {
115
+ return {
116
+ path: stringValue(value.path) ?? "/var/run/meshagent",
117
+ };
118
+ }
119
+ function normalizeContainerMountSpec(value) {
120
+ const source = objectOrUndefined(value) ?? {};
121
+ const room = objectArray(source.room)?.map(normalizeRoomMount);
122
+ const project = objectArray(source.project)?.map(normalizeProjectMount);
123
+ const images = objectArray(source.images)?.map(normalizeImageMount);
124
+ const files = objectArray(source.files)?.map(normalizeFileMount);
125
+ const emptyDirs = objectArray(source.empty_dirs)?.map(normalizeEmptyDirMount);
126
+ const configs = objectArray(source.configs)?.map(normalizeConfigMount);
127
+ return {
128
+ ...(room !== undefined ? { room } : {}),
129
+ ...(project !== undefined ? { project } : {}),
130
+ ...(images !== undefined ? { images } : {}),
131
+ ...(files !== undefined ? { files } : {}),
132
+ ...(emptyDirs !== undefined ? { empty_dirs: emptyDirs } : {}),
133
+ ...(configs !== undefined ? { configs } : {}),
134
+ };
135
+ }
136
+ function normalizeAgentSpec(agent, values) {
137
+ const formatted = formatJsonValue(agent, values);
138
+ const spec = cloneJsonValue(formatted);
139
+ if (spec.email != null && spec.email.public == null) {
140
+ spec.email = { ...spec.email, public: false };
141
+ }
142
+ if (spec.channels?.email) {
143
+ spec.channels = {
144
+ ...spec.channels,
145
+ email: spec.channels.email.map((channel) => ({
146
+ ...channel,
147
+ private: channel.private ?? false,
148
+ })),
149
+ };
150
+ }
151
+ if (spec.channels?.messaging) {
152
+ spec.channels = {
153
+ ...spec.channels,
154
+ messaging: spec.channels.messaging.map((channel) => ({
155
+ ...channel,
156
+ protocol: channel.protocol ?? "meshagent.agent-message.v1",
157
+ })),
158
+ };
159
+ }
160
+ return spec;
161
+ }
162
+ export function normalizeServiceSpec(service) {
163
+ const normalized = cloneJsonValue(service);
164
+ if (normalized.container?.storage != null) {
165
+ normalized.container = {
166
+ ...normalized.container,
167
+ storage: normalizeContainerMountSpec(normalized.container.storage),
168
+ };
169
+ }
170
+ return normalized;
171
+ }
172
+ export class ServiceTemplateSpec {
173
+ constructor({ version = "v1", kind = "ServiceTemplate", variables, metadata, ports = [], container, external, agents = [], }) {
174
+ this.version = version;
175
+ this.kind = kind;
176
+ this.variables = variables;
177
+ this.metadata = metadata;
178
+ this.ports = ports;
179
+ this.container = container;
180
+ this.external = external;
181
+ this.agents = agents;
182
+ }
183
+ static fromJson(json) {
184
+ const metadata = objectOrUndefined(json.metadata);
185
+ if (metadata === undefined || typeof metadata.name !== "string") {
186
+ throw new RoomException("Invalid service template payload: missing metadata.name");
187
+ }
188
+ return new ServiceTemplateSpec({
189
+ version: stringValue(json.version) ?? "v1",
190
+ kind: stringValue(json.kind) ?? "ServiceTemplate",
191
+ variables: objectArray(json.variables),
192
+ metadata: cloneJsonValue(metadata),
193
+ ports: (objectArray(json.ports) ?? []),
194
+ container: objectOrUndefined(json.container),
195
+ external: objectOrUndefined(json.external),
196
+ agents: objectArray(json.agents) ?? [],
197
+ });
198
+ }
199
+ toJson() {
200
+ return {
201
+ version: this.version,
202
+ kind: this.kind,
203
+ ...(this.variables != null ? { variables: cloneJsonValue(this.variables) } : {}),
204
+ metadata: cloneJsonValue(this.metadata),
205
+ ...(this.ports.length > 0 ? { ports: cloneJsonValue(this.ports) } : {}),
206
+ ...(this.container != null ? { container: cloneJsonValue(this.container) } : {}),
207
+ ...(this.external != null ? { external: cloneJsonValue(this.external) } : {}),
208
+ ...(this.agents.length > 0 ? { agents: cloneJsonValue(this.agents) } : {}),
209
+ };
210
+ }
211
+ toServiceSpec({ values = {} } = {}) {
212
+ const service = {
213
+ version: "v1",
214
+ kind: "Service",
215
+ metadata: cloneJsonValue(this.metadata),
216
+ agents: this.agents.map((agent) => normalizeAgentSpec(agent, values)),
217
+ ports: cloneJsonValue(this.ports),
218
+ };
219
+ if (this.container != null) {
220
+ const formattedContainer = formatJsonValue(this.container, values);
221
+ const image = stringValue(formattedContainer.image);
222
+ if (image === undefined || image.length === 0) {
223
+ throw new RoomException("ServiceTemplateSpec.image is required to build a ServiceSpec");
224
+ }
225
+ service.container = {
226
+ ...(booleanValue(formattedContainer.private) !== undefined ? { private: booleanValue(formattedContainer.private) } : {}),
227
+ ...(stringValue(formattedContainer.command) !== undefined ? { command: stringValue(formattedContainer.command) } : {}),
228
+ ...(stringValue(formattedContainer.working_dir) !== undefined ? { working_dir: stringValue(formattedContainer.working_dir) } : {}),
229
+ image,
230
+ ...(Array.isArray(formattedContainer.environment)
231
+ ? { environment: formattedContainer.environment }
232
+ : {}),
233
+ ...(objectOrUndefined(formattedContainer.storage) !== undefined
234
+ ? { storage: normalizeContainerMountSpec(formattedContainer.storage) }
235
+ : {}),
236
+ ...(booleanValue(formattedContainer.on_demand) !== undefined ? { on_demand: booleanValue(formattedContainer.on_demand) } : {}),
237
+ ...(booleanValue(formattedContainer.writable_root_fs) !== undefined
238
+ ? { writable_root_fs: booleanValue(formattedContainer.writable_root_fs) }
239
+ : {}),
240
+ };
241
+ }
242
+ if (this.external != null) {
243
+ const formattedExternal = formatJsonValue(this.external, values);
244
+ const url = stringValue(formattedExternal.url);
245
+ if (url !== undefined) {
246
+ service.external = { url };
247
+ }
248
+ }
249
+ return normalizeServiceSpec(service);
250
+ }
251
+ }
5
252
  function pruneUndefinedValues(value) {
6
253
  if (Array.isArray(value)) {
7
254
  const prunedItems = value
@@ -24,6 +271,27 @@ function pruneUndefinedValues(value) {
24
271
  }
25
272
  return value;
26
273
  }
274
+ function pruneNullishValues(value) {
275
+ if (Array.isArray(value)) {
276
+ return value
277
+ .map((item) => pruneNullishValues(item))
278
+ .filter((item) => item !== undefined);
279
+ }
280
+ if (value === null || value === undefined) {
281
+ return undefined;
282
+ }
283
+ if (typeof value === "object") {
284
+ const result = {};
285
+ for (const [key, entryValue] of Object.entries(value)) {
286
+ const normalized = pruneNullishValues(entryValue);
287
+ if (normalized !== undefined) {
288
+ result[key] = normalized;
289
+ }
290
+ }
291
+ return result;
292
+ }
293
+ return value;
294
+ }
27
295
  function serializeServiceSpec(service) {
28
296
  const agents = service.agents?.map((agent) => ({
29
297
  ...agent,
@@ -47,6 +315,17 @@ function serializeCreateServiceSpec(service) {
47
315
  delete payload.id;
48
316
  return payload;
49
317
  }
318
+ export class ManagedAgentGrant {
319
+ constructor({ admin = false } = {}) {
320
+ this.admin = admin;
321
+ }
322
+ static fromJson(json) {
323
+ return new ManagedAgentGrant({ admin: json["admin"] === true });
324
+ }
325
+ toJson() {
326
+ return { admin: this.admin };
327
+ }
328
+ }
50
329
  const globalScope = globalThis;
51
330
  function bytesToBase64(bytes) {
52
331
  if (globalScope.Buffer) {
@@ -149,7 +428,11 @@ export class Meshagent {
149
428
  catch {
150
429
  message = "<unable to read body>";
151
430
  }
152
- throw new RoomException(`Failed to ${action}. Status code: ${response.status}, body: ${message}`);
431
+ const errorMessage = `Failed to ${action}. Status code: ${response.status}, body: ${message}`;
432
+ if (response.status === 403) {
433
+ throw new ForbiddenException(errorMessage);
434
+ }
435
+ throw new RoomException(errorMessage);
153
436
  }
154
437
  switch (responseType) {
155
438
  case "json":
@@ -188,7 +471,7 @@ export class Meshagent {
188
471
  if (!data || typeof data !== "object") {
189
472
  throw new RoomException("Invalid room session payload");
190
473
  }
191
- const { id, room_id: roomIdRaw, roomId, room_name: roomNameRaw, roomName, created_at: createdRaw, createdAt, is_active: isActiveRaw, isActive, participants } = data;
474
+ 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;
192
475
  if (typeof id !== "string") {
193
476
  throw new RoomException("Invalid room session payload: missing id");
194
477
  }
@@ -204,13 +487,32 @@ export class Meshagent {
204
487
  if (typeof isActiveValue !== "boolean") {
205
488
  throw new RoomException("Invalid room session payload: missing is_active");
206
489
  }
207
- return {
490
+ return new RoomSession({
208
491
  id,
209
492
  roomId: typeof roomId === "string" ? roomId : typeof roomIdRaw === "string" ? roomIdRaw : undefined,
210
493
  roomName: roomNameValue,
211
494
  createdAt: new Date(created),
212
495
  isActive: isActiveValue,
213
496
  participants: participants && typeof participants === "object" ? participants : undefined,
497
+ kind: typeof kind === "string" ? kind : "room",
498
+ agentId: typeof agentId === "string" ? agentId : typeof agentIdRaw === "string" ? agentIdRaw : undefined,
499
+ agentName: typeof agentName === "string" ? agentName : typeof agentNameRaw === "string" ? agentNameRaw : undefined,
500
+ });
501
+ }
502
+ parseManagedAgent(data) {
503
+ if (!data || typeof data !== "object") {
504
+ throw new RoomException("Invalid managed agent payload");
505
+ }
506
+ const { id, name, configuration } = data;
507
+ if (typeof id !== "string" || typeof name !== "string") {
508
+ throw new RoomException("Invalid managed agent payload: missing id or name");
509
+ }
510
+ return {
511
+ id,
512
+ name,
513
+ configuration: configuration && typeof configuration === "object" && !Array.isArray(configuration)
514
+ ? configuration
515
+ : {},
214
516
  };
215
517
  }
216
518
  parseRoom(data) {
@@ -776,7 +1078,7 @@ export class Meshagent {
776
1078
  });
777
1079
  }
778
1080
  async addUserToProject(projectId, userId, options = {}) {
779
- const { isAdmin, isDeveloper, canCreateRooms } = options;
1081
+ const { isAdmin, isDeveloper, canCreateRooms, inviteRedirectUrl } = options;
780
1082
  return await this.request(`/accounts/projects/${projectId}/users`, {
781
1083
  method: "POST",
782
1084
  json: {
@@ -787,6 +1089,28 @@ export class Meshagent {
787
1089
  ...(canCreateRooms !== undefined
788
1090
  ? { can_create_rooms: canCreateRooms }
789
1091
  : {}),
1092
+ ...(inviteRedirectUrl !== undefined
1093
+ ? { invite_redirect_url: inviteRedirectUrl }
1094
+ : {}),
1095
+ },
1096
+ action: "add user to project",
1097
+ });
1098
+ }
1099
+ async addUserToProjectByEmail(projectId, email, options = {}) {
1100
+ const { isAdmin, isDeveloper, canCreateRooms, inviteRedirectUrl } = options;
1101
+ return await this.request(`/accounts/projects/${projectId}/users`, {
1102
+ method: "POST",
1103
+ json: {
1104
+ project_id: projectId,
1105
+ email,
1106
+ ...(isAdmin !== undefined ? { is_admin: isAdmin } : {}),
1107
+ ...(isDeveloper !== undefined ? { is_developer: isDeveloper } : {}),
1108
+ ...(canCreateRooms !== undefined
1109
+ ? { can_create_rooms: canCreateRooms }
1110
+ : {}),
1111
+ ...(inviteRedirectUrl !== undefined
1112
+ ? { invite_redirect_url: inviteRedirectUrl }
1113
+ : {}),
790
1114
  },
791
1115
  action: "add user to project",
792
1116
  });
@@ -844,6 +1168,22 @@ export class Meshagent {
844
1168
  action: "get project by key",
845
1169
  });
846
1170
  }
1171
+ async createAgent(params) {
1172
+ const { projectId, configuration, ifNotExists = false, permissions } = params;
1173
+ const permissionsJson = permissions == null
1174
+ ? undefined
1175
+ : Object.fromEntries(Object.entries(permissions).map(([userId, grant]) => [userId, grant.toJson()]));
1176
+ const data = await this.request(`/accounts/projects/${this.encodePathComponent(projectId)}/agents`, {
1177
+ method: "POST",
1178
+ json: {
1179
+ configuration: pruneNullishValues(configuration),
1180
+ if_not_exists: ifNotExists,
1181
+ ...(permissionsJson !== undefined ? { permissions: permissionsJson } : {}),
1182
+ },
1183
+ action: "create agent",
1184
+ });
1185
+ return this.parseManagedAgent(data);
1186
+ }
847
1187
  async createApiKey(projectId, name, description) {
848
1188
  return await this.request(`/accounts/projects/${projectId}/api-keys`, {
849
1189
  method: "POST",
@@ -1335,14 +1675,14 @@ export class Meshagent {
1335
1675
  const data = await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/services/${serviceId}`, {
1336
1676
  action: "fetch room service",
1337
1677
  });
1338
- return data;
1678
+ return normalizeServiceSpec(data);
1339
1679
  }
1340
1680
  async listRoomServices(projectId, roomName) {
1341
1681
  const data = await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/services`, {
1342
1682
  action: "list room services",
1343
1683
  });
1344
1684
  const services = Array.isArray(data?.services) ? data.services : [];
1345
- return services;
1685
+ return services.map((service) => normalizeServiceSpec(service));
1346
1686
  }
1347
1687
  async deleteRoomService(projectId, roomName, serviceId) {
1348
1688
  await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/services/${serviceId}`, {
@@ -1366,14 +1706,14 @@ export class Meshagent {
1366
1706
  const data = await this.request(`/accounts/projects/${projectId}/services/${serviceId}`, {
1367
1707
  action: "fetch service",
1368
1708
  });
1369
- return data;
1709
+ return normalizeServiceSpec(data);
1370
1710
  }
1371
1711
  async listServices(projectId) {
1372
1712
  const data = await this.request(`/accounts/projects/${projectId}/services`, {
1373
1713
  action: "list services",
1374
1714
  });
1375
1715
  const services = Array.isArray(data?.services) ? data.services : [];
1376
- return services;
1716
+ return services.map((service) => normalizeServiceSpec(service));
1377
1717
  }
1378
1718
  async deleteService(projectId, serviceId) {
1379
1719
  await this.request(`/accounts/projects/${projectId}/services/${serviceId}`, {
@@ -1712,13 +2052,16 @@ export class Meshagent {
1712
2052
  });
1713
2053
  }
1714
2054
  async createRoomGrantByEmail(params) {
1715
- const { projectId, roomId, email, permissions } = params;
2055
+ const { projectId, roomId, email, permissions, inviteRedirectUrl } = params;
1716
2056
  await this.request(`/accounts/projects/${projectId}/room-grants`, {
1717
2057
  method: "POST",
1718
2058
  json: {
1719
2059
  room_id: roomId,
1720
2060
  email,
1721
2061
  permissions: permissions.toJSON(),
2062
+ ...(inviteRedirectUrl !== undefined
2063
+ ? { invite_redirect_url: inviteRedirectUrl }
2064
+ : {}),
1722
2065
  },
1723
2066
  action: "create room grant",
1724
2067
  responseType: "void",
@@ -57,7 +57,7 @@ export class MessagingClient extends EventEmitter {
57
57
  return input;
58
58
  }
59
59
  async _invoke({ operation, input, }) {
60
- await this.client.invoke({
60
+ await this.client.invokeContent({
61
61
  toolkit: "messaging",
62
62
  tool: operation,
63
63
  input: new JsonContent({ json: input }),
@@ -14,7 +14,7 @@ export class QueuesClient {
14
14
  return new RoomServerException(`unexpected return type from queues.${operation}`);
15
15
  }
16
16
  async _invoke(operation, arguments_) {
17
- return await this.client.invoke({
17
+ return await this.client.invokeContent({
18
18
  toolkit: "queues",
19
19
  tool: operation,
20
20
  arguments: arguments_,