@ateam-ai-mobile/core 0.1.1 → 0.1.2

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/dist/index.d.mts CHANGED
@@ -80,6 +80,10 @@ interface AdasConfig {
80
80
  coreUrl: UrlSource;
81
81
  /** Voice service base URL (optional — only voice features need it). */
82
82
  voiceUrl?: UrlSource;
83
+ /** Consumer-auth base URL, e.g. https://consumer-auth.ateam-ai.com. Only
84
+ * needed for `switchTenant()` (re-scoping the session to another tenant
85
+ * the user belongs to). */
86
+ consumerAuthUrl?: UrlSource;
83
87
  tokenProvider: TokenProvider;
84
88
  /** Tenant slug — used for plugin URL resolution and voice, never sent as a
85
89
  * header (the backend derives the tenant from the JWT). Pass a getter when
@@ -93,6 +97,24 @@ interface AdasConfig {
93
97
  * survive app restarts. No-op when omitted (previews live in memory for
94
98
  * the session only). @ateam-ai-mobile/ui ships an Expo/RN implementation. */
95
99
  attachmentCache?: AttachmentCache;
100
+ /** Called by `switchTenant()` with the freshly-minted session for the
101
+ * target tenant. The host MUST persist it here (store the new JWT so
102
+ * tokenProvider.getToken() returns it, and update the active tenant) —
103
+ * the SDK never stores credentials. Awaited before the chat reconnects. */
104
+ onSession?: (session: AdasSession) => void | Promise<void>;
105
+ }
106
+ /** A tenant-scoped session minted by the platform (e.g. via switchTenant). */
107
+ interface AdasSession {
108
+ jwt: string;
109
+ tenant: {
110
+ id: string;
111
+ name: string;
112
+ };
113
+ actor: {
114
+ id: string;
115
+ email: string | null;
116
+ roles: string[];
117
+ };
96
118
  }
97
119
  /** Register the SDK configuration. Call once at app start, before any other
98
120
  * SDK API. Calling again replaces the config (e.g. env switch) — combine
@@ -103,6 +125,7 @@ declare function getConfig(): AdasConfig;
103
125
  declare function getCoreApiUrl(): string;
104
126
  declare function getCoreWsUrl(): string;
105
127
  declare function getVoiceApiUrl(): string;
128
+ declare function getConsumerAuthApiUrl(): string;
106
129
  declare function getTenant(): string;
107
130
  declare function getUser(): AdasUser | null;
108
131
  declare function getToken(): string | null;
@@ -160,14 +183,26 @@ interface TenantMembership {
160
183
  /**
161
184
  * List the tenants the CURRENT user belongs to (GET /api/tenants/list).
162
185
  *
163
- * For consumer JWTs the backend resolves memberships by login identity
164
- * (google/apple oauth or embed id) across active tenants; builder JWTs get
165
- * their user-doc memberships. Returns [] when signed out or unknown.
166
- *
167
- * Note: switching tenant still requires a NEW JWT for that tenant (the
168
- * token is tenant-scoped) — the host owns that re-auth flow.
186
+ * The list is membership-scoped: for consumer JWTs the backend returns ONLY
187
+ * tenants where the user's login identity (google/apple oauth or embed id)
188
+ * has an active actor; builder JWTs get their user-doc memberships. It never
189
+ * leaks the full tenant list. Returns [] when signed out or unknown.
169
190
  */
170
191
  declare function listMyTenants(): Promise<TenantMembership[]>;
192
+ /**
193
+ * Re-scope the whole session to another tenant the user already belongs to.
194
+ *
195
+ * The backend treats the JWT tenant claim as the sole source of truth, so
196
+ * switching = minting a fresh JWT for the target tenant's actor. The SDK
197
+ * owns the call (POST consumer-auth /platform/consumer/switch-tenant, authed
198
+ * by the current token); the HOST persists the new session via
199
+ * `config.onSession` (the SDK never stores credentials). The chat stream is
200
+ * then torn down and cleared so it reconnects against the new tenant.
201
+ *
202
+ * Requires `consumerAuthUrl` and `onSession` in the initAdas() config.
203
+ * Throws on any non-OK response (e.g. not a member of the target tenant).
204
+ */
205
+ declare function switchTenant(targetTenantId: string): Promise<AdasSession>;
171
206
 
172
207
  interface ToolCall {
173
208
  name: string;
@@ -719,4 +754,4 @@ interface AcsKvStorage {
719
754
  }
720
755
  declare function setAcsCacheStorage(kv: AcsKvStorage | null): void;
721
756
 
722
- export { type AcsArtifact, type AcsDeleteReason, type AcsEvent, type AcsKvStorage, type AcsPatchReason, type AcsReachabilityReporter, type AcsSurface, type AdasConfig, type AdasUser, type AttachmentCache, type AttachmentPreview, type BufferedCommand, type DeleteResult, type HomeAction, type HomeActionLeaf, type HomeActionReason, type JobProgress, type Message, type MessageAttachment, type OutgoingAttachment, type PatchResult, PluginCommandEmitter, type RefreshOutcome, TABLE_BLOCK_CLOSE, TABLE_BLOCK_OPEN, type TenantMembership, type TokenProvider, type ToolCall, type UIAction, ada, apiFetch, apiFetchRaw, blocksToText, borderRadius, closeChatStream, colors, connectAcsWs, connectorCall, deleteArtifact, disconnectAcsWs, fontSize, getConfig, getCoreApiUrl, getCoreWsUrl, getTenant, getToken, getUser, getVoiceApiUrl, initAdas, isAdasInitialized, listHomeActions, listMadeForYou, listMyTenants, listSurface, mcpFetch, mcpToolCall, notifyAcsWsForeground, patchArtifact, patchHomeAction, pluginCommandEmitter, postCommandResult, recordEvent, setAcsCacheStorage, setAcsReachabilityReporter, setHomeActionOrder, setOrder, spacing, unwrapMcpResult, useChatStore, useHomeActionsStore, useWidgetsStore };
757
+ export { type AcsArtifact, type AcsDeleteReason, type AcsEvent, type AcsKvStorage, type AcsPatchReason, type AcsReachabilityReporter, type AcsSurface, type AdasConfig, type AdasSession, type AdasUser, type AttachmentCache, type AttachmentPreview, type BufferedCommand, type DeleteResult, type HomeAction, type HomeActionLeaf, type HomeActionReason, type JobProgress, type Message, type MessageAttachment, type OutgoingAttachment, type PatchResult, PluginCommandEmitter, type RefreshOutcome, TABLE_BLOCK_CLOSE, TABLE_BLOCK_OPEN, type TenantMembership, type TokenProvider, type ToolCall, type UIAction, ada, apiFetch, apiFetchRaw, blocksToText, borderRadius, closeChatStream, colors, connectAcsWs, connectorCall, deleteArtifact, disconnectAcsWs, fontSize, getConfig, getConsumerAuthApiUrl, getCoreApiUrl, getCoreWsUrl, getTenant, getToken, getUser, getVoiceApiUrl, initAdas, isAdasInitialized, listHomeActions, listMadeForYou, listMyTenants, listSurface, mcpFetch, mcpToolCall, notifyAcsWsForeground, patchArtifact, patchHomeAction, pluginCommandEmitter, postCommandResult, recordEvent, setAcsCacheStorage, setAcsReachabilityReporter, setHomeActionOrder, setOrder, spacing, switchTenant, unwrapMcpResult, useChatStore, useHomeActionsStore, useWidgetsStore };
package/dist/index.d.ts CHANGED
@@ -80,6 +80,10 @@ interface AdasConfig {
80
80
  coreUrl: UrlSource;
81
81
  /** Voice service base URL (optional — only voice features need it). */
82
82
  voiceUrl?: UrlSource;
83
+ /** Consumer-auth base URL, e.g. https://consumer-auth.ateam-ai.com. Only
84
+ * needed for `switchTenant()` (re-scoping the session to another tenant
85
+ * the user belongs to). */
86
+ consumerAuthUrl?: UrlSource;
83
87
  tokenProvider: TokenProvider;
84
88
  /** Tenant slug — used for plugin URL resolution and voice, never sent as a
85
89
  * header (the backend derives the tenant from the JWT). Pass a getter when
@@ -93,6 +97,24 @@ interface AdasConfig {
93
97
  * survive app restarts. No-op when omitted (previews live in memory for
94
98
  * the session only). @ateam-ai-mobile/ui ships an Expo/RN implementation. */
95
99
  attachmentCache?: AttachmentCache;
100
+ /** Called by `switchTenant()` with the freshly-minted session for the
101
+ * target tenant. The host MUST persist it here (store the new JWT so
102
+ * tokenProvider.getToken() returns it, and update the active tenant) —
103
+ * the SDK never stores credentials. Awaited before the chat reconnects. */
104
+ onSession?: (session: AdasSession) => void | Promise<void>;
105
+ }
106
+ /** A tenant-scoped session minted by the platform (e.g. via switchTenant). */
107
+ interface AdasSession {
108
+ jwt: string;
109
+ tenant: {
110
+ id: string;
111
+ name: string;
112
+ };
113
+ actor: {
114
+ id: string;
115
+ email: string | null;
116
+ roles: string[];
117
+ };
96
118
  }
97
119
  /** Register the SDK configuration. Call once at app start, before any other
98
120
  * SDK API. Calling again replaces the config (e.g. env switch) — combine
@@ -103,6 +125,7 @@ declare function getConfig(): AdasConfig;
103
125
  declare function getCoreApiUrl(): string;
104
126
  declare function getCoreWsUrl(): string;
105
127
  declare function getVoiceApiUrl(): string;
128
+ declare function getConsumerAuthApiUrl(): string;
106
129
  declare function getTenant(): string;
107
130
  declare function getUser(): AdasUser | null;
108
131
  declare function getToken(): string | null;
@@ -160,14 +183,26 @@ interface TenantMembership {
160
183
  /**
161
184
  * List the tenants the CURRENT user belongs to (GET /api/tenants/list).
162
185
  *
163
- * For consumer JWTs the backend resolves memberships by login identity
164
- * (google/apple oauth or embed id) across active tenants; builder JWTs get
165
- * their user-doc memberships. Returns [] when signed out or unknown.
166
- *
167
- * Note: switching tenant still requires a NEW JWT for that tenant (the
168
- * token is tenant-scoped) — the host owns that re-auth flow.
186
+ * The list is membership-scoped: for consumer JWTs the backend returns ONLY
187
+ * tenants where the user's login identity (google/apple oauth or embed id)
188
+ * has an active actor; builder JWTs get their user-doc memberships. It never
189
+ * leaks the full tenant list. Returns [] when signed out or unknown.
169
190
  */
170
191
  declare function listMyTenants(): Promise<TenantMembership[]>;
192
+ /**
193
+ * Re-scope the whole session to another tenant the user already belongs to.
194
+ *
195
+ * The backend treats the JWT tenant claim as the sole source of truth, so
196
+ * switching = minting a fresh JWT for the target tenant's actor. The SDK
197
+ * owns the call (POST consumer-auth /platform/consumer/switch-tenant, authed
198
+ * by the current token); the HOST persists the new session via
199
+ * `config.onSession` (the SDK never stores credentials). The chat stream is
200
+ * then torn down and cleared so it reconnects against the new tenant.
201
+ *
202
+ * Requires `consumerAuthUrl` and `onSession` in the initAdas() config.
203
+ * Throws on any non-OK response (e.g. not a member of the target tenant).
204
+ */
205
+ declare function switchTenant(targetTenantId: string): Promise<AdasSession>;
171
206
 
172
207
  interface ToolCall {
173
208
  name: string;
@@ -719,4 +754,4 @@ interface AcsKvStorage {
719
754
  }
720
755
  declare function setAcsCacheStorage(kv: AcsKvStorage | null): void;
721
756
 
722
- export { type AcsArtifact, type AcsDeleteReason, type AcsEvent, type AcsKvStorage, type AcsPatchReason, type AcsReachabilityReporter, type AcsSurface, type AdasConfig, type AdasUser, type AttachmentCache, type AttachmentPreview, type BufferedCommand, type DeleteResult, type HomeAction, type HomeActionLeaf, type HomeActionReason, type JobProgress, type Message, type MessageAttachment, type OutgoingAttachment, type PatchResult, PluginCommandEmitter, type RefreshOutcome, TABLE_BLOCK_CLOSE, TABLE_BLOCK_OPEN, type TenantMembership, type TokenProvider, type ToolCall, type UIAction, ada, apiFetch, apiFetchRaw, blocksToText, borderRadius, closeChatStream, colors, connectAcsWs, connectorCall, deleteArtifact, disconnectAcsWs, fontSize, getConfig, getCoreApiUrl, getCoreWsUrl, getTenant, getToken, getUser, getVoiceApiUrl, initAdas, isAdasInitialized, listHomeActions, listMadeForYou, listMyTenants, listSurface, mcpFetch, mcpToolCall, notifyAcsWsForeground, patchArtifact, patchHomeAction, pluginCommandEmitter, postCommandResult, recordEvent, setAcsCacheStorage, setAcsReachabilityReporter, setHomeActionOrder, setOrder, spacing, unwrapMcpResult, useChatStore, useHomeActionsStore, useWidgetsStore };
757
+ export { type AcsArtifact, type AcsDeleteReason, type AcsEvent, type AcsKvStorage, type AcsPatchReason, type AcsReachabilityReporter, type AcsSurface, type AdasConfig, type AdasSession, type AdasUser, type AttachmentCache, type AttachmentPreview, type BufferedCommand, type DeleteResult, type HomeAction, type HomeActionLeaf, type HomeActionReason, type JobProgress, type Message, type MessageAttachment, type OutgoingAttachment, type PatchResult, PluginCommandEmitter, type RefreshOutcome, TABLE_BLOCK_CLOSE, TABLE_BLOCK_OPEN, type TenantMembership, type TokenProvider, type ToolCall, type UIAction, ada, apiFetch, apiFetchRaw, blocksToText, borderRadius, closeChatStream, colors, connectAcsWs, connectorCall, deleteArtifact, disconnectAcsWs, fontSize, getConfig, getConsumerAuthApiUrl, getCoreApiUrl, getCoreWsUrl, getTenant, getToken, getUser, getVoiceApiUrl, initAdas, isAdasInitialized, listHomeActions, listMadeForYou, listMyTenants, listSurface, mcpFetch, mcpToolCall, notifyAcsWsForeground, patchArtifact, patchHomeAction, pluginCommandEmitter, postCommandResult, recordEvent, setAcsCacheStorage, setAcsReachabilityReporter, setHomeActionOrder, setOrder, spacing, switchTenant, unwrapMcpResult, useChatStore, useHomeActionsStore, useWidgetsStore };
package/dist/index.js CHANGED
@@ -36,6 +36,7 @@ __export(index_exports, {
36
36
  disconnectAcsWs: () => disconnectAcsWs,
37
37
  fontSize: () => fontSize,
38
38
  getConfig: () => getConfig,
39
+ getConsumerAuthApiUrl: () => getConsumerAuthApiUrl,
39
40
  getCoreApiUrl: () => getCoreApiUrl,
40
41
  getCoreWsUrl: () => getCoreWsUrl,
41
42
  getTenant: () => getTenant,
@@ -61,6 +62,7 @@ __export(index_exports, {
61
62
  setHomeActionOrder: () => setHomeActionOrder,
62
63
  setOrder: () => setOrder,
63
64
  spacing: () => spacing,
65
+ switchTenant: () => switchTenant,
64
66
  unwrapMcpResult: () => unwrapMcpResult,
65
67
  useChatStore: () => useChatStore,
66
68
  useHomeActionsStore: () => useHomeActionsStore,
@@ -96,6 +98,11 @@ function getVoiceApiUrl() {
96
98
  if (!url) throw new Error("[adas] voiceUrl not configured");
97
99
  return resolveUrl(url);
98
100
  }
101
+ function getConsumerAuthApiUrl() {
102
+ const url = getConfig().consumerAuthUrl;
103
+ if (!url) throw new Error("[adas] consumerAuthUrl not configured \u2014 required for switchTenant()");
104
+ return resolveUrl(url);
105
+ }
99
106
  function getTenant() {
100
107
  const t = getConfig().tenant;
101
108
  return (typeof t === "function" ? t() : t) || "";
@@ -235,12 +242,6 @@ function unwrapMcpResult(result) {
235
242
  }
236
243
  }
237
244
 
238
- // src/api/tenants.ts
239
- async function listMyTenants() {
240
- const data = await apiFetch("/api/tenants/list");
241
- return data.ok && Array.isArray(data.tenants) ? data.tenants : [];
242
- }
243
-
244
245
  // src/chat/store.ts
245
246
  var import_zustand = require("zustand");
246
247
 
@@ -975,6 +976,41 @@ async function pollJob(jobId, token) {
975
976
  });
976
977
  }
977
978
 
979
+ // src/api/tenants.ts
980
+ async function listMyTenants() {
981
+ const data = await apiFetch("/api/tenants/list");
982
+ return data.ok && Array.isArray(data.tenants) ? data.tenants : [];
983
+ }
984
+ async function switchTenant(targetTenantId) {
985
+ const token = getToken();
986
+ if (!token) throw new Error("[adas] switchTenant: not signed in");
987
+ const res = await fetch(`${getConsumerAuthApiUrl()}/platform/consumer/switch-tenant`, {
988
+ method: "POST",
989
+ headers: {
990
+ "Content-Type": "application/json",
991
+ Authorization: `Bearer ${token}`
992
+ },
993
+ body: JSON.stringify({ target_tenant: targetTenantId })
994
+ });
995
+ const data = await res.json().catch(() => null);
996
+ if (!res.ok || !data?.ok || !data.jwt) {
997
+ throw new Error(data?.error || `switchTenant failed (${res.status})`);
998
+ }
999
+ const session = {
1000
+ jwt: data.jwt,
1001
+ tenant: data.tenant,
1002
+ actor: data.actor
1003
+ };
1004
+ const onSession = getConfig().onSession;
1005
+ if (!onSession) {
1006
+ throw new Error("[adas] switchTenant: config.onSession is required to persist the new session");
1007
+ }
1008
+ await onSession(session);
1009
+ closeChatStream();
1010
+ useChatStore.getState().clearChat();
1011
+ return session;
1012
+ }
1013
+
978
1014
  // src/theme/tokens.ts
979
1015
  var colors = {
980
1016
  dark: {
@@ -1666,6 +1702,7 @@ function disconnectAcsWs() {
1666
1702
  disconnectAcsWs,
1667
1703
  fontSize,
1668
1704
  getConfig,
1705
+ getConsumerAuthApiUrl,
1669
1706
  getCoreApiUrl,
1670
1707
  getCoreWsUrl,
1671
1708
  getTenant,
@@ -1691,6 +1728,7 @@ function disconnectAcsWs() {
1691
1728
  setHomeActionOrder,
1692
1729
  setOrder,
1693
1730
  spacing,
1731
+ switchTenant,
1694
1732
  unwrapMcpResult,
1695
1733
  useChatStore,
1696
1734
  useHomeActionsStore,