@meshagent/meshagent 0.48.0 → 0.49.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/browser/meshagent-client.d.ts +30 -5
- package/dist/browser/meshagent-client.js +25 -7
- package/dist/browser/messaging-client.js +9 -2
- package/dist/browser/room-client.d.ts +2 -0
- package/dist/browser/room-client.js +11 -3
- package/dist/esm/meshagent-client.d.ts +30 -5
- package/dist/esm/meshagent-client.js +25 -7
- package/dist/esm/messaging-client.js +9 -2
- package/dist/esm/room-client.d.ts +2 -0
- package/dist/esm/room-client.js +11 -3
- package/dist/node/meshagent-client.d.ts +30 -5
- package/dist/node/meshagent-client.js +25 -7
- package/dist/node/messaging-client.js +9 -2
- package/dist/node/room-client.d.ts +2 -0
- package/dist/node/room-client.js +11 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [0.49.1]
|
|
2
|
+
- Stability
|
|
3
|
+
|
|
4
|
+
## [0.49.0]
|
|
5
|
+
- Breaking: `createProject` no longer accepts inline settings; project settings are now document-based with `room_roles` support.
|
|
6
|
+
- Route path models now use a service-port/content-target union and support CORS, compression, index, and IAP for room-content routes.
|
|
7
|
+
- `RoomRole` now includes `guest`, and missing project-settings documents return `undefined`.
|
|
8
|
+
|
|
9
|
+
## [0.48.1]
|
|
10
|
+
- Stability
|
|
11
|
+
- Added typed room-content route targets with subpath, CORS, index serving, IAP, and Brotli-by-default compression options.
|
|
12
|
+
|
|
1
13
|
## [0.48.0]
|
|
2
14
|
- Reworked the TS/JS agent chat stack to preserve ordered threaded messages and support injected-message threads across chat clients and process handling.
|
|
3
15
|
- Added chat feed widgets and virtual scrolling to the React/Tailwind UI, improving large-thread performance.
|
|
@@ -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";
|
|
@@ -425,12 +426,33 @@ export interface RouteBackend {
|
|
|
425
426
|
room?: RouteBackendTarget | null;
|
|
426
427
|
agent?: RouteBackendTarget | null;
|
|
427
428
|
}
|
|
428
|
-
export interface
|
|
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 {
|
|
429
445
|
path?: string;
|
|
430
446
|
pathType?: "prefix" | "exact";
|
|
431
447
|
stripPrefix?: boolean;
|
|
432
|
-
targetPort: string | number;
|
|
433
448
|
}
|
|
449
|
+
export type RoutePathSpec = RoutePathBase & ({
|
|
450
|
+
targetPort: string | number;
|
|
451
|
+
targetContent?: never;
|
|
452
|
+
} | {
|
|
453
|
+
targetContent: RouteContentSpec;
|
|
454
|
+
targetPort?: never;
|
|
455
|
+
});
|
|
434
456
|
export interface RouteSpec {
|
|
435
457
|
version: "v1";
|
|
436
458
|
kind: "Route";
|
|
@@ -584,14 +606,17 @@ export declare class Meshagent {
|
|
|
584
606
|
projectId: string;
|
|
585
607
|
path: string;
|
|
586
608
|
}): Promise<Uint8Array>;
|
|
587
|
-
createProject(name: string
|
|
609
|
+
createProject(name: string): Promise<Record<string, unknown>>;
|
|
588
610
|
addUserToProject(projectId: string, userId: string, options?: {
|
|
589
611
|
roles?: ProjectRole[];
|
|
590
612
|
email?: string;
|
|
591
613
|
inviteRedirectUrl?: string;
|
|
592
614
|
}): Promise<Record<string, unknown>>;
|
|
593
615
|
removeUserFromProject(projectId: string, userId: string): Promise<Record<string, unknown>>;
|
|
594
|
-
|
|
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>>;
|
|
595
620
|
updateUserInProject(projectId: string, userId: string, roles: ProjectRole[]): Promise<Record<string, unknown>>;
|
|
596
621
|
getUsersInProjectPage(projectId: string, options?: {
|
|
597
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
|
|
873
|
+
async createProject(name) {
|
|
871
874
|
return await this.request(`/accounts/projects`, {
|
|
872
875
|
method: "POST",
|
|
873
|
-
json: { name
|
|
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
|
-
|
|
898
|
-
return
|
|
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:
|
|
901
|
-
action:
|
|
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
|
-
|
|
697
|
-
|
|
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;
|
|
@@ -78,6 +78,7 @@ export declare class RoomClient {
|
|
|
78
78
|
private _localParticipantReady;
|
|
79
79
|
private _connected;
|
|
80
80
|
private _closing;
|
|
81
|
+
private _dismissed;
|
|
81
82
|
private _localParticipant;
|
|
82
83
|
private _lifecycleTask;
|
|
83
84
|
private _terminalState;
|
|
@@ -169,6 +170,7 @@ export declare class RoomClient {
|
|
|
169
170
|
private _retryProtocolConnection;
|
|
170
171
|
private _reconnect;
|
|
171
172
|
private _connectionLifecycle;
|
|
173
|
+
_dismiss(): void;
|
|
172
174
|
dispose(): void;
|
|
173
175
|
_sendProtocolNowait({ type, data, label, messageId, expectResponse, }: {
|
|
174
176
|
type: string;
|
|
@@ -225,6 +225,7 @@ class RoomClient {
|
|
|
225
225
|
this._localParticipantReady = new completer_js_1.Completer();
|
|
226
226
|
this._connected = false;
|
|
227
227
|
this._closing = false;
|
|
228
|
+
this._dismissed = false;
|
|
228
229
|
this._localParticipant = null;
|
|
229
230
|
this._lifecycleTask = null;
|
|
230
231
|
this._terminalState = null;
|
|
@@ -882,7 +883,7 @@ class RoomClient {
|
|
|
882
883
|
const deadline = this._reconnectTimeout == null ? null : Date.now() + this._reconnectTimeout;
|
|
883
884
|
let firstAttempt = true;
|
|
884
885
|
let retryCount = 0;
|
|
885
|
-
while (!this._closing) {
|
|
886
|
+
while (!this._closing && !this._dismissed) {
|
|
886
887
|
if (firstAttempt) {
|
|
887
888
|
firstAttempt = false;
|
|
888
889
|
if (this._reconnectTimeout == null) {
|
|
@@ -1013,7 +1014,7 @@ class RoomClient {
|
|
|
1013
1014
|
this._completeRoomClosed();
|
|
1014
1015
|
return;
|
|
1015
1016
|
}
|
|
1016
|
-
if (closeKind !== protocol_js_1.ProtocolCloseKind.ERROR) {
|
|
1017
|
+
if (closeKind !== protocol_js_1.ProtocolCloseKind.ERROR || this._dismissed) {
|
|
1017
1018
|
this._setTerminalState({ state });
|
|
1018
1019
|
}
|
|
1019
1020
|
this._markDisconnected({ reason: closeReason, kind: closeKind });
|
|
@@ -1025,7 +1026,7 @@ class RoomClient {
|
|
|
1025
1026
|
this.messaging._onRoomDisconnect({ reason: closeReason });
|
|
1026
1027
|
await this._failPendingWork({ state });
|
|
1027
1028
|
await this._closeProtocol(protocol);
|
|
1028
|
-
if (closeKind === protocol_js_1.ProtocolCloseKind.ERROR) {
|
|
1029
|
+
if (closeKind === protocol_js_1.ProtocolCloseKind.ERROR && !this._dismissed) {
|
|
1029
1030
|
if (this._reconnectTimeout === 0) {
|
|
1030
1031
|
if (closeReason == null) {
|
|
1031
1032
|
console.warn("room connection lost; automatic reconnect disabled");
|
|
@@ -1054,6 +1055,13 @@ class RoomClient {
|
|
|
1054
1055
|
return;
|
|
1055
1056
|
}
|
|
1056
1057
|
}
|
|
1058
|
+
_dismiss() {
|
|
1059
|
+
if (this._closing || this._dismissed) {
|
|
1060
|
+
return;
|
|
1061
|
+
}
|
|
1062
|
+
this._dismissed = true;
|
|
1063
|
+
this._protocolInstance.dispose();
|
|
1064
|
+
}
|
|
1057
1065
|
dispose() {
|
|
1058
1066
|
this._closing = true;
|
|
1059
1067
|
this._markDisconnected({
|
|
@@ -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";
|
|
@@ -425,12 +426,33 @@ export interface RouteBackend {
|
|
|
425
426
|
room?: RouteBackendTarget | null;
|
|
426
427
|
agent?: RouteBackendTarget | null;
|
|
427
428
|
}
|
|
428
|
-
export interface
|
|
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 {
|
|
429
445
|
path?: string;
|
|
430
446
|
pathType?: "prefix" | "exact";
|
|
431
447
|
stripPrefix?: boolean;
|
|
432
|
-
targetPort: string | number;
|
|
433
448
|
}
|
|
449
|
+
export type RoutePathSpec = RoutePathBase & ({
|
|
450
|
+
targetPort: string | number;
|
|
451
|
+
targetContent?: never;
|
|
452
|
+
} | {
|
|
453
|
+
targetContent: RouteContentSpec;
|
|
454
|
+
targetPort?: never;
|
|
455
|
+
});
|
|
434
456
|
export interface RouteSpec {
|
|
435
457
|
version: "v1";
|
|
436
458
|
kind: "Route";
|
|
@@ -584,14 +606,17 @@ export declare class Meshagent {
|
|
|
584
606
|
projectId: string;
|
|
585
607
|
path: string;
|
|
586
608
|
}): Promise<Uint8Array>;
|
|
587
|
-
createProject(name: string
|
|
609
|
+
createProject(name: string): Promise<Record<string, unknown>>;
|
|
588
610
|
addUserToProject(projectId: string, userId: string, options?: {
|
|
589
611
|
roles?: ProjectRole[];
|
|
590
612
|
email?: string;
|
|
591
613
|
inviteRedirectUrl?: string;
|
|
592
614
|
}): Promise<Record<string, unknown>>;
|
|
593
615
|
removeUserFromProject(projectId: string, userId: string): Promise<Record<string, unknown>>;
|
|
594
|
-
|
|
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>>;
|
|
595
620
|
updateUserInProject(projectId: string, userId: string, roles: ProjectRole[]): Promise<Record<string, unknown>>;
|
|
596
621
|
getUsersInProjectPage(projectId: string, options?: {
|
|
597
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
|
|
868
|
+
async createProject(name) {
|
|
866
869
|
return await this.request(`/accounts/projects`, {
|
|
867
870
|
method: "POST",
|
|
868
|
-
json: { name
|
|
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
|
-
|
|
893
|
-
return
|
|
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:
|
|
896
|
-
action:
|
|
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
|
-
|
|
693
|
-
|
|
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;
|
|
@@ -78,6 +78,7 @@ export declare class RoomClient {
|
|
|
78
78
|
private _localParticipantReady;
|
|
79
79
|
private _connected;
|
|
80
80
|
private _closing;
|
|
81
|
+
private _dismissed;
|
|
81
82
|
private _localParticipant;
|
|
82
83
|
private _lifecycleTask;
|
|
83
84
|
private _terminalState;
|
|
@@ -169,6 +170,7 @@ export declare class RoomClient {
|
|
|
169
170
|
private _retryProtocolConnection;
|
|
170
171
|
private _reconnect;
|
|
171
172
|
private _connectionLifecycle;
|
|
173
|
+
_dismiss(): void;
|
|
172
174
|
dispose(): void;
|
|
173
175
|
_sendProtocolNowait({ type, data, label, messageId, expectResponse, }: {
|
|
174
176
|
type: string;
|
package/dist/esm/room-client.js
CHANGED
|
@@ -221,6 +221,7 @@ export class RoomClient {
|
|
|
221
221
|
this._localParticipantReady = new Completer();
|
|
222
222
|
this._connected = false;
|
|
223
223
|
this._closing = false;
|
|
224
|
+
this._dismissed = false;
|
|
224
225
|
this._localParticipant = null;
|
|
225
226
|
this._lifecycleTask = null;
|
|
226
227
|
this._terminalState = null;
|
|
@@ -878,7 +879,7 @@ export class RoomClient {
|
|
|
878
879
|
const deadline = this._reconnectTimeout == null ? null : Date.now() + this._reconnectTimeout;
|
|
879
880
|
let firstAttempt = true;
|
|
880
881
|
let retryCount = 0;
|
|
881
|
-
while (!this._closing) {
|
|
882
|
+
while (!this._closing && !this._dismissed) {
|
|
882
883
|
if (firstAttempt) {
|
|
883
884
|
firstAttempt = false;
|
|
884
885
|
if (this._reconnectTimeout == null) {
|
|
@@ -1009,7 +1010,7 @@ export class RoomClient {
|
|
|
1009
1010
|
this._completeRoomClosed();
|
|
1010
1011
|
return;
|
|
1011
1012
|
}
|
|
1012
|
-
if (closeKind !== ProtocolCloseKind.ERROR) {
|
|
1013
|
+
if (closeKind !== ProtocolCloseKind.ERROR || this._dismissed) {
|
|
1013
1014
|
this._setTerminalState({ state });
|
|
1014
1015
|
}
|
|
1015
1016
|
this._markDisconnected({ reason: closeReason, kind: closeKind });
|
|
@@ -1021,7 +1022,7 @@ export class RoomClient {
|
|
|
1021
1022
|
this.messaging._onRoomDisconnect({ reason: closeReason });
|
|
1022
1023
|
await this._failPendingWork({ state });
|
|
1023
1024
|
await this._closeProtocol(protocol);
|
|
1024
|
-
if (closeKind === ProtocolCloseKind.ERROR) {
|
|
1025
|
+
if (closeKind === ProtocolCloseKind.ERROR && !this._dismissed) {
|
|
1025
1026
|
if (this._reconnectTimeout === 0) {
|
|
1026
1027
|
if (closeReason == null) {
|
|
1027
1028
|
console.warn("room connection lost; automatic reconnect disabled");
|
|
@@ -1050,6 +1051,13 @@ export class RoomClient {
|
|
|
1050
1051
|
return;
|
|
1051
1052
|
}
|
|
1052
1053
|
}
|
|
1054
|
+
_dismiss() {
|
|
1055
|
+
if (this._closing || this._dismissed) {
|
|
1056
|
+
return;
|
|
1057
|
+
}
|
|
1058
|
+
this._dismissed = true;
|
|
1059
|
+
this._protocolInstance.dispose();
|
|
1060
|
+
}
|
|
1053
1061
|
dispose() {
|
|
1054
1062
|
this._closing = true;
|
|
1055
1063
|
this._markDisconnected({
|
|
@@ -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";
|
|
@@ -425,12 +426,33 @@ export interface RouteBackend {
|
|
|
425
426
|
room?: RouteBackendTarget | null;
|
|
426
427
|
agent?: RouteBackendTarget | null;
|
|
427
428
|
}
|
|
428
|
-
export interface
|
|
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 {
|
|
429
445
|
path?: string;
|
|
430
446
|
pathType?: "prefix" | "exact";
|
|
431
447
|
stripPrefix?: boolean;
|
|
432
|
-
targetPort: string | number;
|
|
433
448
|
}
|
|
449
|
+
export type RoutePathSpec = RoutePathBase & ({
|
|
450
|
+
targetPort: string | number;
|
|
451
|
+
targetContent?: never;
|
|
452
|
+
} | {
|
|
453
|
+
targetContent: RouteContentSpec;
|
|
454
|
+
targetPort?: never;
|
|
455
|
+
});
|
|
434
456
|
export interface RouteSpec {
|
|
435
457
|
version: "v1";
|
|
436
458
|
kind: "Route";
|
|
@@ -584,14 +606,17 @@ export declare class Meshagent {
|
|
|
584
606
|
projectId: string;
|
|
585
607
|
path: string;
|
|
586
608
|
}): Promise<Uint8Array>;
|
|
587
|
-
createProject(name: string
|
|
609
|
+
createProject(name: string): Promise<Record<string, unknown>>;
|
|
588
610
|
addUserToProject(projectId: string, userId: string, options?: {
|
|
589
611
|
roles?: ProjectRole[];
|
|
590
612
|
email?: string;
|
|
591
613
|
inviteRedirectUrl?: string;
|
|
592
614
|
}): Promise<Record<string, unknown>>;
|
|
593
615
|
removeUserFromProject(projectId: string, userId: string): Promise<Record<string, unknown>>;
|
|
594
|
-
|
|
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>>;
|
|
595
620
|
updateUserInProject(projectId: string, userId: string, roles: ProjectRole[]): Promise<Record<string, unknown>>;
|
|
596
621
|
getUsersInProjectPage(projectId: string, options?: {
|
|
597
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
|
|
873
|
+
async createProject(name) {
|
|
871
874
|
return await this.request(`/accounts/projects`, {
|
|
872
875
|
method: "POST",
|
|
873
|
-
json: { name
|
|
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
|
-
|
|
898
|
-
return
|
|
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:
|
|
901
|
-
action:
|
|
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
|
-
|
|
697
|
-
|
|
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;
|
|
@@ -78,6 +78,7 @@ export declare class RoomClient {
|
|
|
78
78
|
private _localParticipantReady;
|
|
79
79
|
private _connected;
|
|
80
80
|
private _closing;
|
|
81
|
+
private _dismissed;
|
|
81
82
|
private _localParticipant;
|
|
82
83
|
private _lifecycleTask;
|
|
83
84
|
private _terminalState;
|
|
@@ -169,6 +170,7 @@ export declare class RoomClient {
|
|
|
169
170
|
private _retryProtocolConnection;
|
|
170
171
|
private _reconnect;
|
|
171
172
|
private _connectionLifecycle;
|
|
173
|
+
_dismiss(): void;
|
|
172
174
|
dispose(): void;
|
|
173
175
|
_sendProtocolNowait({ type, data, label, messageId, expectResponse, }: {
|
|
174
176
|
type: string;
|
package/dist/node/room-client.js
CHANGED
|
@@ -225,6 +225,7 @@ class RoomClient {
|
|
|
225
225
|
this._localParticipantReady = new completer_js_1.Completer();
|
|
226
226
|
this._connected = false;
|
|
227
227
|
this._closing = false;
|
|
228
|
+
this._dismissed = false;
|
|
228
229
|
this._localParticipant = null;
|
|
229
230
|
this._lifecycleTask = null;
|
|
230
231
|
this._terminalState = null;
|
|
@@ -882,7 +883,7 @@ class RoomClient {
|
|
|
882
883
|
const deadline = this._reconnectTimeout == null ? null : Date.now() + this._reconnectTimeout;
|
|
883
884
|
let firstAttempt = true;
|
|
884
885
|
let retryCount = 0;
|
|
885
|
-
while (!this._closing) {
|
|
886
|
+
while (!this._closing && !this._dismissed) {
|
|
886
887
|
if (firstAttempt) {
|
|
887
888
|
firstAttempt = false;
|
|
888
889
|
if (this._reconnectTimeout == null) {
|
|
@@ -1013,7 +1014,7 @@ class RoomClient {
|
|
|
1013
1014
|
this._completeRoomClosed();
|
|
1014
1015
|
return;
|
|
1015
1016
|
}
|
|
1016
|
-
if (closeKind !== protocol_js_1.ProtocolCloseKind.ERROR) {
|
|
1017
|
+
if (closeKind !== protocol_js_1.ProtocolCloseKind.ERROR || this._dismissed) {
|
|
1017
1018
|
this._setTerminalState({ state });
|
|
1018
1019
|
}
|
|
1019
1020
|
this._markDisconnected({ reason: closeReason, kind: closeKind });
|
|
@@ -1025,7 +1026,7 @@ class RoomClient {
|
|
|
1025
1026
|
this.messaging._onRoomDisconnect({ reason: closeReason });
|
|
1026
1027
|
await this._failPendingWork({ state });
|
|
1027
1028
|
await this._closeProtocol(protocol);
|
|
1028
|
-
if (closeKind === protocol_js_1.ProtocolCloseKind.ERROR) {
|
|
1029
|
+
if (closeKind === protocol_js_1.ProtocolCloseKind.ERROR && !this._dismissed) {
|
|
1029
1030
|
if (this._reconnectTimeout === 0) {
|
|
1030
1031
|
if (closeReason == null) {
|
|
1031
1032
|
console.warn("room connection lost; automatic reconnect disabled");
|
|
@@ -1054,6 +1055,13 @@ class RoomClient {
|
|
|
1054
1055
|
return;
|
|
1055
1056
|
}
|
|
1056
1057
|
}
|
|
1058
|
+
_dismiss() {
|
|
1059
|
+
if (this._closing || this._dismissed) {
|
|
1060
|
+
return;
|
|
1061
|
+
}
|
|
1062
|
+
this._dismissed = true;
|
|
1063
|
+
this._protocolInstance.dispose();
|
|
1064
|
+
}
|
|
1057
1065
|
dispose() {
|
|
1058
1066
|
this._closing = true;
|
|
1059
1067
|
this._markDisconnected({
|