@aikaara/chat-sdk 0.8.1 → 0.8.3

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/headless.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("./MountTenant-BrBxPpjb.cjs");class r extends i.EventEmitter{registration=null;pendingEdits=[];constructor(e){super(),this.setupListeners(e)}registerForm(e){this.registration=e;const t=this.pendingEdits.filter(s=>s.entity_type===e.entityType&&String(s.entity_id)===String(e.entityId));if(t.length>0){for(const s of t)e.onFieldUpdate(s.fields),this.emit("edit:applied",{entityType:s.entity_type,entityId:s.entity_id,fields:s.fields});this.pendingEdits=this.pendingEdits.filter(s=>!(s.entity_type===e.entityType&&String(s.entity_id)===String(e.entityId)))}}unregisterForm(e,t){this.registration?.entityType===e&&String(this.registration?.entityId)===String(t)&&(this.registration=null)}get currentForm(){return this.registration}pushFieldUpdates(e,t,s){this.registration&&this.registration.entityType===e&&String(this.registration.entityId)===String(t)?(this.registration.onFieldUpdate(s),this.emit("edit:applied",{entityType:e,entityId:t,fields:s})):(this.pendingEdits.push({action:"edit_entity",entity_type:e,entity_id:t,fields:s}),this.emit("edit:pending",{entityType:e,entityId:t,fields:s}))}async requestSave(){if(!this.registration)return{success:!1,error:"No form registered"};try{return await this.registration.onSave(),this.emit("save:success",{entityType:this.registration.entityType,entityId:this.registration.entityId}),{success:!0}}catch(e){const t=e instanceof Error?e.message:"Save failed";return this.emit("save:error",{entityType:this.registration.entityType,entityId:this.registration.entityId,error:t}),{success:!1,error:t}}}async requestTest(e){if(!this.registration?.onTest)return{success:!1,error:"Current form does not support testing"};try{return await this.registration.onTest(e),{success:!0}}catch(t){return{success:!1,error:t instanceof Error?t.message:"Test failed"}}}setupListeners(e){e.on("action:edit_entity",t=>{this.pushFieldUpdates(t.entity_type,t.entity_id,t.fields)}),e.on("action:save_entity",t=>{this.requestSave()}),e.on("action:test_tool",t=>{this.emit("test:triggered",{toolId:t.tool_id,parameters:t.parameters}),this.requestTest(t.parameters)})}}exports.ActionCableClient=i.ActionCableClient;exports.AikaaraChatClient=i.AikaaraChatClient;exports.ApiClient=i.ApiClient;exports.ChannelSubscription=i.ChannelSubscription;exports.ConnectionManager=i.ConnectionManager;exports.ConversationManager=i.ConversationManager;exports.EventEmitter=i.EventEmitter;exports.MessageStore=i.MessageStore;exports.SessionAuthAdapter=i.SessionAuthAdapter;exports.SsoExchangeAdapter=i.SsoExchangeAdapter;exports.TiledeskTransport=i.TiledeskTransport;exports.clearPersistedConversationId=i.clearPersistedConversationId;exports.collectSsoCredentials=i.collectSsoCredentials;exports.createFetchUploadAdapter=i.createFetchUploadAdapter;exports.createPresigned3StepUploadAdapter=i.createPresigned3StepUploadAdapter;exports.createTiledeskHistoryAdapter=i.createTiledeskHistoryAdapter;exports.extractTiledeskFileEnvelope=i.extractTiledeskFileEnvelope;exports.inferTiledeskRole=i.inferTiledeskRole;exports.isTiledeskSelfEcho=i.isTiledeskSelfEcho;exports.mountFromSlug=i.mountFromSlug;exports.mountTenantWidget=i.mount;exports.parseTiledeskTemplate=i.parseTiledeskTemplate;exports.FormBridge=r;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./MountTenant-BCjKRkD8.cjs");class s extends e.EventEmitter{registration=null;pendingEdits=[];constructor(t){super(),this.setupListeners(t)}registerForm(t){this.registration=t;const i=this.pendingEdits.filter(r=>r.entity_type===t.entityType&&String(r.entity_id)===String(t.entityId));if(i.length>0){for(const r of i)t.onFieldUpdate(r.fields),this.emit("edit:applied",{entityType:r.entity_type,entityId:r.entity_id,fields:r.fields});this.pendingEdits=this.pendingEdits.filter(r=>!(r.entity_type===t.entityType&&String(r.entity_id)===String(t.entityId)))}}unregisterForm(t,i){this.registration?.entityType===t&&String(this.registration?.entityId)===String(i)&&(this.registration=null)}get currentForm(){return this.registration}pushFieldUpdates(t,i,r){this.registration&&this.registration.entityType===t&&String(this.registration.entityId)===String(i)?(this.registration.onFieldUpdate(r),this.emit("edit:applied",{entityType:t,entityId:i,fields:r})):(this.pendingEdits.push({action:"edit_entity",entity_type:t,entity_id:i,fields:r}),this.emit("edit:pending",{entityType:t,entityId:i,fields:r}))}async requestSave(){if(!this.registration)return{success:!1,error:"No form registered"};try{return await this.registration.onSave(),this.emit("save:success",{entityType:this.registration.entityType,entityId:this.registration.entityId}),{success:!0}}catch(t){const i=t instanceof Error?t.message:"Save failed";return this.emit("save:error",{entityType:this.registration.entityType,entityId:this.registration.entityId,error:i}),{success:!1,error:i}}}async requestTest(t){if(!this.registration?.onTest)return{success:!1,error:"Current form does not support testing"};try{return await this.registration.onTest(t),{success:!0}}catch(i){return{success:!1,error:i instanceof Error?i.message:"Test failed"}}}setupListeners(t){t.on("action:edit_entity",i=>{this.pushFieldUpdates(i.entity_type,i.entity_id,i.fields)}),t.on("action:save_entity",i=>{this.requestSave()}),t.on("action:test_tool",i=>{this.emit("test:triggered",{toolId:i.tool_id,parameters:i.parameters}),this.requestTest(i.parameters)})}}exports.ActionCableClient=e.ActionCableClient;exports.AikaaraChatClient=e.AikaaraChatClient;exports.ApiClient=e.ApiClient;exports.ChannelSubscription=e.ChannelSubscription;exports.ConnectionManager=e.ConnectionManager;exports.ConversationManager=e.ConversationManager;exports.EventEmitter=e.EventEmitter;exports.MessageStore=e.MessageStore;exports.SessionAuthAdapter=e.SessionAuthAdapter;exports.SsoExchangeAdapter=e.SsoExchangeAdapter;exports.TiledeskTransport=e.TiledeskTransport;exports.TokenDiscoveryError=e.TokenDiscoveryError;exports.TokenDiscoveryReader=e.TokenDiscoveryReader;exports.clearPersistedConversationId=e.clearPersistedConversationId;exports.collectSsoCredentials=e.collectSsoCredentials;exports.createFetchUploadAdapter=e.createFetchUploadAdapter;exports.createPresigned3StepUploadAdapter=e.createPresigned3StepUploadAdapter;exports.createTiledeskHistoryAdapter=e.createTiledeskHistoryAdapter;exports.discoverToken=e.discoverToken;exports.extractTiledeskFileEnvelope=e.extractTiledeskFileEnvelope;exports.inferTiledeskRole=e.inferTiledeskRole;exports.isTiledeskSelfEcho=e.isTiledeskSelfEcho;exports.mountFromSlug=e.mountFromSlug;exports.mountTenantWidget=e.mount;exports.parseTiledeskTemplate=e.parseTiledeskTemplate;exports.FormBridge=s;
@@ -222,8 +222,18 @@ export declare class ApiClient {
222
222
  private baseUrl;
223
223
  private apiKey?;
224
224
  private authToken?;
225
- private userToken;
225
+ protected userToken: string;
226
+ private refreshHook;
226
227
  constructor(baseUrl: string, userToken: string, apiKey?: string, authToken?: string);
228
+ /**
229
+ * Install a refresh hook. When a request returns 401 the client invokes
230
+ * the hook, replaces its in-memory `authToken`, and retries exactly once.
231
+ */
232
+ setAuthRefreshHook(hook: AuthRefreshHook | null): void;
233
+ /** Surface the current bearer (e.g. for upload adapters that share it). */
234
+ getAuthToken(): string | undefined;
235
+ /** Replace the bearer used by subsequent requests. */
236
+ setAuthToken(next: string | undefined): void;
227
237
  createConversation(params: {
228
238
  systemPromptId?: number;
229
239
  channel?: string;
@@ -234,8 +244,17 @@ export declare class ApiClient {
234
244
  getMessages(conversationId: string): Promise<Message[]>;
235
245
  private mapMessage;
236
246
  private request;
247
+ private fetchWithHeaders;
237
248
  }
238
249
 
250
+ export declare type ApiPanelFieldFormat = 'text' | 'currency' | 'date' | 'number';
251
+
252
+ export declare type ApiPanelRefresh = 'load' | 'assistant' | 'interval' | '30s' | '5m' | 'manual';
253
+
254
+ export declare type ApiPanelRender = 'fields' | 'steps';
255
+
256
+ export declare type ApiPanelSource = 'api' | 'paste';
257
+
239
258
  export declare interface AppContext {
240
259
  /** Current page/route path in the host app (e.g., '/products/42') */
241
260
  currentPage: string;
@@ -266,6 +285,30 @@ declare interface AppContext_2 {
266
285
  custom?: Record<string, unknown>;
267
286
  }
268
287
 
288
+ /**
289
+ * Static page metadata written by the dashboard's App Layout tab.
290
+ * The hosted-shell renders top/bottom nav from this list; SDK code
291
+ * doesn't consume it.
292
+ */
293
+ export declare interface AppPageDef {
294
+ id: string;
295
+ name: string;
296
+ /** Icon name from the shell's icon set (Chat, Sparkle, Book, …). */
297
+ icon?: string;
298
+ /** `"chat"` (default surface) or `"static"` (placeholder). */
299
+ kind?: 'chat' | 'static';
300
+ hint?: string;
301
+ }
302
+
303
+ /**
304
+ * Hook the API client uses to recover from a 401. Wired up by the higher
305
+ * level mount when `descriptor.sso.autoRefresh === true`: the discovered
306
+ * partner token is re-read, exchanged for a fresh chat JWT, and the
307
+ * `authToken` field below is updated in place so the retry sends the new
308
+ * bearer. Returning `null` (or throwing) lets the original 401 propagate.
309
+ */
310
+ declare type AuthRefreshHook = () => Promise<string | null>;
311
+
269
312
  export declare class ChannelSubscription {
270
313
  readonly identifier: string;
271
314
  private callbacks;
@@ -523,6 +566,16 @@ export declare class ConversationManager {
523
566
  private saveToStorage;
524
567
  }
525
568
 
569
+ export declare interface CookieSourceConfig {
570
+ /** Cookie name. */
571
+ name?: string;
572
+ /**
573
+ * Informational only. The browser enforces the actual domain scope; we
574
+ * surface this so dashboards can document intent.
575
+ */
576
+ domain?: string;
577
+ }
578
+
526
579
  declare interface CreateConversationResponse {
527
580
  id: string;
528
581
  status: string;
@@ -536,6 +589,23 @@ export declare function createTiledeskHistoryAdapter(config: TiledeskHistoryAdap
536
589
 
537
590
  export declare type CredentialProviders = Record<string, () => string | Promise<string>>;
538
591
 
592
+ export declare interface DiscoveredToken {
593
+ /** The raw partner token. */
594
+ token: string;
595
+ /** Echoed so callers can log + alert when the source changes mid-flow. */
596
+ source: TokenSourceKind;
597
+ }
598
+
599
+ /**
600
+ * Dispatcher. Resolves the partner token according to
601
+ * `descriptor.tokenSource`. Returns a Promise so async-only sources
602
+ * (`postmsg`, `global`) share the same surface as synchronous ones.
603
+ *
604
+ * Throws when the token can't be found — callers decide whether to
605
+ * fall back to a login screen (per `descriptor.fallback`).
606
+ */
607
+ export declare function discoverToken(opts: TokenDiscoveryOptions): Promise<DiscoveredToken>;
608
+
539
609
  export declare interface EditEntityAction {
540
610
  action: 'edit_entity';
541
611
  entity_type: string;
@@ -734,8 +804,25 @@ export declare interface FormRegistration {
734
804
  getCurrentValues: () => Record<string, unknown>;
735
805
  }
736
806
 
807
+ export declare interface GlobalSourceConfig {
808
+ /** Dot-path into `window` (e.g. `"PartnerSDK.session.token"`). */
809
+ path?: string;
810
+ /** Max poll time in ms (default 2000). */
811
+ timeoutMs?: number;
812
+ /** Poll interval in ms (default 100). */
813
+ intervalMs?: number;
814
+ }
815
+
816
+ export declare interface HashSourceConfig {
817
+ /** Hash key (after `#…&key=value&…`). Default `"token"`. */
818
+ key?: string;
819
+ }
820
+
737
821
  export declare function inferTiledeskRole(message: TiledeskMessage, cfg: TiledeskRoleConfig): TiledeskRole;
738
822
 
823
+ export declare interface InitSourceConfig {
824
+ }
825
+
739
826
  /**
740
827
  * Self-echo detector — Tiledesk fans the user's outgoing publish back
741
828
  * as a `clientadded` event on the same connection. UI must dedupe against
@@ -899,6 +986,21 @@ declare interface NavigateAction_2 {
899
986
 
900
987
  export declare function parseTiledeskTemplate(message: TiledeskMessage): TiledeskParsedTemplate;
901
988
 
989
+ export declare interface PostMsgSourceConfig {
990
+ /** Message envelope `type` field that gates which postMessage we accept. */
991
+ type?: string;
992
+ /** Property inside `event.data` carrying the token. Default `"token"`. */
993
+ key?: string;
994
+ /**
995
+ * Allowed origins (comma-separated or single string). When set, messages
996
+ * from any other origin are ignored. When unset every origin is accepted
997
+ * — partners are encouraged to set this in production.
998
+ */
999
+ origins?: string;
1000
+ /** Milliseconds to wait before rejecting. Default 30_000. */
1001
+ timeoutMs?: number;
1002
+ }
1003
+
902
1004
  /**
903
1005
  * One HTTP call run by the SDK before auth. Failure of `soft: true` steps
904
1006
  * is logged and ignored; failure of strict steps aborts the mount.
@@ -948,6 +1050,66 @@ export declare interface Presigned3StepAdapterConfig {
948
1050
  extraHeaders?: Record<string, string>;
949
1051
  }
950
1052
 
1053
+ export declare interface QuerySourceConfig {
1054
+ /** Query-string parameter name. Default `"token"`. */
1055
+ key?: string;
1056
+ }
1057
+
1058
+ /**
1059
+ * One slot's component pointer. The `kind` discriminator picks which
1060
+ * loader runs. Both kinds resolve to a `Promise<HTMLElement>` after load,
1061
+ * which the runtime appends into the slot anchor.
1062
+ */
1063
+ export declare type RemoteComponent = {
1064
+ kind: 'iife-element';
1065
+ /** URL of an IIFE bundle that calls `customElements.define(tag, …)`. */
1066
+ scriptUrl: string;
1067
+ /** Custom-element tag the bundle registers. */
1068
+ tag: string;
1069
+ /** Optional method-call map: `{ setLayout: "stacked" }` becomes
1070
+ * `el.setLayout("stacked")` after mount. */
1071
+ props?: Record<string, unknown>;
1072
+ } | {
1073
+ kind: 'remote-dom';
1074
+ /** URL of an IIFE bundle that, when executed, leaves a global at
1075
+ * `globalName` exposing `mount({ target, ctx, complete, props })`.
1076
+ * Authored via `@aikaara/chat-sdk/remote-author`. */
1077
+ scriptUrl: string;
1078
+ /** Optional global name; defaults to the slot id with non-alphanumeric
1079
+ * chars replaced by underscores (e.g. "screen:login" → "screen_login"). */
1080
+ globalName?: string;
1081
+ /** Sandbox kind. Today only `iframe`; `worker` reserved for later. */
1082
+ sandbox?: 'iframe' | 'worker';
1083
+ /** Forwarded to the bundle's `mount({ props })` call. */
1084
+ props?: Record<string, unknown>;
1085
+ };
1086
+
1087
+ /**
1088
+ * One route in `descriptor.app.routes`.
1089
+ *
1090
+ * `path` is matched against the URL pathname AFTER the tenant's slug
1091
+ * prefix is stripped (in subpath mode). Supports trailing wildcards (`/*`)
1092
+ * and named params (`/:id`) — the parser is intentionally tiny.
1093
+ *
1094
+ * `component` references a slot in `descriptor.components`.
1095
+ *
1096
+ * `guards` are simple predicate names the shell evaluates against runtime
1097
+ * session state. Today: `'sso'` (SSO exchange done), `'authed'` (user
1098
+ * has any session), `'panVerified'` (PAN flow finished). Tenants can
1099
+ * extend by exposing flags via `complete(payload)` from preceding screens.
1100
+ *
1101
+ * `redirectIfFails` lets a guard send the user to another route id
1102
+ * instead of erroring. Useful for `'authed'` failing → redirect to login.
1103
+ */
1104
+ export declare interface RouteDef {
1105
+ path: string;
1106
+ component: string;
1107
+ guards?: string[];
1108
+ redirectIfFails?: string;
1109
+ /** Optional layout slot wrapping this route's component. */
1110
+ layout?: string;
1111
+ }
1112
+
951
1113
  export declare interface SaveEntityAction {
952
1114
  action: 'save_entity';
953
1115
  }
@@ -1014,6 +1176,41 @@ export declare interface SessionAuthDescriptor {
1014
1176
 
1015
1177
  export declare type SessionTokenProvider = string | (() => string | Promise<string>);
1016
1178
 
1179
+ export declare interface SidePanelDef {
1180
+ enabled?: boolean;
1181
+ type: SidePanelType;
1182
+ title?: string;
1183
+ mobile?: SidePanelMobile;
1184
+ steps?: Array<{
1185
+ name: string;
1186
+ hint?: string;
1187
+ }>;
1188
+ emptyText?: string;
1189
+ allowUpload?: boolean;
1190
+ summaryFields?: string[];
1191
+ supportPhone?: string;
1192
+ supportHours?: string;
1193
+ showHumanHandoff?: boolean;
1194
+ source?: ApiPanelSource;
1195
+ endpoint?: string;
1196
+ sampleJson?: string;
1197
+ refresh?: ApiPanelRefresh;
1198
+ intervalSec?: number;
1199
+ render?: ApiPanelRender;
1200
+ fields?: Array<{
1201
+ label: string;
1202
+ path: string;
1203
+ format?: ApiPanelFieldFormat;
1204
+ }>;
1205
+ stepsPath?: string;
1206
+ stepStatusKey?: string;
1207
+ customUrl?: string;
1208
+ }
1209
+
1210
+ export declare type SidePanelMobile = 'drawer' | 'hidden';
1211
+
1212
+ export declare type SidePanelType = 'steps' | 'files' | 'summary' | 'support' | 'api' | 'custom';
1213
+
1017
1214
  export declare interface SlugMountedWidget extends MountedTenantWidget {
1018
1215
  fullName: string;
1019
1216
  /** Resolved descriptor (fallback ⊕ fetched ⊕ overrides). Host reads
@@ -1021,6 +1218,13 @@ export declare interface SlugMountedWidget extends MountedTenantWidget {
1021
1218
  descriptor: WidgetConfigDescriptor;
1022
1219
  /** Force a fresh /chatbuddy/auth-style refetch (clears cached requestId). */
1023
1220
  refreshAuth(): Promise<void>;
1221
+ /**
1222
+ * Re-discover the partner token (per `descriptor.sso.tokenSource`) and
1223
+ * re-exchange for a fresh chat JWT. Returns the new bearer or null when
1224
+ * discovery fails. Only available when `descriptor.sso.autoRefresh` is
1225
+ * `true`; returns `null` immediately otherwise.
1226
+ */
1227
+ refreshPartnerAuth(): Promise<string | null>;
1024
1228
  }
1025
1229
 
1026
1230
  export declare interface SlugMountOptions {
@@ -1064,6 +1268,13 @@ export declare interface SlugMountOptions {
1064
1268
  * without host code per call.
1065
1269
  */
1066
1270
  identity?: Record<string, string | undefined>;
1271
+ /**
1272
+ * Partner token supplied directly by the embedding host. Used by
1273
+ * `descriptor.sso.tokenSource === "init"` (v2 sign-in flow) — every
1274
+ * other source kind discovers the token from the page itself
1275
+ * (query / hash / cookie / storage / postMessage / global).
1276
+ */
1277
+ partnerToken?: string;
1067
1278
  };
1068
1279
  /** Optional escape hatches; merge over descriptor-driven defaults. */
1069
1280
  hooks?: {
@@ -1124,8 +1335,37 @@ export declare interface SsoDescriptor {
1124
1335
  apiKey?: string;
1125
1336
  /** Extra static headers attached to the exchange POST. */
1126
1337
  headers?: Record<string, string>;
1127
- /** Browser credential collection spec. */
1128
- collect: SsoCollectSpec[];
1338
+ /**
1339
+ * Legacy v1 shape — explicit list of credential sources the browser
1340
+ * reads + posts to the exchange endpoint. Still supported for the
1341
+ * bandhan-itr / myfinancials cohort that shipped before the v2
1342
+ * sign-in tab. Mutually exclusive with `tokenSource` (v2).
1343
+ */
1344
+ collect?: SsoCollectSpec[];
1345
+ /** Provider family. `"partner"` is the only value today. */
1346
+ provider?: string;
1347
+ /** Recipe id paired with this descriptor (e.g. `partner_token_to_backend_jwt`). */
1348
+ flow?: string;
1349
+ /** Skip the login screen entirely — read token, exchange, mount chat. */
1350
+ skipLogin?: boolean;
1351
+ /** Re-read the token source on any request that 401s. */
1352
+ autoRefresh?: boolean;
1353
+ /** Selects which token reader runs at boot. */
1354
+ tokenSource?: TokenSourceKind;
1355
+ /** Per-source config (only the matching block is emitted by the dashboard). */
1356
+ tokenSourceConfig?: TokenSourceConfig;
1357
+ /** What to do when token-discovery fails — show a fallback screen. */
1358
+ fallback?: {
1359
+ enabled?: boolean;
1360
+ method?: 'phone' | 'email';
1361
+ };
1362
+ /** Dot-paths into the partner identity payload returned by `auth`. */
1363
+ map?: {
1364
+ id?: string;
1365
+ email?: string;
1366
+ name?: string;
1367
+ phone?: string;
1368
+ };
1129
1369
  }
1130
1370
 
1131
1371
  export declare class SsoExchangeAdapter {
@@ -1185,6 +1425,15 @@ export declare interface SsoIdentity {
1185
1425
  */
1186
1426
  export declare type SsoSourceKind = 'cookie' | 'localStorage' | 'sessionStorage' | 'url_param' | 'header_meta' | 'callback';
1187
1427
 
1428
+ export declare interface StorageSourceConfig {
1429
+ /** `"local"` (default) or `"session"`. */
1430
+ store?: 'local' | 'session';
1431
+ /** Storage key. */
1432
+ key?: string;
1433
+ /** Optional dot-path. When set the value is JSON.parsed and walked. */
1434
+ path?: string;
1435
+ }
1436
+
1188
1437
  declare type SubscriptionCallback = (data: unknown) => void;
1189
1438
 
1190
1439
  declare interface TemplateMessageEvent {
@@ -1573,6 +1822,102 @@ declare interface TiledeskTransportConfig_2 {
1573
1822
  debug?: boolean;
1574
1823
  }
1575
1824
 
1825
+ export declare interface TokenDiscoveryDescriptor {
1826
+ /** `"partner"` today; reserved for future SSO families. */
1827
+ provider?: string;
1828
+ /** Recipe id the backend pairs with this descriptor. */
1829
+ flow?: string;
1830
+ /** When true the embedded SDK skips the login UI entirely. */
1831
+ skipLogin?: boolean;
1832
+ /** When true the SDK re-reads the source on 401 retries. */
1833
+ autoRefresh?: boolean;
1834
+ /** One of the seven supported source kinds. */
1835
+ tokenSource: TokenSourceKind;
1836
+ /** Source-specific config; only the matching block is read. */
1837
+ tokenSourceConfig?: TokenSourceConfig;
1838
+ /** Fallback (e.g. show a phone OTP screen) when discovery fails. */
1839
+ fallback?: {
1840
+ enabled?: boolean;
1841
+ method?: 'phone' | 'email';
1842
+ };
1843
+ /** Dot-paths into the partner identity payload returned by the auth call. */
1844
+ map?: {
1845
+ id?: string;
1846
+ email?: string;
1847
+ name?: string;
1848
+ phone?: string;
1849
+ };
1850
+ }
1851
+
1852
+ export declare class TokenDiscoveryError extends Error {
1853
+ readonly source: string;
1854
+ constructor(source: string, msg: string);
1855
+ }
1856
+
1857
+ export declare interface TokenDiscoveryOptions {
1858
+ /** Descriptor from `widget_configs/:slug` (`configurations.sso`). */
1859
+ descriptor: TokenDiscoveryDescriptor;
1860
+ /**
1861
+ * Initial token explicitly passed to the SDK by the parent caller. Used
1862
+ * by the `init` source kind; ignored by every other.
1863
+ */
1864
+ initToken?: string;
1865
+ }
1866
+
1867
+ /**
1868
+ * Thin wrapper that re-runs `discoverToken` on demand. Used by
1869
+ * `ApiClient` when a request 401s and `descriptor.sso.autoRefresh` is set.
1870
+ *
1871
+ * The first call caches the token; `.refresh()` forces a re-read of the
1872
+ * source. `init` mode can't be refreshed (the partner already gave us the
1873
+ * single token) — callers should fall through to fallback there.
1874
+ */
1875
+ export declare class TokenDiscoveryReader {
1876
+ private readonly opts;
1877
+ private cached;
1878
+ constructor(opts: TokenDiscoveryOptions);
1879
+ get descriptor(): TokenDiscoveryDescriptor;
1880
+ /** Resolve the token. Returns cache if present. */
1881
+ get(): Promise<DiscoveredToken>;
1882
+ /**
1883
+ * Re-evaluate the source. For `init` mode (where the SDK has no way to
1884
+ * re-read) this returns the cached token unchanged — callers should
1885
+ * treat repeated 401s after a refresh attempt as terminal.
1886
+ */
1887
+ refresh(): Promise<DiscoveredToken>;
1888
+ }
1889
+
1890
+ export declare type TokenSourceConfig = InitSourceConfig | QuerySourceConfig | HashSourceConfig | PostMsgSourceConfig | CookieSourceConfig | StorageSourceConfig | GlobalSourceConfig;
1891
+
1892
+ /**
1893
+ * Partner-token discovery dispatcher (v2 sign-in flow).
1894
+ *
1895
+ * The dashboard's Sign-in tab writes a `descriptor.sso` block that names
1896
+ * one of seven token-source modes plus a per-mode config block. At runtime
1897
+ * the SDK reads the descriptor, dispatches to the matching reader, and
1898
+ * returns the raw partner token. When `descriptor.sso.skipLogin === true`
1899
+ * the host shell uses the token directly to do the auth exchange; when
1900
+ * `descriptor.sso.autoRefresh === true` the reader is re-evaluated on any
1901
+ * request that returned 401 (see {@link ApiClient}).
1902
+ *
1903
+ * Reading flows:
1904
+ * - `init` — supplied at construction (e.g. `Aikaara.init({token})`).
1905
+ * - `query` — `URLSearchParams(location.search).get(cfg.key)`.
1906
+ * - `hash` — `location.hash` parsed as URLSearchParams; cfg.key wins.
1907
+ * - `postmsg` — `window.addEventListener('message')` filtered by
1908
+ * `cfg.type` + `cfg.key`; origins allowlist optional.
1909
+ * - `cookie` — `document.cookie` parsed; domain scope is informational
1910
+ * (browser already enforces it for the running page).
1911
+ * - `storage` — `(localStorage|sessionStorage).getItem(cfg.key)`; when
1912
+ * `cfg.path` is set, parsed as JSON + dot-path resolved.
1913
+ * - `global` — `window[cfg.path]` resolved via dot-path; polled for
1914
+ * up to 2 seconds for late-loading partner SDKs.
1915
+ *
1916
+ * The dispatcher is intentionally side-effect-free apart from
1917
+ * `postmsg` (which has to attach a listener). Callers control caching.
1918
+ */
1919
+ export declare type TokenSourceKind = 'init' | 'query' | 'hash' | 'postmsg' | 'cookie' | 'storage' | 'global';
1920
+
1576
1921
  export declare interface ToolCall {
1577
1922
  id: string;
1578
1923
  type: 'function';
@@ -1892,6 +2237,65 @@ export declare interface WidgetConfigDescriptor {
1892
2237
  scriptUrl?: string;
1893
2238
  props?: Record<string, unknown>;
1894
2239
  }>;
2240
+ /**
2241
+ * Multi-screen app definition. When present, the hosted-shell renders a
2242
+ * History-API router rooted at the tenant's mount path. Each route
2243
+ * names a slot key that resolves to a `components[slot]` entry.
2244
+ *
2245
+ * When absent, behaviour is the today's single-screen mount (chat
2246
+ * widget at root). No breaking change for existing tenants.
2247
+ */
2248
+ app?: {
2249
+ /** Route id rendered when path matches `/` (or `/<slug>/` in subpath). */
2250
+ defaultRoute: string;
2251
+ /** Map of route id → definition. */
2252
+ routes: Record<string, RouteDef>;
2253
+ /**
2254
+ * Static page list rendered by the hosted-shell's top/bottom nav. The
2255
+ * dashboard's App Layout tab writes this; the SDK doesn't read it.
2256
+ * Surfaced here so descriptor consumers get a typed view.
2257
+ */
2258
+ pages?: AppPageDef[];
2259
+ /** Side panels wrapping the chat — see {@link SidePanelDef}. */
2260
+ panels?: {
2261
+ left?: SidePanelDef;
2262
+ right?: SidePanelDef;
2263
+ };
2264
+ };
2265
+ /**
2266
+ * Tenant-side API config consumed by the side-panel runtime. Right now
2267
+ * only the `api`-type panel uses this — it prefixes `panel.endpoint`
2268
+ * with `api.baseUrl` and sends the chat JWT as `Authorization`. Other
2269
+ * descriptor blocks (`upload`, `historyApiBase`, etc.) keep their own
2270
+ * fields for backwards compatibility.
2271
+ */
2272
+ api?: {
2273
+ /** Absolute base URL for tenant API calls. No trailing slash. */
2274
+ baseUrl?: string;
2275
+ };
2276
+ /**
2277
+ * Unified slot map. Supersedes `templates` and the bespoke
2278
+ * `linkHandlers[].render` mechanism. Each key is a slot id that some
2279
+ * piece of the runtime knows to look up:
2280
+ *
2281
+ * "template:<contentTypeOrTemplateId>" — Tiledesk contentType=300 templates
2282
+ * "screen:login" | "screen:prechat" | "screen:chat" | … — full screens
2283
+ * "panel:header" | "panel:left-rail" | … — chat-shell side panels
2284
+ * "viewer:file" | "viewer:compare-plans" | … — link-modal renderers
2285
+ *
2286
+ * Two component kinds today:
2287
+ * - `iife-element` : tenant ships an IIFE that calls customElements.define;
2288
+ * SDK loads the script + creates `<tag>` and dispatches.
2289
+ * - `remote-dom` : tenant ships a remote-dom bundle (React/Preact/Svelte
2290
+ * JSX); SDK lazy-loads `@aikaara/chat-sdk/remote-host`,
2291
+ * creates a hidden iframe with DOMRemoteReceiver, and
2292
+ * mirrors the tenant's tree into the host slot.
2293
+ *
2294
+ * Backwards compat: at mount time, every entry in `templates` is mirrored
2295
+ * into `components['template:'+id]` as kind:'iife-element' if a matching
2296
+ * key isn't already present. Tenants on the old shape see no change.
2297
+ */
2298
+ components?: Record<string, RemoteComponent>;
1895
2299
  }
1896
2300
 
1897
2301
  /**
package/dist/headless.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { E as s } from "./MountTenant-BVimPLfY.mjs";
2
- import { A as p, b as l, k as g, C as h, l as c, m as y, M as u, S as m, n as f, T as S, o as T, p as _, q as E, s as v, t as C, u as F, v as A, w as k, x as I, y as x, z as U } from "./MountTenant-BVimPLfY.mjs";
1
+ import { E as s } from "./MountTenant-CxO7hJgs.mjs";
2
+ import { A as p, b as l, k as g, C as c, l as h, m as y, M as u, S as m, n as f, T, o as S, p as _, q as v, s as E, t as C, u as F, v as k, w as A, x as I, y as x, z as U, B as q, D as M, F as b } from "./MountTenant-CxO7hJgs.mjs";
3
3
  class a extends s {
4
4
  registration = null;
5
5
  pendingEdits = [];
@@ -96,24 +96,27 @@ export {
96
96
  p as ActionCableClient,
97
97
  l as AikaaraChatClient,
98
98
  g as ApiClient,
99
- h as ChannelSubscription,
100
- c as ConnectionManager,
99
+ c as ChannelSubscription,
100
+ h as ConnectionManager,
101
101
  y as ConversationManager,
102
102
  s as EventEmitter,
103
103
  a as FormBridge,
104
104
  u as MessageStore,
105
105
  m as SessionAuthAdapter,
106
106
  f as SsoExchangeAdapter,
107
- S as TiledeskTransport,
108
- T as clearPersistedConversationId,
109
- _ as collectSsoCredentials,
110
- E as createFetchUploadAdapter,
111
- v as createPresigned3StepUploadAdapter,
112
- C as createTiledeskHistoryAdapter,
113
- F as extractTiledeskFileEnvelope,
114
- A as inferTiledeskRole,
115
- k as isTiledeskSelfEcho,
116
- I as mountFromSlug,
117
- x as mountTenantWidget,
118
- U as parseTiledeskTemplate
107
+ T as TiledeskTransport,
108
+ S as TokenDiscoveryError,
109
+ _ as TokenDiscoveryReader,
110
+ v as clearPersistedConversationId,
111
+ E as collectSsoCredentials,
112
+ C as createFetchUploadAdapter,
113
+ F as createPresigned3StepUploadAdapter,
114
+ k as createTiledeskHistoryAdapter,
115
+ A as discoverToken,
116
+ I as extractTiledeskFileEnvelope,
117
+ x as inferTiledeskRole,
118
+ U as isTiledeskSelfEcho,
119
+ q as mountFromSlug,
120
+ M as mountTenantWidget,
121
+ b as parseTiledeskTemplate
119
122
  };
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./MountTenant-BrBxPpjb.cjs"),s=require("./headless.cjs");function l(a){e.registerComponents();const t=document.createElement("aikaara-chat-widget"),i={baseUrl:"base-url",userToken:"user-token",apiKey:"api-key",title:"title",subtitle:"subtitle",theme:"theme",primaryColor:"primary-color",position:"position",width:"width",height:"height",placeholder:"placeholder",welcomeMessage:"welcome-message",avatarUrl:"avatar-url"};for(const[n,o]of Object.entries(i)){const r=a[n];r!=null&&t.setAttribute(o,String(r))}return t.configure(a),document.body.appendChild(t),t}function d(){const a=document.querySelector("aikaara-chat-widget");a&&a.remove()}exports.ActionCableClient=e.ActionCableClient;exports.AikaaraChatBubble=e.AikaaraChatBubble;exports.AikaaraChatClient=e.AikaaraChatClient;exports.AikaaraChatHeader=e.AikaaraChatHeader;exports.AikaaraChatInput=e.AikaaraChatInput;exports.AikaaraChatWidget=e.AikaaraChatWidget;exports.AikaaraErrorBanner=e.AikaaraErrorBanner;exports.AikaaraMessageBubble=e.AikaaraMessageBubble;exports.AikaaraMessageList=e.AikaaraMessageList;exports.AikaaraStreamingMessage=e.AikaaraStreamingMessage;exports.AikaaraTypingIndicator=e.AikaaraTypingIndicator;exports.ApiClient=e.ApiClient;exports.ChannelSubscription=e.ChannelSubscription;exports.ConnectionManager=e.ConnectionManager;exports.ConversationManager=e.ConversationManager;exports.EventEmitter=e.EventEmitter;exports.MessageStore=e.MessageStore;exports.SessionAuthAdapter=e.SessionAuthAdapter;exports.SsoExchangeAdapter=e.SsoExchangeAdapter;exports.TiledeskTransport=e.TiledeskTransport;exports.clearPersistedConversationId=e.clearPersistedConversationId;exports.collectSsoCredentials=e.collectSsoCredentials;exports.createFetchUploadAdapter=e.createFetchUploadAdapter;exports.createPresigned3StepUploadAdapter=e.createPresigned3StepUploadAdapter;exports.createTiledeskHistoryAdapter=e.createTiledeskHistoryAdapter;exports.extractTiledeskFileEnvelope=e.extractTiledeskFileEnvelope;exports.inferTiledeskRole=e.inferTiledeskRole;exports.isTiledeskSelfEcho=e.isTiledeskSelfEcho;exports.mountFromSlug=e.mountFromSlug;exports.mountTenantWidget=e.mount;exports.parseTiledeskTemplate=e.parseTiledeskTemplate;exports.registerComponents=e.registerComponents;exports.FormBridge=s.FormBridge;exports.mount=l;exports.unmount=d;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./MountTenant-BCjKRkD8.cjs"),s=require("./headless.cjs");function l(a){e.registerComponents();const t=document.createElement("aikaara-chat-widget"),i={baseUrl:"base-url",userToken:"user-token",apiKey:"api-key",title:"title",subtitle:"subtitle",theme:"theme",primaryColor:"primary-color",position:"position",width:"width",height:"height",placeholder:"placeholder",welcomeMessage:"welcome-message",avatarUrl:"avatar-url"};for(const[o,n]of Object.entries(i)){const r=a[o];r!=null&&t.setAttribute(n,String(r))}return t.configure(a),document.body.appendChild(t),t}function d(){const a=document.querySelector("aikaara-chat-widget");a&&a.remove()}exports.ActionCableClient=e.ActionCableClient;exports.AikaaraChatBubble=e.AikaaraChatBubble;exports.AikaaraChatClient=e.AikaaraChatClient;exports.AikaaraChatHeader=e.AikaaraChatHeader;exports.AikaaraChatInput=e.AikaaraChatInput;exports.AikaaraChatWidget=e.AikaaraChatWidget;exports.AikaaraErrorBanner=e.AikaaraErrorBanner;exports.AikaaraMessageBubble=e.AikaaraMessageBubble;exports.AikaaraMessageList=e.AikaaraMessageList;exports.AikaaraStreamingMessage=e.AikaaraStreamingMessage;exports.AikaaraTypingIndicator=e.AikaaraTypingIndicator;exports.ApiClient=e.ApiClient;exports.ChannelSubscription=e.ChannelSubscription;exports.ConnectionManager=e.ConnectionManager;exports.ConversationManager=e.ConversationManager;exports.EventEmitter=e.EventEmitter;exports.MessageStore=e.MessageStore;exports.SessionAuthAdapter=e.SessionAuthAdapter;exports.SsoExchangeAdapter=e.SsoExchangeAdapter;exports.TiledeskTransport=e.TiledeskTransport;exports.TokenDiscoveryError=e.TokenDiscoveryError;exports.TokenDiscoveryReader=e.TokenDiscoveryReader;exports.clearPersistedConversationId=e.clearPersistedConversationId;exports.collectSsoCredentials=e.collectSsoCredentials;exports.createFetchUploadAdapter=e.createFetchUploadAdapter;exports.createPresigned3StepUploadAdapter=e.createPresigned3StepUploadAdapter;exports.createTiledeskHistoryAdapter=e.createTiledeskHistoryAdapter;exports.discoverToken=e.discoverToken;exports.extractTiledeskFileEnvelope=e.extractTiledeskFileEnvelope;exports.inferTiledeskRole=e.inferTiledeskRole;exports.isTiledeskSelfEcho=e.isTiledeskSelfEcho;exports.mountFromSlug=e.mountFromSlug;exports.mountTenantWidget=e.mount;exports.parseTiledeskTemplate=e.parseTiledeskTemplate;exports.registerComponents=e.registerComponents;exports.FormBridge=s.FormBridge;exports.mount=l;exports.unmount=d;