@meshagent/meshagent 0.47.1 → 0.49.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/browser/containers-client.d.ts +1 -0
  3. package/dist/browser/containers-client.js +34 -0
  4. package/dist/browser/entrypoint.d.ts +1 -0
  5. package/dist/browser/entrypoint.js +3 -3
  6. package/dist/browser/index.d.ts +1 -0
  7. package/dist/browser/index.js +1 -0
  8. package/dist/browser/meshagent-client.d.ts +37 -5
  9. package/dist/browser/meshagent-client.js +25 -7
  10. package/dist/browser/messaging-client.js +9 -2
  11. package/dist/browser/mounts-client.d.ts +21 -0
  12. package/dist/browser/mounts-client.js +82 -0
  13. package/dist/browser/room-client.d.ts +4 -0
  14. package/dist/browser/room-client.js +13 -3
  15. package/dist/esm/containers-client.d.ts +1 -0
  16. package/dist/esm/containers-client.js +34 -0
  17. package/dist/esm/entrypoint.d.ts +1 -0
  18. package/dist/esm/entrypoint.js +3 -3
  19. package/dist/esm/index.d.ts +1 -0
  20. package/dist/esm/index.js +1 -0
  21. package/dist/esm/meshagent-client.d.ts +37 -5
  22. package/dist/esm/meshagent-client.js +25 -7
  23. package/dist/esm/messaging-client.js +9 -2
  24. package/dist/esm/mounts-client.d.ts +21 -0
  25. package/dist/esm/mounts-client.js +78 -0
  26. package/dist/esm/room-client.d.ts +4 -0
  27. package/dist/esm/room-client.js +13 -3
  28. package/dist/node/containers-client.d.ts +1 -0
  29. package/dist/node/containers-client.js +34 -0
  30. package/dist/node/entrypoint.d.ts +1 -0
  31. package/dist/node/entrypoint.js +3 -3
  32. package/dist/node/index.d.ts +1 -0
  33. package/dist/node/index.js +1 -0
  34. package/dist/node/meshagent-client.d.ts +37 -5
  35. package/dist/node/meshagent-client.js +25 -7
  36. package/dist/node/messaging-client.js +9 -2
  37. package/dist/node/mounts-client.d.ts +21 -0
  38. package/dist/node/mounts-client.js +82 -0
  39. package/dist/node/room-client.d.ts +4 -0
  40. package/dist/node/room-client.js +13 -3
  41. package/package.json +1 -1
@@ -1,7 +1,8 @@
1
1
  import { ApiScope } from "./participant-token.js";
2
2
  export type ProjectRole = "member" | "admin" | "developer" | "room_creator" | "room_inventory" | "room_manager" | "session_inventory" | "agent_creator" | "agent_inventory" | "agent_manager" | "repository_creator" | "repository_inventory" | "repository_manager" | "feed_creator" | "feed_inventory" | "feed_manager" | "oauth_client_creator" | "oauth_client_inventory" | "oauth_client_manager" | "api_key_creator" | "api_key_inventory" | "api_key_manager" | "service_creator" | "service_inventory" | "service_manager" | "service_account_creator" | "service_account_inventory" | "service_account_manager" | "participant_token_creator" | "mailbox_creator" | "mailbox_inventory" | "mailbox_manager" | "route_creator" | "route_inventory" | "route_manager" | "scheduled_task_creator" | "scheduled_task_inventory" | "scheduled_task_manager" | "feed_subscription_creator" | "feed_subscription_inventory" | "feed_subscription_manager" | "llm_logger_creator" | "llm_logger_inventory" | "llm_logger_manager" | "llm_proxy_user" | "usage_reporter" | "billing_manager" | "group_manager";
3
3
  export type ResourceRole = "viewer" | "operator" | "developer" | "admin";
4
- export type RoomRole = "site_user" | ResourceRole;
4
+ export type RoomRole = "site_user" | "guest" | ResourceRole;
5
+ export type ProjectSettingsDocumentName = "openai" | "anthropic" | "otel" | "admission" | "room" | "room_roles";
5
6
  export type FeedRole = "reader" | "subscriber" | "publisher" | "manager";
6
7
  export type SecretRole = "use_proxy";
7
8
  export type AccessRole = ProjectRole | RoomRole | FeedRole | SecretRole | "list";
@@ -235,6 +236,12 @@ export interface RoomStorageMountSpec {
235
236
  subpath?: string | null;
236
237
  read_only?: boolean;
237
238
  }
239
+ export interface VolumeStorageMountSpec {
240
+ name: string;
241
+ path: string;
242
+ subpath?: string | null;
243
+ read_only?: boolean;
244
+ }
238
245
  export interface EmptyDirMountSpec {
239
246
  path: string;
240
247
  read_only?: boolean;
@@ -249,6 +256,7 @@ export interface FileMountSpec {
249
256
  }
250
257
  export interface ContainerMountSpec {
251
258
  room?: RoomStorageMountSpec[];
259
+ volumes?: VolumeStorageMountSpec[];
252
260
  empty_dirs?: EmptyDirMountSpec[];
253
261
  configs?: ConfigMountSpec[];
254
262
  files?: FileMountSpec[];
@@ -418,12 +426,33 @@ export interface RouteBackend {
418
426
  room?: RouteBackendTarget | null;
419
427
  agent?: RouteBackendTarget | null;
420
428
  }
421
- export interface RoutePathSpec {
429
+ export interface RouteCorsRule {
430
+ allowedOrigins: string[];
431
+ allowedMethods?: string[];
432
+ allowedHeaders?: string[];
433
+ exposeHeaders?: string[];
434
+ maxAgeSeconds?: number;
435
+ allowCredentials?: boolean;
436
+ }
437
+ export interface RouteContentSpec {
438
+ subpath?: string;
439
+ cors?: RouteCorsRule[];
440
+ index?: boolean;
441
+ iap?: boolean;
442
+ compression?: "brotli" | "gzip" | "none";
443
+ }
444
+ interface RoutePathBase {
422
445
  path?: string;
423
446
  pathType?: "prefix" | "exact";
424
447
  stripPrefix?: boolean;
425
- targetPort: string | number;
426
448
  }
449
+ export type RoutePathSpec = RoutePathBase & ({
450
+ targetPort: string | number;
451
+ targetContent?: never;
452
+ } | {
453
+ targetContent: RouteContentSpec;
454
+ targetPort?: never;
455
+ });
427
456
  export interface RouteSpec {
428
457
  version: "v1";
429
458
  kind: "Route";
@@ -577,14 +606,17 @@ export declare class Meshagent {
577
606
  projectId: string;
578
607
  path: string;
579
608
  }): Promise<Uint8Array>;
580
- createProject(name: string, settings?: Record<string, unknown>): Promise<Record<string, unknown>>;
609
+ createProject(name: string): Promise<Record<string, unknown>>;
581
610
  addUserToProject(projectId: string, userId: string, options?: {
582
611
  roles?: ProjectRole[];
583
612
  email?: string;
584
613
  inviteRedirectUrl?: string;
585
614
  }): Promise<Record<string, unknown>>;
586
615
  removeUserFromProject(projectId: string, userId: string): Promise<Record<string, unknown>>;
587
- updateProjectSettings(projectId: string, settings: Record<string, unknown>): Promise<Record<string, unknown>>;
616
+ private projectSettingsDocumentPath;
617
+ getProjectSettingsDocument(projectId: string, name: ProjectSettingsDocumentName): Promise<Record<string, unknown> | undefined>;
618
+ setProjectSettingsDocument(projectId: string, name: ProjectSettingsDocumentName, document: Record<string, unknown>): Promise<Record<string, unknown>>;
619
+ deleteProjectSettingsDocument(projectId: string, name: ProjectSettingsDocumentName): Promise<Record<string, unknown>>;
588
620
  updateUserInProject(projectId: string, userId: string, roles: ProjectRole[]): Promise<Record<string, unknown>>;
589
621
  getUsersInProjectPage(projectId: string, options?: {
590
622
  pageSize?: number;
@@ -245,7 +245,7 @@ export class Meshagent {
245
245
  return url.toString();
246
246
  }
247
247
  async request(path, options) {
248
- const { method = "GET", query, json, body, headers, action, responseType = "json" } = options;
248
+ const { method = "GET", query, json, body, headers, action, responseType = "json", returnUndefinedOnNotFound = false } = options;
249
249
  const url = this.buildUrl(path, query);
250
250
  const finalHeaders = {};
251
251
  if (this.token) {
@@ -274,6 +274,9 @@ export class Meshagent {
274
274
  headers: finalHeaders,
275
275
  body: toFetchBody(requestBody),
276
276
  });
277
+ if (response.status === 404 && returnUndefinedOnNotFound) {
278
+ return undefined;
279
+ }
277
280
  if (!response.ok) {
278
281
  let message;
279
282
  try {
@@ -862,10 +865,10 @@ export class Meshagent {
862
865
  responseType: "arrayBuffer",
863
866
  });
864
867
  }
865
- async createProject(name, settings) {
868
+ async createProject(name) {
866
869
  return await this.request(`/accounts/projects`, {
867
870
  method: "POST",
868
- json: { name, settings },
871
+ json: { name },
869
872
  action: "create project",
870
873
  });
871
874
  }
@@ -889,11 +892,26 @@ export class Meshagent {
889
892
  action: "remove user from project",
890
893
  });
891
894
  }
892
- async updateProjectSettings(projectId, settings) {
893
- return await this.request(`/accounts/projects/${projectId}/settings`, {
895
+ projectSettingsDocumentPath(name) {
896
+ return name === "room_roles" ? "room-roles" : name;
897
+ }
898
+ async getProjectSettingsDocument(projectId, name) {
899
+ return await this.request(`/accounts/projects/${projectId}/settings/${this.projectSettingsDocumentPath(name)}`, {
900
+ action: `get ${name} project settings`,
901
+ returnUndefinedOnNotFound: true,
902
+ });
903
+ }
904
+ async setProjectSettingsDocument(projectId, name, document) {
905
+ return await this.request(`/accounts/projects/${projectId}/settings/${this.projectSettingsDocumentPath(name)}`, {
894
906
  method: "PUT",
895
- json: settings,
896
- action: "update project settings",
907
+ json: document,
908
+ action: `set ${name} project settings`,
909
+ });
910
+ }
911
+ async deleteProjectSettingsDocument(projectId, name) {
912
+ return await this.request(`/accounts/projects/${projectId}/settings/${this.projectSettingsDocumentPath(name)}`, {
913
+ method: "DELETE",
914
+ action: `delete ${name} project settings`,
897
915
  });
898
916
  }
899
917
  async updateUserInProject(projectId, userId, roles) {
@@ -689,8 +689,15 @@ export class MessagingClient extends EventEmitter {
689
689
  break;
690
690
  }
691
691
  const event = new RoomMessageEvent({ message });
692
- this.client.emit(event);
693
- this.emit("message", event);
692
+ try {
693
+ this.client.emit(event);
694
+ this.emit("message", event);
695
+ }
696
+ finally {
697
+ if (message.type === "dismiss") {
698
+ this.client._dismiss();
699
+ }
700
+ }
694
701
  }
695
702
  _onParticipantEnabled(message) {
696
703
  const data = message.message;
@@ -0,0 +1,21 @@
1
+ import type { RoomClient } from "./room-client.js";
2
+ export interface MountedVolumeConsumer {
3
+ kind: "room" | "container";
4
+ containerId?: string;
5
+ }
6
+ export interface MountedVolume {
7
+ id: string;
8
+ name: string;
9
+ required: boolean;
10
+ description: string;
11
+ metadata: Record<string, unknown>;
12
+ annotations: Record<string, string>;
13
+ storageClass: "standard" | "juice" | "zerofs";
14
+ maxSizeMb?: number;
15
+ consumers: MountedVolumeConsumer[];
16
+ }
17
+ export declare class MountsClient {
18
+ private readonly room;
19
+ constructor(room: RoomClient);
20
+ list(): Promise<MountedVolume[]>;
21
+ }
@@ -0,0 +1,78 @@
1
+ import { JsonContent } from "./response.js";
2
+ import { RoomServerException } from "./room-server-client.js";
3
+ function isRecord(value) {
4
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5
+ }
6
+ function parseMountedVolume(value) {
7
+ if (!isRecord(value)
8
+ || typeof value["id"] !== "string"
9
+ || typeof value["name"] !== "string"
10
+ || typeof value["required"] !== "boolean") {
11
+ throw new RoomServerException("unexpected return type from mounts.list");
12
+ }
13
+ const metadata = isRecord(value["metadata"]) ? value["metadata"] : {};
14
+ const rawAnnotations = isRecord(value["annotations"]) ? value["annotations"] : {};
15
+ const annotations = {};
16
+ for (const [key, item] of Object.entries(rawAnnotations)) {
17
+ if (typeof item === "string") {
18
+ annotations[key] = item;
19
+ }
20
+ }
21
+ const rawConsumers = value["consumers"] ?? [];
22
+ if (!Array.isArray(rawConsumers)) {
23
+ throw new RoomServerException("unexpected return type from mounts.list");
24
+ }
25
+ const consumers = rawConsumers.map((consumer) => {
26
+ if (!isRecord(consumer)
27
+ || (consumer["kind"] !== "room" && consumer["kind"] !== "container")
28
+ || (consumer["kind"] === "container" && typeof consumer["container_id"] !== "string")
29
+ || (consumer["kind"] === "room" && consumer["container_id"] !== undefined)) {
30
+ throw new RoomServerException("unexpected return type from mounts.list");
31
+ }
32
+ return {
33
+ kind: consumer["kind"],
34
+ containerId: typeof consumer["container_id"] === "string"
35
+ ? consumer["container_id"]
36
+ : undefined,
37
+ };
38
+ });
39
+ const storageClass = value["storage_class"] ?? "standard";
40
+ if (storageClass !== "standard" && storageClass !== "juice" && storageClass !== "zerofs") {
41
+ throw new RoomServerException("unexpected return type from mounts.list");
42
+ }
43
+ const maxSizeMb = value["max_size_mb"];
44
+ if (maxSizeMb !== undefined && (typeof maxSizeMb !== "number" || !Number.isInteger(maxSizeMb) || maxSizeMb <= 0)) {
45
+ throw new RoomServerException("unexpected return type from mounts.list");
46
+ }
47
+ return {
48
+ id: value["id"],
49
+ name: value["name"],
50
+ required: value["required"],
51
+ description: typeof value["description"] === "string" ? value["description"] : "",
52
+ metadata,
53
+ annotations,
54
+ storageClass,
55
+ maxSizeMb,
56
+ consumers,
57
+ };
58
+ }
59
+ export class MountsClient {
60
+ constructor(room) {
61
+ this.room = room;
62
+ }
63
+ async list() {
64
+ const response = await this.room.invokeContent({
65
+ toolkit: "mounts",
66
+ tool: "list",
67
+ input: {},
68
+ });
69
+ if (!(response instanceof JsonContent)) {
70
+ throw new RoomServerException("unexpected return type from mounts.list");
71
+ }
72
+ const volumes = response.json["volumes"];
73
+ if (!Array.isArray(volumes)) {
74
+ throw new RoomServerException("unexpected return type from mounts.list");
75
+ }
76
+ return volumes.map(parseMountedVolume);
77
+ }
78
+ }
@@ -4,6 +4,7 @@ import { DeveloperClient } from "./developer-client.js";
4
4
  import { type EventHandler, type EventName } from "./event-emitter.js";
5
5
  import { MessagingClient } from "./messaging-client.js";
6
6
  import { MemoryClient } from "./memory-client.js";
7
+ import { MountsClient } from "./mounts-client.js";
7
8
  import { LocalParticipant } from "./participant.js";
8
9
  import { Protocol, ProtocolCloseKind, type MessageHandler, type ProtocolFactory } from "./protocol.js";
9
10
  import { QueuesClient } from "./queues-client.js";
@@ -59,6 +60,7 @@ export declare class RoomClient {
59
60
  readonly containers: ContainersClient;
60
61
  readonly memory: MemoryClient;
61
62
  readonly services: ServicesClient;
63
+ readonly mounts: MountsClient;
62
64
  _protocolInstance: Protocol;
63
65
  _entered: boolean;
64
66
  _allowDisconnectedRequests: boolean;
@@ -76,6 +78,7 @@ export declare class RoomClient {
76
78
  private _localParticipantReady;
77
79
  private _connected;
78
80
  private _closing;
81
+ private _dismissed;
79
82
  private _localParticipant;
80
83
  private _lifecycleTask;
81
84
  private _terminalState;
@@ -167,6 +170,7 @@ export declare class RoomClient {
167
170
  private _retryProtocolConnection;
168
171
  private _reconnect;
169
172
  private _connectionLifecycle;
173
+ _dismiss(): void;
170
174
  dispose(): void;
171
175
  _sendProtocolNowait({ type, data, label, messageId, expectResponse, }: {
172
176
  type: string;
@@ -5,6 +5,7 @@ import { DeveloperClient } from "./developer-client.js";
5
5
  import { EventEmitter } from "./event-emitter.js";
6
6
  import { MessagingClient } from "./messaging-client.js";
7
7
  import { MemoryClient } from "./memory-client.js";
8
+ import { MountsClient } from "./mounts-client.js";
8
9
  import { LocalParticipant } from "./participant.js";
9
10
  import { ProtocolCloseException, ProtocolCloseKind, ProtocolHandshakeException, ProtocolReconnectUnsupportedException, WebSocketClientProtocol, } from "./protocol.js";
10
11
  import { QueuesClient } from "./queues-client.js";
@@ -220,6 +221,7 @@ export class RoomClient {
220
221
  this._localParticipantReady = new Completer();
221
222
  this._connected = false;
222
223
  this._closing = false;
224
+ this._dismissed = false;
223
225
  this._localParticipant = null;
224
226
  this._lifecycleTask = null;
225
227
  this._terminalState = null;
@@ -257,6 +259,7 @@ export class RoomClient {
257
259
  this.containers = new ContainersClient({ room: this });
258
260
  this.memory = new MemoryClient({ room: this });
259
261
  this.services = new ServicesClient({ room: this });
262
+ this.mounts = new MountsClient(this);
260
263
  }
261
264
  static withIAP({ url = "./.well-known/meshagent/room/connect", reconnectTimeout = null, } = {}) {
262
265
  return new RoomClient({
@@ -876,7 +879,7 @@ export class RoomClient {
876
879
  const deadline = this._reconnectTimeout == null ? null : Date.now() + this._reconnectTimeout;
877
880
  let firstAttempt = true;
878
881
  let retryCount = 0;
879
- while (!this._closing) {
882
+ while (!this._closing && !this._dismissed) {
880
883
  if (firstAttempt) {
881
884
  firstAttempt = false;
882
885
  if (this._reconnectTimeout == null) {
@@ -1007,7 +1010,7 @@ export class RoomClient {
1007
1010
  this._completeRoomClosed();
1008
1011
  return;
1009
1012
  }
1010
- if (closeKind !== ProtocolCloseKind.ERROR) {
1013
+ if (closeKind !== ProtocolCloseKind.ERROR || this._dismissed) {
1011
1014
  this._setTerminalState({ state });
1012
1015
  }
1013
1016
  this._markDisconnected({ reason: closeReason, kind: closeKind });
@@ -1019,7 +1022,7 @@ export class RoomClient {
1019
1022
  this.messaging._onRoomDisconnect({ reason: closeReason });
1020
1023
  await this._failPendingWork({ state });
1021
1024
  await this._closeProtocol(protocol);
1022
- if (closeKind === ProtocolCloseKind.ERROR) {
1025
+ if (closeKind === ProtocolCloseKind.ERROR && !this._dismissed) {
1023
1026
  if (this._reconnectTimeout === 0) {
1024
1027
  if (closeReason == null) {
1025
1028
  console.warn("room connection lost; automatic reconnect disabled");
@@ -1048,6 +1051,13 @@ export class RoomClient {
1048
1051
  return;
1049
1052
  }
1050
1053
  }
1054
+ _dismiss() {
1055
+ if (this._closing || this._dismissed) {
1056
+ return;
1057
+ }
1058
+ this._dismissed = true;
1059
+ this._protocolInstance.dispose();
1060
+ }
1051
1061
  dispose() {
1052
1062
  this._closing = true;
1053
1063
  this._markDisconnected({
@@ -72,6 +72,7 @@ export interface RoomContainer {
72
72
  state: string;
73
73
  private: boolean;
74
74
  serviceId?: string;
75
+ mounts?: ContainerMountSpec;
75
76
  stats?: RoomContainerStats;
76
77
  exitStatus?: ContainerExitStatus;
77
78
  }
@@ -9,6 +9,38 @@ const stream_controller_js_1 = require("./stream-controller.js");
9
9
  function isRecord(value) {
10
10
  return typeof value === "object" && value !== null && !Array.isArray(value);
11
11
  }
12
+ function parseContainerMountSpec(value) {
13
+ if (value === undefined || value === null) {
14
+ return undefined;
15
+ }
16
+ if (!isRecord(value)) {
17
+ throw new room_server_client_js_1.RoomServerException("unexpected return type from containers.list");
18
+ }
19
+ const readMounts = (field, validate) => {
20
+ const raw = value[field];
21
+ if (raw === undefined || raw === null) {
22
+ return undefined;
23
+ }
24
+ if (!Array.isArray(raw) || !raw.every((mount) => isRecord(mount) && validate(mount))) {
25
+ throw new room_server_client_js_1.RoomServerException("unexpected return type from containers.list");
26
+ }
27
+ return raw;
28
+ };
29
+ const optionalMountFieldsAreValid = (mount) => (mount["subpath"] === undefined || mount["subpath"] === null || typeof mount["subpath"] === "string")
30
+ && (mount["read_only"] === undefined || typeof mount["read_only"] === "boolean");
31
+ return {
32
+ room: readMounts("room", (mount) => typeof mount["path"] === "string" && optionalMountFieldsAreValid(mount)),
33
+ volumes: readMounts("volumes", (mount) => typeof mount["name"] === "string"
34
+ && typeof mount["path"] === "string"
35
+ && optionalMountFieldsAreValid(mount)),
36
+ empty_dirs: readMounts("empty_dirs", (mount) => typeof mount["path"] === "string"
37
+ && (mount["read_only"] === undefined || typeof mount["read_only"] === "boolean")),
38
+ configs: readMounts("configs", (mount) => mount["path"] === undefined || mount["path"] === null || typeof mount["path"] === "string"),
39
+ files: readMounts("files", (mount) => typeof mount["path"] === "string"
40
+ && (mount["read_only"] === undefined || typeof mount["read_only"] === "boolean")
41
+ && (mount["text"] === undefined || mount["text"] === null || typeof mount["text"] === "string")),
42
+ };
43
+ }
12
44
  function toStringMapList(values) {
13
45
  return Object.entries(values).map(([key, value]) => ({ key, value }));
14
46
  }
@@ -904,6 +936,7 @@ class ContainersClient {
904
936
  const imageIdRaw = entry["image_id"];
905
937
  const portsRaw = entry["ports"];
906
938
  const serviceIdRaw = entry["service_id"];
939
+ const mountsRaw = entry["mounts"];
907
940
  const statsRaw = entry["stats"];
908
941
  const exitStatusRaw = entry["exit_status"];
909
942
  if (!Array.isArray(portsRaw) ||
@@ -964,6 +997,7 @@ class ContainersClient {
964
997
  state,
965
998
  private: privateFlag,
966
999
  serviceId: typeof serviceIdRaw === "string" ? serviceIdRaw : undefined,
1000
+ mounts: parseContainerMountSpec(mountsRaw),
967
1001
  stats,
968
1002
  exitStatus,
969
1003
  });
@@ -16,6 +16,7 @@ export var ServerXmlDocument: {
16
16
  ignoreRemoteMapChanges: UndoManagerOptions;
17
17
  captureTimeout: UndoManagerOptions;
18
18
  afterTransactionHandler: (transaction: any) => void;
19
+ destroy(): void;
19
20
  addToScope(ytypes: Array<any | {
20
21
  gc: DocOpts;
21
22
  gcFilter: DocOpts;
@@ -3038,10 +3038,9 @@ var UndoManager = class extends ObservableV2 {
3038
3038
  this.emit("stack-item-updated", changeEvent);
3039
3039
  }
3040
3040
  };
3041
+ this.destroy = this.destroy.bind(this);
3041
3042
  this.doc.on("afterTransaction", this.afterTransactionHandler);
3042
- this.doc.on("destroy", () => {
3043
- this.destroy();
3044
- });
3043
+ this.doc.on("destroy", this.destroy);
3045
3044
  }
3046
3045
  addToScope(ytypes) {
3047
3046
  const tmpSet = new Set(this.scope);
@@ -3110,6 +3109,7 @@ var UndoManager = class extends ObservableV2 {
3110
3109
  destroy() {
3111
3110
  this.trackedOrigins.delete(this);
3112
3111
  this.doc.off("afterTransaction", this.afterTransactionHandler);
3112
+ this.doc.off("destroy", this.destroy);
3113
3113
  super.destroy();
3114
3114
  }
3115
3115
  };
@@ -10,6 +10,7 @@ export * from './document.js';
10
10
  export * from './meshagent-client.js';
11
11
  export * from './messaging-client.js';
12
12
  export * from './memory-client.js';
13
+ export * from './mounts-client.js';
13
14
  export * from './oauth-scopes.js';
14
15
  export * from './participant-token.js';
15
16
  export * from './participant.js';
@@ -26,6 +26,7 @@ __exportStar(require("./document.js"), exports);
26
26
  __exportStar(require("./meshagent-client.js"), exports);
27
27
  __exportStar(require("./messaging-client.js"), exports);
28
28
  __exportStar(require("./memory-client.js"), exports);
29
+ __exportStar(require("./mounts-client.js"), exports);
29
30
  __exportStar(require("./oauth-scopes.js"), exports);
30
31
  __exportStar(require("./participant-token.js"), exports);
31
32
  __exportStar(require("./participant.js"), exports);
@@ -1,7 +1,8 @@
1
1
  import { ApiScope } from "./participant-token.js";
2
2
  export type ProjectRole = "member" | "admin" | "developer" | "room_creator" | "room_inventory" | "room_manager" | "session_inventory" | "agent_creator" | "agent_inventory" | "agent_manager" | "repository_creator" | "repository_inventory" | "repository_manager" | "feed_creator" | "feed_inventory" | "feed_manager" | "oauth_client_creator" | "oauth_client_inventory" | "oauth_client_manager" | "api_key_creator" | "api_key_inventory" | "api_key_manager" | "service_creator" | "service_inventory" | "service_manager" | "service_account_creator" | "service_account_inventory" | "service_account_manager" | "participant_token_creator" | "mailbox_creator" | "mailbox_inventory" | "mailbox_manager" | "route_creator" | "route_inventory" | "route_manager" | "scheduled_task_creator" | "scheduled_task_inventory" | "scheduled_task_manager" | "feed_subscription_creator" | "feed_subscription_inventory" | "feed_subscription_manager" | "llm_logger_creator" | "llm_logger_inventory" | "llm_logger_manager" | "llm_proxy_user" | "usage_reporter" | "billing_manager" | "group_manager";
3
3
  export type ResourceRole = "viewer" | "operator" | "developer" | "admin";
4
- export type RoomRole = "site_user" | ResourceRole;
4
+ export type RoomRole = "site_user" | "guest" | ResourceRole;
5
+ export type ProjectSettingsDocumentName = "openai" | "anthropic" | "otel" | "admission" | "room" | "room_roles";
5
6
  export type FeedRole = "reader" | "subscriber" | "publisher" | "manager";
6
7
  export type SecretRole = "use_proxy";
7
8
  export type AccessRole = ProjectRole | RoomRole | FeedRole | SecretRole | "list";
@@ -235,6 +236,12 @@ export interface RoomStorageMountSpec {
235
236
  subpath?: string | null;
236
237
  read_only?: boolean;
237
238
  }
239
+ export interface VolumeStorageMountSpec {
240
+ name: string;
241
+ path: string;
242
+ subpath?: string | null;
243
+ read_only?: boolean;
244
+ }
238
245
  export interface EmptyDirMountSpec {
239
246
  path: string;
240
247
  read_only?: boolean;
@@ -249,6 +256,7 @@ export interface FileMountSpec {
249
256
  }
250
257
  export interface ContainerMountSpec {
251
258
  room?: RoomStorageMountSpec[];
259
+ volumes?: VolumeStorageMountSpec[];
252
260
  empty_dirs?: EmptyDirMountSpec[];
253
261
  configs?: ConfigMountSpec[];
254
262
  files?: FileMountSpec[];
@@ -418,12 +426,33 @@ export interface RouteBackend {
418
426
  room?: RouteBackendTarget | null;
419
427
  agent?: RouteBackendTarget | null;
420
428
  }
421
- export interface RoutePathSpec {
429
+ export interface RouteCorsRule {
430
+ allowedOrigins: string[];
431
+ allowedMethods?: string[];
432
+ allowedHeaders?: string[];
433
+ exposeHeaders?: string[];
434
+ maxAgeSeconds?: number;
435
+ allowCredentials?: boolean;
436
+ }
437
+ export interface RouteContentSpec {
438
+ subpath?: string;
439
+ cors?: RouteCorsRule[];
440
+ index?: boolean;
441
+ iap?: boolean;
442
+ compression?: "brotli" | "gzip" | "none";
443
+ }
444
+ interface RoutePathBase {
422
445
  path?: string;
423
446
  pathType?: "prefix" | "exact";
424
447
  stripPrefix?: boolean;
425
- targetPort: string | number;
426
448
  }
449
+ export type RoutePathSpec = RoutePathBase & ({
450
+ targetPort: string | number;
451
+ targetContent?: never;
452
+ } | {
453
+ targetContent: RouteContentSpec;
454
+ targetPort?: never;
455
+ });
427
456
  export interface RouteSpec {
428
457
  version: "v1";
429
458
  kind: "Route";
@@ -577,14 +606,17 @@ export declare class Meshagent {
577
606
  projectId: string;
578
607
  path: string;
579
608
  }): Promise<Uint8Array>;
580
- createProject(name: string, settings?: Record<string, unknown>): Promise<Record<string, unknown>>;
609
+ createProject(name: string): Promise<Record<string, unknown>>;
581
610
  addUserToProject(projectId: string, userId: string, options?: {
582
611
  roles?: ProjectRole[];
583
612
  email?: string;
584
613
  inviteRedirectUrl?: string;
585
614
  }): Promise<Record<string, unknown>>;
586
615
  removeUserFromProject(projectId: string, userId: string): Promise<Record<string, unknown>>;
587
- updateProjectSettings(projectId: string, settings: Record<string, unknown>): Promise<Record<string, unknown>>;
616
+ private projectSettingsDocumentPath;
617
+ getProjectSettingsDocument(projectId: string, name: ProjectSettingsDocumentName): Promise<Record<string, unknown> | undefined>;
618
+ setProjectSettingsDocument(projectId: string, name: ProjectSettingsDocumentName, document: Record<string, unknown>): Promise<Record<string, unknown>>;
619
+ deleteProjectSettingsDocument(projectId: string, name: ProjectSettingsDocumentName): Promise<Record<string, unknown>>;
588
620
  updateUserInProject(projectId: string, userId: string, roles: ProjectRole[]): Promise<Record<string, unknown>>;
589
621
  getUsersInProjectPage(projectId: string, options?: {
590
622
  pageSize?: number;
@@ -250,7 +250,7 @@ class Meshagent {
250
250
  return url.toString();
251
251
  }
252
252
  async request(path, options) {
253
- const { method = "GET", query, json, body, headers, action, responseType = "json" } = options;
253
+ const { method = "GET", query, json, body, headers, action, responseType = "json", returnUndefinedOnNotFound = false } = options;
254
254
  const url = this.buildUrl(path, query);
255
255
  const finalHeaders = {};
256
256
  if (this.token) {
@@ -279,6 +279,9 @@ class Meshagent {
279
279
  headers: finalHeaders,
280
280
  body: toFetchBody(requestBody),
281
281
  });
282
+ if (response.status === 404 && returnUndefinedOnNotFound) {
283
+ return undefined;
284
+ }
282
285
  if (!response.ok) {
283
286
  let message;
284
287
  try {
@@ -867,10 +870,10 @@ class Meshagent {
867
870
  responseType: "arrayBuffer",
868
871
  });
869
872
  }
870
- async createProject(name, settings) {
873
+ async createProject(name) {
871
874
  return await this.request(`/accounts/projects`, {
872
875
  method: "POST",
873
- json: { name, settings },
876
+ json: { name },
874
877
  action: "create project",
875
878
  });
876
879
  }
@@ -894,11 +897,26 @@ class Meshagent {
894
897
  action: "remove user from project",
895
898
  });
896
899
  }
897
- async updateProjectSettings(projectId, settings) {
898
- return await this.request(`/accounts/projects/${projectId}/settings`, {
900
+ projectSettingsDocumentPath(name) {
901
+ return name === "room_roles" ? "room-roles" : name;
902
+ }
903
+ async getProjectSettingsDocument(projectId, name) {
904
+ return await this.request(`/accounts/projects/${projectId}/settings/${this.projectSettingsDocumentPath(name)}`, {
905
+ action: `get ${name} project settings`,
906
+ returnUndefinedOnNotFound: true,
907
+ });
908
+ }
909
+ async setProjectSettingsDocument(projectId, name, document) {
910
+ return await this.request(`/accounts/projects/${projectId}/settings/${this.projectSettingsDocumentPath(name)}`, {
899
911
  method: "PUT",
900
- json: settings,
901
- action: "update project settings",
912
+ json: document,
913
+ action: `set ${name} project settings`,
914
+ });
915
+ }
916
+ async deleteProjectSettingsDocument(projectId, name) {
917
+ return await this.request(`/accounts/projects/${projectId}/settings/${this.projectSettingsDocumentPath(name)}`, {
918
+ method: "DELETE",
919
+ action: `delete ${name} project settings`,
902
920
  });
903
921
  }
904
922
  async updateUserInProject(projectId, userId, roles) {
@@ -693,8 +693,15 @@ class MessagingClient extends event_emitter_js_1.EventEmitter {
693
693
  break;
694
694
  }
695
695
  const event = new room_event_js_1.RoomMessageEvent({ message });
696
- this.client.emit(event);
697
- this.emit("message", event);
696
+ try {
697
+ this.client.emit(event);
698
+ this.emit("message", event);
699
+ }
700
+ finally {
701
+ if (message.type === "dismiss") {
702
+ this.client._dismiss();
703
+ }
704
+ }
698
705
  }
699
706
  _onParticipantEnabled(message) {
700
707
  const data = message.message;