@aikaara/chat-sdk 0.8.0 → 0.8.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/headless.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("./MountTenant-DHxy8WY9.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 i=require("./MountTenant-DvmiAoZ_.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;
@@ -222,7 +222,7 @@ export declare class ApiClient {
222
222
  private baseUrl;
223
223
  private apiKey?;
224
224
  private authToken?;
225
- private userToken;
225
+ protected userToken: string;
226
226
  constructor(baseUrl: string, userToken: string, apiKey?: string, authToken?: string);
227
227
  createConversation(params: {
228
228
  systemPromptId?: number;
@@ -948,6 +948,61 @@ export declare interface Presigned3StepAdapterConfig {
948
948
  extraHeaders?: Record<string, string>;
949
949
  }
950
950
 
951
+ /**
952
+ * One slot's component pointer. The `kind` discriminator picks which
953
+ * loader runs. Both kinds resolve to a `Promise<HTMLElement>` after load,
954
+ * which the runtime appends into the slot anchor.
955
+ */
956
+ declare type RemoteComponent = {
957
+ kind: 'iife-element';
958
+ /** URL of an IIFE bundle that calls `customElements.define(tag, …)`. */
959
+ scriptUrl: string;
960
+ /** Custom-element tag the bundle registers. */
961
+ tag: string;
962
+ /** Optional method-call map: `{ setLayout: "stacked" }` becomes
963
+ * `el.setLayout("stacked")` after mount. */
964
+ props?: Record<string, unknown>;
965
+ } | {
966
+ kind: 'remote-dom';
967
+ /** URL of an IIFE bundle that, when executed, leaves a global at
968
+ * `globalName` exposing `mount({ target, ctx, complete, props })`.
969
+ * Authored via `@aikaara/chat-sdk/remote-author`. */
970
+ scriptUrl: string;
971
+ /** Optional global name; defaults to the slot id with non-alphanumeric
972
+ * chars replaced by underscores (e.g. "screen:login" → "screen_login"). */
973
+ globalName?: string;
974
+ /** Sandbox kind. Today only `iframe`; `worker` reserved for later. */
975
+ sandbox?: 'iframe' | 'worker';
976
+ /** Forwarded to the bundle's `mount({ props })` call. */
977
+ props?: Record<string, unknown>;
978
+ };
979
+
980
+ /**
981
+ * One route in `descriptor.app.routes`.
982
+ *
983
+ * `path` is matched against the URL pathname AFTER the tenant's slug
984
+ * prefix is stripped (in subpath mode). Supports trailing wildcards (`/*`)
985
+ * and named params (`/:id`) — the parser is intentionally tiny.
986
+ *
987
+ * `component` references a slot in `descriptor.components`.
988
+ *
989
+ * `guards` are simple predicate names the shell evaluates against runtime
990
+ * session state. Today: `'sso'` (SSO exchange done), `'authed'` (user
991
+ * has any session), `'panVerified'` (PAN flow finished). Tenants can
992
+ * extend by exposing flags via `complete(payload)` from preceding screens.
993
+ *
994
+ * `redirectIfFails` lets a guard send the user to another route id
995
+ * instead of erroring. Useful for `'authed'` failing → redirect to login.
996
+ */
997
+ declare interface RouteDef {
998
+ path: string;
999
+ component: string;
1000
+ guards?: string[];
1001
+ redirectIfFails?: string;
1002
+ /** Optional layout slot wrapping this route's component. */
1003
+ layout?: string;
1004
+ }
1005
+
951
1006
  export declare interface SaveEntityAction {
952
1007
  action: 'save_entity';
953
1008
  }
@@ -1685,6 +1740,7 @@ export declare interface WidgetConfig extends ChatClientConfig {
1685
1740
  attachPosition?: 'left' | 'right';
1686
1741
  sendButtonShape?: 'circle' | 'square';
1687
1742
  };
1743
+ templateLayout?: 'inside' | 'outside';
1688
1744
  showBubble?: boolean;
1689
1745
  bubbleText?: string;
1690
1746
  bubbleIcon?: string;
@@ -1745,6 +1801,17 @@ export declare interface WidgetConfigDescriptor {
1745
1801
  /** Round (default) or filled square send button. */
1746
1802
  sendButtonShape?: 'circle' | 'square';
1747
1803
  };
1804
+ /**
1805
+ * Where contentType=300 templates render relative to the bubble carrying
1806
+ * the message text.
1807
+ * - `inside` (default): template UI nested inside the bot bubble — the
1808
+ * option chips share the bubble's background colour. Matches the
1809
+ * pre-bandhan look.
1810
+ * - `outside`: template UI is a sibling below the bubble (UAT bandhan
1811
+ * style). Lets option chips inherit the chat surface background and
1812
+ * wrap freely, no max-width clamp.
1813
+ */
1814
+ templateLayout?: 'inside' | 'outside';
1748
1815
  /**
1749
1816
  * Full theme token set. Mirrored as CSS variables (`--aikaara-*`) on the
1750
1817
  * widget root so any inner web-component can style itself by referencing
@@ -1880,6 +1947,43 @@ export declare interface WidgetConfigDescriptor {
1880
1947
  scriptUrl?: string;
1881
1948
  props?: Record<string, unknown>;
1882
1949
  }>;
1950
+ /**
1951
+ * Multi-screen app definition. When present, the hosted-shell renders a
1952
+ * History-API router rooted at the tenant's mount path. Each route
1953
+ * names a slot key that resolves to a `components[slot]` entry.
1954
+ *
1955
+ * When absent, behaviour is the today's single-screen mount (chat
1956
+ * widget at root). No breaking change for existing tenants.
1957
+ */
1958
+ app?: {
1959
+ /** Route id rendered when path matches `/` (or `/<slug>/` in subpath). */
1960
+ defaultRoute: string;
1961
+ /** Map of route id → definition. */
1962
+ routes: Record<string, RouteDef>;
1963
+ };
1964
+ /**
1965
+ * Unified slot map. Supersedes `templates` and the bespoke
1966
+ * `linkHandlers[].render` mechanism. Each key is a slot id that some
1967
+ * piece of the runtime knows to look up:
1968
+ *
1969
+ * "template:<contentTypeOrTemplateId>" — Tiledesk contentType=300 templates
1970
+ * "screen:login" | "screen:prechat" | "screen:chat" | … — full screens
1971
+ * "panel:header" | "panel:left-rail" | … — chat-shell side panels
1972
+ * "viewer:file" | "viewer:compare-plans" | … — link-modal renderers
1973
+ *
1974
+ * Two component kinds today:
1975
+ * - `iife-element` : tenant ships an IIFE that calls customElements.define;
1976
+ * SDK loads the script + creates `<tag>` and dispatches.
1977
+ * - `remote-dom` : tenant ships a remote-dom bundle (React/Preact/Svelte
1978
+ * JSX); SDK lazy-loads `@aikaara/chat-sdk/remote-host`,
1979
+ * creates a hidden iframe with DOMRemoteReceiver, and
1980
+ * mirrors the tenant's tree into the host slot.
1981
+ *
1982
+ * Backwards compat: at mount time, every entry in `templates` is mirrored
1983
+ * into `components['template:'+id]` as kind:'iife-element' if a matching
1984
+ * key isn't already present. Tenants on the old shape see no change.
1985
+ */
1986
+ components?: Record<string, RemoteComponent>;
1883
1987
  }
1884
1988
 
1885
1989
  /**
package/dist/headless.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { E as s } from "./MountTenant-CdaBBA2O.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-CdaBBA2O.mjs";
1
+ import { E as s } from "./MountTenant-DzNgBTiU.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-DzNgBTiU.mjs";
3
3
  class a extends s {
4
4
  registration = null;
5
5
  pendingEdits = [];
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./MountTenant-DHxy8WY9.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-DvmiAoZ_.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;
package/dist/index.d.ts CHANGED
@@ -234,6 +234,8 @@ export declare class AikaaraMessageList extends HTMLElement {
234
234
  private getLinkBearer;
235
235
  setHideSystemMessages(items: string[]): void;
236
236
  setTimestampFormat(fmt: 'time' | 'datetime' | 'date' | 'none'): void;
237
+ private templateLayout;
238
+ setTemplateLayout(layout: 'inside' | 'outside'): void;
237
239
  /** Returns true when a message should be hidden by the descriptor's
238
240
  * `hideSystemMessages` filter. Matches the trimmed content
239
241
  * case-insensitively against any configured needle (substring match). */
@@ -290,7 +292,7 @@ export declare class ApiClient {
290
292
  private baseUrl;
291
293
  private apiKey?;
292
294
  private authToken?;
293
- private userToken;
295
+ protected userToken: string;
294
296
  constructor(baseUrl: string, userToken: string, apiKey?: string, authToken?: string);
295
297
  createConversation(params: {
296
298
  systemPromptId?: number;
@@ -851,6 +853,61 @@ export declare interface Presigned3StepAdapterConfig {
851
853
 
852
854
  export declare function registerComponents(): void;
853
855
 
856
+ /**
857
+ * One slot's component pointer. The `kind` discriminator picks which
858
+ * loader runs. Both kinds resolve to a `Promise<HTMLElement>` after load,
859
+ * which the runtime appends into the slot anchor.
860
+ */
861
+ declare type RemoteComponent = {
862
+ kind: 'iife-element';
863
+ /** URL of an IIFE bundle that calls `customElements.define(tag, …)`. */
864
+ scriptUrl: string;
865
+ /** Custom-element tag the bundle registers. */
866
+ tag: string;
867
+ /** Optional method-call map: `{ setLayout: "stacked" }` becomes
868
+ * `el.setLayout("stacked")` after mount. */
869
+ props?: Record<string, unknown>;
870
+ } | {
871
+ kind: 'remote-dom';
872
+ /** URL of an IIFE bundle that, when executed, leaves a global at
873
+ * `globalName` exposing `mount({ target, ctx, complete, props })`.
874
+ * Authored via `@aikaara/chat-sdk/remote-author`. */
875
+ scriptUrl: string;
876
+ /** Optional global name; defaults to the slot id with non-alphanumeric
877
+ * chars replaced by underscores (e.g. "screen:login" → "screen_login"). */
878
+ globalName?: string;
879
+ /** Sandbox kind. Today only `iframe`; `worker` reserved for later. */
880
+ sandbox?: 'iframe' | 'worker';
881
+ /** Forwarded to the bundle's `mount({ props })` call. */
882
+ props?: Record<string, unknown>;
883
+ };
884
+
885
+ /**
886
+ * One route in `descriptor.app.routes`.
887
+ *
888
+ * `path` is matched against the URL pathname AFTER the tenant's slug
889
+ * prefix is stripped (in subpath mode). Supports trailing wildcards (`/*`)
890
+ * and named params (`/:id`) — the parser is intentionally tiny.
891
+ *
892
+ * `component` references a slot in `descriptor.components`.
893
+ *
894
+ * `guards` are simple predicate names the shell evaluates against runtime
895
+ * session state. Today: `'sso'` (SSO exchange done), `'authed'` (user
896
+ * has any session), `'panVerified'` (PAN flow finished). Tenants can
897
+ * extend by exposing flags via `complete(payload)` from preceding screens.
898
+ *
899
+ * `redirectIfFails` lets a guard send the user to another route id
900
+ * instead of erroring. Useful for `'authed'` failing → redirect to login.
901
+ */
902
+ declare interface RouteDef {
903
+ path: string;
904
+ component: string;
905
+ guards?: string[];
906
+ redirectIfFails?: string;
907
+ /** Optional layout slot wrapping this route's component. */
908
+ layout?: string;
909
+ }
910
+
854
911
  export declare interface SaveEntityAction {
855
912
  action: 'save_entity';
856
913
  }
@@ -1445,6 +1502,7 @@ export declare interface WidgetConfig extends ChatClientConfig {
1445
1502
  attachPosition?: 'left' | 'right';
1446
1503
  sendButtonShape?: 'circle' | 'square';
1447
1504
  };
1505
+ templateLayout?: 'inside' | 'outside';
1448
1506
  showBubble?: boolean;
1449
1507
  bubbleText?: string;
1450
1508
  bubbleIcon?: string;
@@ -1505,6 +1563,17 @@ export declare interface WidgetConfigDescriptor {
1505
1563
  /** Round (default) or filled square send button. */
1506
1564
  sendButtonShape?: 'circle' | 'square';
1507
1565
  };
1566
+ /**
1567
+ * Where contentType=300 templates render relative to the bubble carrying
1568
+ * the message text.
1569
+ * - `inside` (default): template UI nested inside the bot bubble — the
1570
+ * option chips share the bubble's background colour. Matches the
1571
+ * pre-bandhan look.
1572
+ * - `outside`: template UI is a sibling below the bubble (UAT bandhan
1573
+ * style). Lets option chips inherit the chat surface background and
1574
+ * wrap freely, no max-width clamp.
1575
+ */
1576
+ templateLayout?: 'inside' | 'outside';
1508
1577
  /**
1509
1578
  * Full theme token set. Mirrored as CSS variables (`--aikaara-*`) on the
1510
1579
  * widget root so any inner web-component can style itself by referencing
@@ -1640,6 +1709,43 @@ export declare interface WidgetConfigDescriptor {
1640
1709
  scriptUrl?: string;
1641
1710
  props?: Record<string, unknown>;
1642
1711
  }>;
1712
+ /**
1713
+ * Multi-screen app definition. When present, the hosted-shell renders a
1714
+ * History-API router rooted at the tenant's mount path. Each route
1715
+ * names a slot key that resolves to a `components[slot]` entry.
1716
+ *
1717
+ * When absent, behaviour is the today's single-screen mount (chat
1718
+ * widget at root). No breaking change for existing tenants.
1719
+ */
1720
+ app?: {
1721
+ /** Route id rendered when path matches `/` (or `/<slug>/` in subpath). */
1722
+ defaultRoute: string;
1723
+ /** Map of route id → definition. */
1724
+ routes: Record<string, RouteDef>;
1725
+ };
1726
+ /**
1727
+ * Unified slot map. Supersedes `templates` and the bespoke
1728
+ * `linkHandlers[].render` mechanism. Each key is a slot id that some
1729
+ * piece of the runtime knows to look up:
1730
+ *
1731
+ * "template:<contentTypeOrTemplateId>" — Tiledesk contentType=300 templates
1732
+ * "screen:login" | "screen:prechat" | "screen:chat" | … — full screens
1733
+ * "panel:header" | "panel:left-rail" | … — chat-shell side panels
1734
+ * "viewer:file" | "viewer:compare-plans" | … — link-modal renderers
1735
+ *
1736
+ * Two component kinds today:
1737
+ * - `iife-element` : tenant ships an IIFE that calls customElements.define;
1738
+ * SDK loads the script + creates `<tag>` and dispatches.
1739
+ * - `remote-dom` : tenant ships a remote-dom bundle (React/Preact/Svelte
1740
+ * JSX); SDK lazy-loads `@aikaara/chat-sdk/remote-host`,
1741
+ * creates a hidden iframe with DOMRemoteReceiver, and
1742
+ * mirrors the tenant's tree into the host slot.
1743
+ *
1744
+ * Backwards compat: at mount time, every entry in `templates` is mirrored
1745
+ * into `components['template:'+id]` as kind:'iife-element' if a matching
1746
+ * key isn't already present. Tenants on the old shape see no change.
1747
+ */
1748
+ components?: Record<string, RemoteComponent>;
1643
1749
  }
1644
1750
 
1645
1751
  /**
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { r as o } from "./MountTenant-CdaBBA2O.mjs";
2
- import { A as u, a as m, b as g, c as h, d as k, e as A, f as C, g as b, h as f, i as S, j as T, k as v, C as y, l as w, m as M, E, M as x, S as B, n as F, T as U, o as I, p as j, q, s as H, t as P, u as W, v as z, w as K, x as L, y as O, z as R } from "./MountTenant-CdaBBA2O.mjs";
1
+ import { r as o } from "./MountTenant-DzNgBTiU.mjs";
2
+ import { A as u, a as m, b as g, c as h, d as k, e as A, f as C, g as b, h as f, i as S, j as T, k as v, C as y, l as w, m as M, E, M as x, S as B, n as F, T as U, o as I, p as j, q, s as H, t as P, u as W, v as z, w as K, x as L, y as O, z as R } from "./MountTenant-DzNgBTiU.mjs";
3
3
  import { FormBridge as G } from "./headless.mjs";
4
4
  function l(e) {
5
5
  o();
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=1;function p(s){let n=!1,t=null;const c=o=>{window.parent?.postMessage({aikaara:r,type:"complete",payload:o},"*")},i=o=>{window.parent?.postMessage({aikaara:r,type:"error",message:o},"*")};window.addEventListener("message",o=>{const e=o.data;!e||e.aikaara!==r||(e.type==="bootstrap"&&!n?(n=!0,t={target:document.body,ctx:e.ctx,props:e.props??{},complete:c,fail:i},Promise.resolve(s(t)).catch(a=>i(a?.message??String(a)))):e.type==="update"&&t&&(t={...t,props:{...t.props,...e.props}},Promise.resolve(s(t)).catch(a=>i(a?.message??String(a)))))}),window.parent?.postMessage({aikaara:r,type:"ready"},"*")}function d(s){p(s)}exports.initRemoteAuthor=p;exports.mount=d;
@@ -0,0 +1,62 @@
1
+ export declare interface AuthorMountArgs {
2
+ /** DOM node to render into — the iframe's `document.body`. */
3
+ target: HTMLElement;
4
+ /** Snapshot of host state at bootstrap time. */
5
+ ctx: RemoteAuthorContext | undefined;
6
+ /** Tenant-supplied props from `descriptor.components[slot].props`. */
7
+ props: Record<string, unknown>;
8
+ /** Signal flow completion. Host receives via its `onComplete` callback. */
9
+ complete: (payload: unknown) => void;
10
+ /** Surface a tenant error to the host. */
11
+ fail: (message: string) => void;
12
+ }
13
+
14
+ /**
15
+ * Wire up the host protocol and call `render` once bootstrap arrives.
16
+ * Subsequent host `update` messages re-invoke `render` so the bundle can
17
+ * re-render with new props (or just accept the changes if React-managed).
18
+ */
19
+ export declare function initRemoteAuthor(render: Renderer): void;
20
+
21
+ /** Convenience wrapper for the common "render once, ignore updates" case. */
22
+ export declare function mount(render: Renderer): void;
23
+
24
+ /**
25
+ * `@aikaara/chat-sdk/remote-author` — tiny tenant-side helper.
26
+ *
27
+ * Pull this into a tenant component bundle. The bundle, when loaded by the
28
+ * shell's RemoteComponentLoader (kind: 'remote-dom'), runs inside a
29
+ * sandboxed iframe. It needs to:
30
+ *
31
+ * 1. Tell the host it's ready.
32
+ * 2. Receive a `bootstrap` message carrying `ctx` + `props`.
33
+ * 3. Render whatever it wants into `document.body`.
34
+ * 4. Optionally call `complete(payload)` to signal the flow finished.
35
+ *
36
+ * This module wraps that protocol so tenants don't have to write
37
+ * postMessage boilerplate. They write a `mount(target, ctx, complete, props)`
38
+ * function (or just call `init(...)` with a render callback).
39
+ *
40
+ * Framework-agnostic: works with React, Preact, Svelte, Vue, vanilla JS.
41
+ *
42
+ * @example React
43
+ * import { initRemoteAuthor } from '@aikaara/chat-sdk/remote-author';
44
+ * import { createRoot } from 'react-dom/client';
45
+ * import LoginScreen from './LoginScreen';
46
+ *
47
+ * initRemoteAuthor(({ target, ctx, complete, props }) => {
48
+ * createRoot(target).render(
49
+ * <LoginScreen ctx={ctx} complete={complete} {...props} />
50
+ * );
51
+ * });
52
+ */
53
+ export declare interface RemoteAuthorContext {
54
+ slug: string;
55
+ theme?: Record<string, unknown>;
56
+ identity?: Record<string, unknown>;
57
+ extras?: Record<string, unknown>;
58
+ }
59
+
60
+ declare type Renderer = (args: AuthorMountArgs) => void | Promise<void>;
61
+
62
+ export { }
@@ -0,0 +1,31 @@
1
+ function n(s) {
2
+ let r = !1, t = null;
3
+ const i = (a) => {
4
+ window.parent?.postMessage(
5
+ { aikaara: 1, type: "complete", payload: a },
6
+ "*"
7
+ );
8
+ }, p = (a) => {
9
+ window.parent?.postMessage(
10
+ { aikaara: 1, type: "error", message: a },
11
+ "*"
12
+ );
13
+ };
14
+ window.addEventListener("message", (a) => {
15
+ const e = a.data;
16
+ !e || e.aikaara !== 1 || (e.type === "bootstrap" && !r ? (r = !0, t = {
17
+ target: document.body,
18
+ ctx: e.ctx,
19
+ props: e.props ?? {},
20
+ complete: i,
21
+ fail: p
22
+ }, Promise.resolve(s(t)).catch((o) => p(o?.message ?? String(o)))) : e.type === "update" && t && (t = { ...t, props: { ...t.props, ...e.props } }, Promise.resolve(s(t)).catch((o) => p(o?.message ?? String(o)))));
23
+ }), window.parent?.postMessage({ aikaara: 1, type: "ready" }, "*");
24
+ }
25
+ function O(s) {
26
+ n(s);
27
+ }
28
+ export {
29
+ n as initRemoteAuthor,
30
+ O as mount
31
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=new Map;async function d(e,r){switch(e.kind){case"iife-element":return p(e,r);case"remote-dom":return w(e,r);default:{const t=e;throw new Error(`loadRemoteComponent: unknown kind ${JSON.stringify(t)}`)}}}async function p(e,r){customElements.get(e.tag)||(await f(e.scriptUrl),await h(e.tag));const t=document.createElement(e.tag);return c(t,e.props),c(t,r.props),r.ctx&&c(t,{setCtx:r.ctx}),r.onComplete&&t.addEventListener("complete",n=>r.onComplete?.(n.detail)),r.onError&&t.addEventListener("error",n=>r.onError?.(n.error??new Error("component error"))),r.target.appendChild(t),{el:t,unmount(){t.remove()},update(n){c(t,n)}}}function c(e,r){if(r)for(const[t,n]of Object.entries(r)){const s=e[t];if(typeof s=="function")try{s.call(e,n)}catch(o){console.warn(`[RemoteComponentLoader] ${t}() threw`,o)}}}function f(e){const r=u.get(e);if(r)return r;const t=new Promise((n,s)=>{const o=document.createElement("script");o.src=e,o.async=!0,o.onload=()=>n(),o.onerror=()=>s(new Error(`Failed to load script ${e}`)),document.head.appendChild(o)});return u.set(e,t),t}function h(e,r=5e3){return customElements.get(e)?Promise.resolve():Promise.race([customElements.whenDefined(e).then(()=>{}),new Promise((t,n)=>{setTimeout(()=>n(new Error(`Custom element <${e}> never registered`)),r)})])}const l=1;function w(e,r){const t=document.createElement("iframe");t.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups"),t.style.cssText="width:100%;height:100%;border:0;display:block;background:transparent;",t.setAttribute("title",`aikaara-remote:${e.globalName??e.scriptUrl}`);const n=[],s=a=>t.contentWindow?.postMessage(a,"*");let o=!1;const m=a=>{if(a.source!==t.contentWindow)return;const i=a.data;!i||i.aikaara!==l||(i.type==="ready"?s({aikaara:l,type:"bootstrap",ctx:r.ctx,props:{...e.props??{},...r.props??{}}}):i.type==="complete"?r.onComplete?.(i.payload):i.type==="error"&&r.onError?.(new Error(i.message)))};return window.addEventListener("message",m),n.push(()=>window.removeEventListener("message",m)),t.srcdoc=`<!doctype html><html><head><meta charset="utf-8">
2
+ <style>html,body{margin:0;padding:0;height:100%;background:transparent;}</style>
3
+ </head><body><script src="${g(e.scriptUrl)}" defer><\/script></body></html>`,r.target.appendChild(t),{el:t,unmount(){if(!o){o=!0;for(const a of n)try{a()}catch{}t.remove()}},update(a){s({aikaara:l,type:"update",props:a})}}}function g(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;")}exports.loadRemoteComponent=d;
@@ -0,0 +1,68 @@
1
+ export declare interface LoadOptions {
2
+ /** Where the rendered element should be inserted. */
3
+ target: HTMLElement;
4
+ /** Forwarded to the tenant component. */
5
+ props?: Record<string, unknown>;
6
+ /** Forwarded as the `ctx` payload (read-only state from host). */
7
+ ctx?: RemoteHostContext;
8
+ /** Tenant components call this to signal a flow step finished
9
+ * (e.g. screen:login → onComplete({ext_uid, token})). */
10
+ onComplete?: (payload: unknown) => void;
11
+ /** Tenant component error → host can show a banner / fall back. */
12
+ onError?: (err: Error) => void;
13
+ }
14
+
15
+ /** Load + mount one slot's component. Returns a handle for tear-down. */
16
+ export declare function loadRemoteComponent(def: RemoteComponent, opts: LoadOptions): Promise<MountedComponent>;
17
+
18
+ export declare interface MountedComponent {
19
+ /** The DOM node added to `target` (custom element or iframe). */
20
+ el: HTMLElement;
21
+ /** Tear down + remove from DOM. Idempotent. */
22
+ unmount(): void;
23
+ /** Push a new `props` payload to the mounted component. */
24
+ update(props: Record<string, unknown>): void;
25
+ }
26
+
27
+ /**
28
+ * One slot's component pointer. The `kind` discriminator picks which
29
+ * loader runs. Both kinds resolve to a `Promise<HTMLElement>` after load,
30
+ * which the runtime appends into the slot anchor.
31
+ */
32
+ export declare type RemoteComponent = {
33
+ kind: 'iife-element';
34
+ /** URL of an IIFE bundle that calls `customElements.define(tag, …)`. */
35
+ scriptUrl: string;
36
+ /** Custom-element tag the bundle registers. */
37
+ tag: string;
38
+ /** Optional method-call map: `{ setLayout: "stacked" }` becomes
39
+ * `el.setLayout("stacked")` after mount. */
40
+ props?: Record<string, unknown>;
41
+ } | {
42
+ kind: 'remote-dom';
43
+ /** URL of an IIFE bundle that, when executed, leaves a global at
44
+ * `globalName` exposing `mount({ target, ctx, complete, props })`.
45
+ * Authored via `@aikaara/chat-sdk/remote-author`. */
46
+ scriptUrl: string;
47
+ /** Optional global name; defaults to the slot id with non-alphanumeric
48
+ * chars replaced by underscores (e.g. "screen:login" → "screen_login"). */
49
+ globalName?: string;
50
+ /** Sandbox kind. Today only `iframe`; `worker` reserved for later. */
51
+ sandbox?: 'iframe' | 'worker';
52
+ /** Forwarded to the bundle's `mount({ props })` call. */
53
+ props?: Record<string, unknown>;
54
+ };
55
+
56
+ export declare interface RemoteHostContext {
57
+ /** Project slug currently mounted. */
58
+ slug: string;
59
+ /** Theme tokens from descriptor.theme — passed for tenant components
60
+ * to render in-brand without re-fetching the descriptor. */
61
+ theme?: Record<string, unknown>;
62
+ /** Identity bag (already-resolved user info). */
63
+ identity?: Record<string, unknown>;
64
+ /** Free-form: descriptor block(s) the tenant component might need. */
65
+ extras?: Record<string, unknown>;
66
+ }
67
+
68
+ export { }
@@ -0,0 +1,104 @@
1
+ const u = /* @__PURE__ */ new Map();
2
+ async function g(e, r) {
3
+ switch (e.kind) {
4
+ case "iife-element":
5
+ return p(e, r);
6
+ case "remote-dom":
7
+ return h(e, r);
8
+ default: {
9
+ const t = e;
10
+ throw new Error(`loadRemoteComponent: unknown kind ${JSON.stringify(t)}`);
11
+ }
12
+ }
13
+ }
14
+ async function p(e, r) {
15
+ customElements.get(e.tag) || (await d(e.scriptUrl), await f(e.tag));
16
+ const t = document.createElement(e.tag);
17
+ return i(t, e.props), i(t, r.props), r.ctx && i(t, { setCtx: r.ctx }), r.onComplete && t.addEventListener("complete", (n) => r.onComplete?.(n.detail)), r.onError && t.addEventListener("error", (n) => r.onError?.(n.error ?? new Error("component error"))), r.target.appendChild(t), {
18
+ el: t,
19
+ unmount() {
20
+ t.remove();
21
+ },
22
+ update(n) {
23
+ i(t, n);
24
+ }
25
+ };
26
+ }
27
+ function i(e, r) {
28
+ if (r)
29
+ for (const [t, n] of Object.entries(r)) {
30
+ const s = e[t];
31
+ if (typeof s == "function")
32
+ try {
33
+ s.call(e, n);
34
+ } catch (o) {
35
+ console.warn(`[RemoteComponentLoader] ${t}() threw`, o);
36
+ }
37
+ }
38
+ }
39
+ function d(e) {
40
+ const r = u.get(e);
41
+ if (r) return r;
42
+ const t = new Promise((n, s) => {
43
+ const o = document.createElement("script");
44
+ o.src = e, o.async = !0, o.onload = () => n(), o.onerror = () => s(new Error(`Failed to load script ${e}`)), document.head.appendChild(o);
45
+ });
46
+ return u.set(e, t), t;
47
+ }
48
+ function f(e, r = 5e3) {
49
+ return customElements.get(e) ? Promise.resolve() : Promise.race([
50
+ customElements.whenDefined(e).then(() => {
51
+ }),
52
+ new Promise((t, n) => {
53
+ setTimeout(() => n(new Error(`Custom element <${e}> never registered`)), r);
54
+ })
55
+ ]);
56
+ }
57
+ const l = 1;
58
+ function h(e, r) {
59
+ const t = document.createElement("iframe");
60
+ t.setAttribute(
61
+ "sandbox",
62
+ // Restrictive set: scripts (run the bundle), same-origin (so the
63
+ // bundle can use localStorage/cookies on its own srcdoc origin),
64
+ // forms (login submits), popups (when tenant code opens external
65
+ // links). NOT allow-top-navigation — the bundle can't break out.
66
+ "allow-scripts allow-same-origin allow-forms allow-popups"
67
+ ), t.style.cssText = "width:100%;height:100%;border:0;display:block;background:transparent;", t.setAttribute("title", `aikaara-remote:${e.globalName ?? e.scriptUrl}`);
68
+ const n = [], s = (a) => t.contentWindow?.postMessage(a, "*");
69
+ let o = !1;
70
+ const m = (a) => {
71
+ if (a.source !== t.contentWindow) return;
72
+ const c = a.data;
73
+ !c || c.aikaara !== l || (c.type === "ready" ? s({
74
+ aikaara: l,
75
+ type: "bootstrap",
76
+ ctx: r.ctx,
77
+ props: { ...e.props ?? {}, ...r.props ?? {} }
78
+ }) : c.type === "complete" ? r.onComplete?.(c.payload) : c.type === "error" && r.onError?.(new Error(c.message)));
79
+ };
80
+ return window.addEventListener("message", m), n.push(() => window.removeEventListener("message", m)), t.srcdoc = `<!doctype html><html><head><meta charset="utf-8">
81
+ <style>html,body{margin:0;padding:0;height:100%;background:transparent;}</style>
82
+ </head><body><script src="${w(e.scriptUrl)}" defer><\/script></body></html>`, r.target.appendChild(t), {
83
+ el: t,
84
+ unmount() {
85
+ if (!o) {
86
+ o = !0;
87
+ for (const a of n) try {
88
+ a();
89
+ } catch {
90
+ }
91
+ t.remove();
92
+ }
93
+ },
94
+ update(a) {
95
+ s({ aikaara: l, type: "update", props: a });
96
+ }
97
+ };
98
+ }
99
+ function w(e) {
100
+ return e.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;");
101
+ }
102
+ export {
103
+ g as loadRemoteComponent
104
+ };
package/dist/ui.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./MountTenant-DHxy8WY9.cjs");exports.AikaaraChat=a.AikaaraChat;exports.AikaaraChatBubble=a.AikaaraChatBubble;exports.AikaaraChatHeader=a.AikaaraChatHeader;exports.AikaaraChatInput=a.AikaaraChatInput;exports.AikaaraChatWidget=a.AikaaraChatWidget;exports.AikaaraComparePlans=a.AikaaraComparePlans;exports.AikaaraErrorBanner=a.AikaaraErrorBanner;exports.AikaaraLinkModal=a.AikaaraLinkModal;exports.AikaaraMessageBubble=a.AikaaraMessageBubble;exports.AikaaraMessageList=a.AikaaraMessageList;exports.AikaaraModalAction=a.AikaaraModalAction;exports.AikaaraOptionList=a.AikaaraOptionList;exports.AikaaraStreamingMessage=a.AikaaraStreamingMessage;exports.AikaaraSubmitAction=a.AikaaraSubmitAction;exports.AikaaraSystemPill=a.AikaaraSystemPill;exports.AikaaraTemplateRenderer=a.AikaaraTemplateRenderer;exports.AikaaraTypingIndicator=a.AikaaraTypingIndicator;exports.registerComponents=a.registerComponents;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./MountTenant-DvmiAoZ_.cjs");exports.AikaaraChat=a.AikaaraChat;exports.AikaaraChatBubble=a.AikaaraChatBubble;exports.AikaaraChatHeader=a.AikaaraChatHeader;exports.AikaaraChatInput=a.AikaaraChatInput;exports.AikaaraChatWidget=a.AikaaraChatWidget;exports.AikaaraComparePlans=a.AikaaraComparePlans;exports.AikaaraErrorBanner=a.AikaaraErrorBanner;exports.AikaaraLinkModal=a.AikaaraLinkModal;exports.AikaaraMessageBubble=a.AikaaraMessageBubble;exports.AikaaraMessageList=a.AikaaraMessageList;exports.AikaaraModalAction=a.AikaaraModalAction;exports.AikaaraOptionList=a.AikaaraOptionList;exports.AikaaraStreamingMessage=a.AikaaraStreamingMessage;exports.AikaaraSubmitAction=a.AikaaraSubmitAction;exports.AikaaraSystemPill=a.AikaaraSystemPill;exports.AikaaraTemplateRenderer=a.AikaaraTemplateRenderer;exports.AikaaraTypingIndicator=a.AikaaraTypingIndicator;exports.registerComponents=a.registerComponents;
package/dist/ui.d.ts CHANGED
@@ -292,6 +292,8 @@ export declare class AikaaraMessageList extends HTMLElement {
292
292
  private getLinkBearer;
293
293
  setHideSystemMessages(items: string[]): void;
294
294
  setTimestampFormat(fmt: 'time' | 'datetime' | 'date' | 'none'): void;
295
+ private templateLayout;
296
+ setTemplateLayout(layout: 'inside' | 'outside'): void;
295
297
  /** Returns true when a message should be hidden by the descriptor's
296
298
  * `hideSystemMessages` filter. Matches the trimmed content
297
299
  * case-insensitively against any configured needle (substring match). */
@@ -1170,6 +1172,7 @@ declare interface WidgetConfig extends ChatClientConfig {
1170
1172
  attachPosition?: 'left' | 'right';
1171
1173
  sendButtonShape?: 'circle' | 'square';
1172
1174
  };
1175
+ templateLayout?: 'inside' | 'outside';
1173
1176
  showBubble?: boolean;
1174
1177
  bubbleText?: string;
1175
1178
  bubbleIcon?: string;
package/dist/ui.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { B as i, a as s, c as e, d as t, e as A, D as k, f as n, F as o, g, h as l, G as d, H as m, i as p, I as C, J as h, K as b, j as M, r as c } from "./MountTenant-CdaBBA2O.mjs";
1
+ import { B as i, a as s, c as e, d as t, e as A, D as k, f as n, F as o, g, h as l, G as d, H as m, i as p, I as C, J as h, K as b, j as M, r as c } from "./MountTenant-DzNgBTiU.mjs";
2
2
  export {
3
3
  i as AikaaraChat,
4
4
  s as AikaaraChatBubble,