@aikaara/chat-sdk 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/headless.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { E as y } from "./AikaaraChatClient-Cqbcd1jb.mjs";
2
- import { A as v, a as F, b as I, C as _, c as E, d as b, M as w, T as U, e as C, i as k, f as j, p as A } from "./AikaaraChatClient-Cqbcd1jb.mjs";
3
- class m extends y {
1
+ import { E as s } from "./MountTenant-5CL6i2El.mjs";
2
+ import { A as p, b as g, k as l, C as h, l as y, m as c, M as u, S as m, T as f, n as T, o as S, p as _, q as v, s as E, t as C, u as F, v as A, w as k, x as I } from "./MountTenant-5CL6i2El.mjs";
3
+ class a extends s {
4
4
  registration = null;
5
5
  pendingEdits = [];
6
6
  constructor(t) {
@@ -92,53 +92,26 @@ class m extends y {
92
92
  });
93
93
  }
94
94
  }
95
- function g(r) {
96
- return {
97
- async upload(t, e) {
98
- const i = new FormData(), p = r.fieldName ?? "file";
99
- i.append(p, t, t.name);
100
- const a = typeof r.extraFields == "function" ? r.extraFields(e) : r.extraFields;
101
- if (a)
102
- for (const [c, u] of Object.entries(a)) i.append(c, u);
103
- i.append("conversationId", e.conversationId), i.append("userId", e.userId), e.projectId && i.append("projectId", e.projectId);
104
- const l = typeof r.headers == "function" ? await r.headers() : r.headers ?? {}, n = await fetch(r.endpoint, {
105
- method: r.method ?? "POST",
106
- body: i,
107
- headers: l,
108
- credentials: r.credentials
109
- });
110
- if (!n.ok)
111
- throw new Error(`Upload failed: ${n.status} ${n.statusText}`);
112
- const o = await n.json().catch(() => ({}));
113
- if (r.parseResponse) return r.parseResponse(o, e);
114
- const s = o, d = s.url ?? s.fileUrl ?? s.publicUrl, h = s.fileName ?? s.name ?? t.name;
115
- if (!d) throw new Error('Upload response missing "url" / "fileUrl" / "publicUrl"');
116
- return {
117
- url: d,
118
- fileName: h,
119
- cloudFileId: typeof s.cloudFileId == "string" ? s.cloudFileId : void 0,
120
- relativePath: typeof s.path == "string" ? s.path : void 0,
121
- contentType: typeof s.contentType == "string" ? s.contentType : void 0,
122
- byteSize: typeof s.byteSize == "number" ? s.byteSize : void 0,
123
- meta: s
124
- };
125
- }
126
- };
127
- }
128
95
  export {
129
- v as ActionCableClient,
130
- F as AikaaraChatClient,
131
- I as ApiClient,
132
- _ as ChannelSubscription,
133
- E as ConnectionManager,
134
- b as ConversationManager,
135
- y as EventEmitter,
136
- m as FormBridge,
137
- w as MessageStore,
138
- U as TiledeskTransport,
139
- g as createFetchUploadAdapter,
140
- C as extractTiledeskFileEnvelope,
141
- k as inferTiledeskRole,
142
- j as isTiledeskSelfEcho,
143
- A as parseTiledeskTemplate
96
+ p as ActionCableClient,
97
+ g as AikaaraChatClient,
98
+ l as ApiClient,
99
+ h as ChannelSubscription,
100
+ y as ConnectionManager,
101
+ c as ConversationManager,
102
+ s as EventEmitter,
103
+ a as FormBridge,
104
+ u as MessageStore,
105
+ m as SessionAuthAdapter,
106
+ f as TiledeskTransport,
107
+ T as clearPersistedConversationId,
108
+ S as createFetchUploadAdapter,
109
+ _ as createPresigned3StepUploadAdapter,
110
+ v as createTiledeskHistoryAdapter,
111
+ E as extractTiledeskFileEnvelope,
112
+ C as inferTiledeskRole,
113
+ F as isTiledeskSelfEcho,
114
+ A as mountFromSlug,
115
+ k as mountTenantWidget,
116
+ I as parseTiledeskTemplate
144
117
  };
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./AikaaraChatClient-kAu65hX-.cjs"),n=require("./headless.cjs"),a=require("./ui.cjs");function c(t){a.registerComponents();const r=document.createElement("aikaara-chat-widget"),o={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[s,l]of Object.entries(o)){const i=t[s];i!=null&&r.setAttribute(l,String(i))}return r.configure(t),document.body.appendChild(r),r}function d(){const t=document.querySelector("aikaara-chat-widget");t&&t.remove()}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.TiledeskTransport=e.TiledeskTransport;exports.extractTiledeskFileEnvelope=e.extractTiledeskFileEnvelope;exports.inferTiledeskRole=e.inferTiledeskRole;exports.isTiledeskSelfEcho=e.isTiledeskSelfEcho;exports.parseTiledeskTemplate=e.parseTiledeskTemplate;exports.FormBridge=n.FormBridge;exports.createFetchUploadAdapter=n.createFetchUploadAdapter;exports.AikaaraChatBubble=a.AikaaraChatBubble;exports.AikaaraChatHeader=a.AikaaraChatHeader;exports.AikaaraChatInput=a.AikaaraChatInput;exports.AikaaraChatWidget=a.AikaaraChatWidget;exports.AikaaraErrorBanner=a.AikaaraErrorBanner;exports.AikaaraMessageBubble=a.AikaaraMessageBubble;exports.AikaaraMessageList=a.AikaaraMessageList;exports.AikaaraStreamingMessage=a.AikaaraStreamingMessage;exports.AikaaraTypingIndicator=a.AikaaraTypingIndicator;exports.registerComponents=a.registerComponents;exports.mount=c;exports.unmount=d;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./MountTenant-dM6HzlAl.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.TiledeskTransport=e.TiledeskTransport;exports.clearPersistedConversationId=e.clearPersistedConversationId;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
@@ -49,15 +49,21 @@ export declare class AikaaraChatClient extends EventEmitter<ChatEvents> {
49
49
  private config;
50
50
  private mode;
51
51
  private uploadAdapter;
52
+ private historyAdapter;
52
53
  private tiledeskUnsubs;
53
54
  constructor(config: ChatClientConfig, opts?: {
54
55
  uploadAdapter?: UploadAdapter;
56
+ historyAdapter?: ConversationHistoryAdapter;
55
57
  });
56
58
  private usesAikaara;
57
59
  private usesTiledesk;
58
60
  private initTiledeskTransport;
59
61
  connect(): Promise<void>;
60
- sendMessage(content: string): Promise<void>;
62
+ private hydrateTiledeskHistory;
63
+ sendMessage(content: string, opts?: {
64
+ attributes?: Record<string, unknown>;
65
+ metadata?: Record<string, unknown>;
66
+ }): Promise<void>;
61
67
  /**
62
68
  * Upload a file via the configured UploadAdapter (client-side: file goes
63
69
  * to the tenant's own backend, never through Aikaara). Then publish the
@@ -121,17 +127,38 @@ export declare class AikaaraChatHeader extends HTMLElement {
121
127
  setStatus(status: string): void;
122
128
  }
123
129
 
130
+ /**
131
+ * Chat input box. Composes a textarea + send button + optional attach button.
132
+ *
133
+ * Events fired (composed:true so they cross shadow boundaries):
134
+ * - `send` `{ content: string }` — user pressed enter / clicked send
135
+ * - `file-pick` `{ file: File }` — user selected a file to upload
136
+ *
137
+ * Attributes:
138
+ * - `placeholder` placeholder text
139
+ * - `disable-attach` hides the attach button (set when host has no uploadAdapter)
140
+ * - `accept` forwarded to the hidden <input type="file">
141
+ * - `multiple` allow selecting multiple files
142
+ */
124
143
  export declare class AikaaraChatInput extends HTMLElement {
125
144
  private shadow;
126
145
  private textarea;
127
146
  private sendBtn;
147
+ private attachBtn;
148
+ private fileInput;
128
149
  private _disabled;
150
+ private _uploading;
129
151
  constructor();
152
+ static get observedAttributes(): string[];
130
153
  connectedCallback(): void;
131
154
  set disabled(val: boolean);
132
155
  get disabled(): boolean;
156
+ /** Toggle the attach button into a "uploading…" spinner state. */
157
+ set uploading(val: boolean);
158
+ get uploading(): boolean;
133
159
  focus(): void;
134
160
  clear(): void;
161
+ private refreshSendDisabled;
135
162
  private handleSend;
136
163
  private autoGrow;
137
164
  }
@@ -148,6 +175,7 @@ export declare class AikaaraChatWidget extends HTMLElement {
148
175
  configure(config: Partial<WidgetConfig>): void;
149
176
  private getConfig;
150
177
  setUploadAdapter(adapter: UploadAdapter): void;
178
+ setHistoryAdapter(adapter: ConversationHistoryAdapter): void;
151
179
  private render;
152
180
  private initController;
153
181
  sendUserEvent(eventKey: string, value?: Record<string, unknown>, source?: string): void;
@@ -300,6 +328,13 @@ export declare interface ChatClientConfig extends ConnectionConfig {
300
328
  departmentId?: string;
301
329
  senderFullname?: string;
302
330
  };
331
+ /**
332
+ * Tenant-level defaults merged into the `action` object of every template
333
+ * postback (e.g. submit-action click). Useful for app-specific keys like
334
+ * `serviceType: 'ITR'` that the bot expects on every form submission.
335
+ * Per-submit values from the form take precedence over these defaults.
336
+ */
337
+ templateActionAttributes?: Record<string, unknown>;
303
338
  onMessage?: (message: Message) => void;
304
339
  onStatusChange?: (status: string) => void;
305
340
  onError?: (error: Error) => void;
@@ -346,6 +381,8 @@ export declare interface ChatEvents {
346
381
  };
347
382
  }
348
383
 
384
+ export declare function clearPersistedConversationId(userId: string, projectId: string): void;
385
+
349
386
  export declare interface ConnectionConfig {
350
387
  baseUrl: string;
351
388
  wsUrl?: string;
@@ -377,6 +414,19 @@ export declare class ConnectionManager extends EventEmitter<ChatEvents> {
377
414
 
378
415
  export declare type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';
379
416
 
417
+ /**
418
+ * Pluggable adapter that hydrates prior conversation messages on connect.
419
+ * The SDK calls this once after MQTT subscribes so the user sees existing
420
+ * history before any new live messages arrive.
421
+ */
422
+ export declare interface ConversationHistoryAdapter {
423
+ fetchMessages(conversationId: string, ctx: {
424
+ userId: string;
425
+ appId?: string;
426
+ projectId?: string;
427
+ }): Promise<TiledeskMessage[]>;
428
+ }
429
+
380
430
  export declare class ConversationManager {
381
431
  private _conversationId;
382
432
  private persist;
@@ -395,6 +445,10 @@ declare interface CreateConversationResponse {
395
445
 
396
446
  export declare function createFetchUploadAdapter(config: FetchUploadAdapterConfig): UploadAdapter;
397
447
 
448
+ export declare function createPresigned3StepUploadAdapter(config: Presigned3StepAdapterConfig): UploadAdapter;
449
+
450
+ export declare function createTiledeskHistoryAdapter(config: TiledeskHistoryAdapterConfig): ConversationHistoryAdapter;
451
+
398
452
  export declare interface EditEntityAction {
399
453
  action: 'edit_entity';
400
454
  entity_type: string;
@@ -616,18 +670,176 @@ export declare class MessageStore {
616
670
 
617
671
  export declare function mount(config: WidgetConfig): AikaaraChatWidget;
618
672
 
673
+ export declare interface MountedTenantWidget {
674
+ widget: AikaaraChatWidget;
675
+ requestId: string;
676
+ config: WidgetConfig;
677
+ destroy: () => void;
678
+ }
679
+
680
+ /**
681
+ * Single-call mount. Pulls the descriptor from `widget_configs/:slug`, runs
682
+ * descriptor.auth to mint chat JWT + requestId, builds upload + history
683
+ * adapters from descriptor.upload, and mounts the web component. Host app
684
+ * supplies only the user id + their session JWT.
685
+ *
686
+ * import { mountFromSlug } from '@aikaara/chat-sdk';
687
+ *
688
+ * await mountFromSlug({
689
+ * container: '#chat',
690
+ * slug: 'bandhan-itr',
691
+ * user: { id: '33568', token: () => getCognitoJwt() },
692
+ * });
693
+ */
694
+ export declare function mountFromSlug(opts: SlugMountOptions): Promise<SlugMountedWidget>;
695
+
696
+ /**
697
+ * Standard tenant mount. Fetches the descriptor (when `configUrl` is set),
698
+ * merges per-mount overrides, builds default adapters from the descriptor's
699
+ * endpoint URLs (when no override is supplied), and mounts the widget.
700
+ */
701
+ export declare function mountTenantWidget(opts: TenantMountOptions): Promise<MountedTenantWidget>;
702
+
619
703
  export declare interface NavigateAction {
620
704
  navigate_to: string;
621
705
  }
622
706
 
623
707
  export declare function parseTiledeskTemplate(message: TiledeskMessage): TiledeskParsedTemplate;
624
708
 
709
+ /**
710
+ * Three-step presigned-S3 upload (sign → PUT → register). Driven entirely
711
+ * by descriptor — no tenant-specific code in host apps.
712
+ */
713
+ export declare interface Presigned3StepAdapterConfig {
714
+ /** GET endpoint that returns a presigned URL. `{fileName}` placeholder. */
715
+ signEndpoint: string;
716
+ signMethod?: 'GET' | 'POST';
717
+ /** Dot path into the response JSON for the presigned URL. Default `data.s3SignedUrl`. */
718
+ signedUrlPath?: string;
719
+ /** Optional POST registering the upload (e.g. `/chatbuddy/file-upload`). */
720
+ registerEndpoint?: string;
721
+ /**
722
+ * Body JSON for the register POST. Tokens: `{fileName}`, `{userId}`,
723
+ * `{requestId}` (alias `{conversationId}`).
724
+ */
725
+ registerBody?: Record<string, unknown>;
726
+ /**
727
+ * Final URL the chat message will carry. Tokens: `{fileName}`, `{userId}`,
728
+ * `{requestId}`. When omitted the presigned URL itself is used.
729
+ */
730
+ viewerTemplate?: string;
731
+ /**
732
+ * Rewrite the host portion of the presigned URL before PUTting (used for
733
+ * dev proxies). E.g. `/s3-upload`. Leave empty for direct.
734
+ */
735
+ s3HostRewrite?: string;
736
+ /** Bearer token getter for sign + register calls. */
737
+ authHeader?: () => string | Promise<string>;
738
+ /** Static extra headers for sign + register. */
739
+ extraHeaders?: Record<string, string>;
740
+ }
741
+
625
742
  export declare function registerComponents(): void;
626
743
 
627
744
  export declare interface SaveEntityAction {
628
745
  action: 'save_entity';
629
746
  }
630
747
 
748
+ export declare class SessionAuthAdapter {
749
+ private readonly descriptor;
750
+ private readonly sessionToken;
751
+ private cache;
752
+ private inflight;
753
+ constructor(descriptor: SessionAuthDescriptor, sessionToken: SessionTokenProvider);
754
+ /** Force-refresh by clearing cache. Next `get()` call refetches. */
755
+ reset(): void;
756
+ get(): Promise<SessionAuthData>;
757
+ private fetchOnce;
758
+ }
759
+
760
+ export declare interface SessionAuthData {
761
+ token: string;
762
+ requestId: string;
763
+ fullName: string;
764
+ expiresAt: number;
765
+ }
766
+
767
+ /**
768
+ * Descriptor-driven session auth.
769
+ *
770
+ * The host app supplies a "session token" — typically a JWT issued by their
771
+ * own auth (Cognito/Auth0/firebase/etc) — and the descriptor declares how to
772
+ * exchange it for a chat-platform JWT + conversation requestId. The SDK runs
773
+ * the exchange itself, caches the result, and refreshes when the chat JWT
774
+ * approaches expiry. The original requestId is preserved across refreshes so
775
+ * the conversation thread is stable.
776
+ */
777
+ export declare interface SessionAuthDescriptor {
778
+ /** Absolute or same-origin URL — POSTed with the session token as bearer. */
779
+ endpoint: string;
780
+ method?: 'POST' | 'GET';
781
+ /** JSON body for the request. POST only. */
782
+ body?: Record<string, unknown>;
783
+ /** Extra static headers (e.g. partnerid). */
784
+ headers?: Record<string, string>;
785
+ /** Header carrying the session token. Default `Authorization`. */
786
+ authHeader?: string;
787
+ /**
788
+ * Template for the session-token header value. `{token}` is replaced.
789
+ * Default: `Bearer {token}`. Use `JWT {token}` etc. when required.
790
+ */
791
+ authHeaderTemplate?: string;
792
+ /** Dot path into the response JSON for the chat JWT. Default `data.token`. */
793
+ tokenPath?: string;
794
+ /** Stripped from the extracted token before use (e.g. `JWT `). */
795
+ tokenStripPrefix?: string;
796
+ /** Dot path for the conversation requestId. Default `data.requestId`. */
797
+ requestIdPath?: string;
798
+ /** Dot path for the user display name. Default `data.fullName`. */
799
+ fullNamePath?: string;
800
+ /** Refetch when the JWT is within this many ms of expiry. Default 60_000. */
801
+ expiryBufferMs?: number;
802
+ }
803
+
804
+ export declare type SessionTokenProvider = string | (() => string | Promise<string>);
805
+
806
+ export declare interface SlugMountedWidget extends MountedTenantWidget {
807
+ fullName: string;
808
+ /** Force a fresh /chatbuddy/auth-style refetch (clears cached requestId). */
809
+ refreshAuth(): Promise<void>;
810
+ }
811
+
812
+ export declare interface SlugMountOptions {
813
+ /** Container element or CSS selector (e.g. `#chat`). */
814
+ container: HTMLElement | string;
815
+ /** Tenant identifier — the SDK fetches `${configBase}/widget_configs/${slug}`. */
816
+ slug: string;
817
+ /** Defaults to `https://api.aikaara.com`. Override for self-hosted aikaara. */
818
+ configBase?: string;
819
+ /** Additional headers for the descriptor fetch. */
820
+ configHeaders?: Record<string, string>;
821
+ user: {
822
+ id: string;
823
+ /** Display name fallback when descriptor.auth doesn't return one. */
824
+ name?: string;
825
+ departmentId?: string;
826
+ /**
827
+ * Session JWT (Cognito/Auth0/firebase/etc) — passed as bearer to
828
+ * `descriptor.auth.endpoint`. Can be a string (static for the session)
829
+ * or a getter that re-resolves on each refresh.
830
+ */
831
+ token: SessionTokenProvider;
832
+ };
833
+ /** Optional escape hatches; merge over descriptor-driven defaults. */
834
+ hooks?: {
835
+ upload?: UploadAdapter;
836
+ history?: ConversationHistoryAdapter;
837
+ onError?: (err: Error) => void;
838
+ };
839
+ /** Per-mount visual overrides. */
840
+ overrides?: Partial<WidgetConfigDescriptor>;
841
+ }
842
+
631
843
  declare type SubscriptionCallback = (data: unknown) => void;
632
844
 
633
845
  declare interface TemplateMessageEvent {
@@ -641,6 +853,43 @@ declare interface TemplateMessageEvent {
641
853
  raw: unknown;
642
854
  }
643
855
 
856
+ export declare interface TenantMountOptions {
857
+ container: HTMLElement;
858
+ /** Fetched from this URL when `config` is omitted. */
859
+ configUrl?: string;
860
+ /** Pre-resolved descriptor — skip the fetch. */
861
+ config?: WidgetConfigDescriptor;
862
+ /** Headers attached when fetching `configUrl` (e.g. tenant-API auth). */
863
+ configHeaders?: Record<string, string>;
864
+ identity: {
865
+ userId: string;
866
+ userName?: string;
867
+ departmentId?: string;
868
+ senderFullname?: string;
869
+ };
870
+ /** Returns a raw Tiledesk JWT (no Bearer/JWT prefix) for MQTT password. */
871
+ tokenProvider: () => Promise<string>;
872
+ /** Authorization value for the history fetch. Defaults to `tokenProvider()`. */
873
+ historyTokenProvider?: () => Promise<string>;
874
+ /**
875
+ * Optional override adapters. If omitted and the descriptor specifies the
876
+ * matching endpoint, the SDK builds default fetch-based adapters.
877
+ */
878
+ uploadAdapter?: UploadAdapter;
879
+ historyAdapter?: ConversationHistoryAdapter;
880
+ /**
881
+ * Pin a conversationId. When omitted we look up
882
+ * `aikaara_chat:requestId:{userId}:{projectId}` in localStorage and reuse
883
+ * any persisted value; only mint a fresh `requestId` when nothing is stored.
884
+ */
885
+ conversationId?: string;
886
+ forceNewConversation?: boolean;
887
+ /** Per-mount overrides that take precedence over the descriptor. */
888
+ overrides?: Partial<WidgetConfigDescriptor>;
889
+ /** Surfaced from the SDK. */
890
+ onError?: (err: Error) => void;
891
+ }
892
+
644
893
  export declare interface TestToolAction {
645
894
  action: 'test_tool';
646
895
  tool_id: number;
@@ -674,6 +923,32 @@ export declare interface TiledeskFileTemplateConfig {
674
923
  isDeepLink?: boolean;
675
924
  }
676
925
 
926
+ export declare interface TiledeskHistoryAdapterConfig {
927
+ /**
928
+ * Base URL of the Tiledesk chat API, e.g. `https://uat-tiledesk.taxbuddy.com/chatapi/api`
929
+ * (no trailing slash). Final URL is composed as
930
+ * `{apiBase}/tilechat/{userId}/conversations/{conversationId}/messages?pageSize={pageSize}`
931
+ */
932
+ apiBase: string;
933
+ pageSize?: number;
934
+ /**
935
+ * Async getter for the bearer token. Most Tiledesk-fronted gateways accept
936
+ * the same JWT used for the MQTT connection. Return `null` to omit the
937
+ * `Authorization` header.
938
+ */
939
+ getToken?: () => string | null | Promise<string | null>;
940
+ /** Override the path template. Default mirrors bandhan's chatapi route. */
941
+ pathTemplate?: string;
942
+ /** Extra static headers to attach (e.g. `partnerid`, `environment`). */
943
+ extraHeaders?: Record<string, string>;
944
+ /**
945
+ * Optional response shape mapper. Default expects
946
+ * `{ success: true, result: TiledeskMessage[] }`
947
+ * which matches the bandhan `/chatapi/api/tilechat/.../messages` response.
948
+ */
949
+ parseResponse?: (raw: unknown) => TiledeskMessage[];
950
+ }
951
+
677
952
  export declare interface TiledeskMessage {
678
953
  text?: string;
679
954
  type?: string;
@@ -760,6 +1035,7 @@ export declare class TiledeskTransport {
760
1035
  private inboundUpdateRegex;
761
1036
  constructor(config: TiledeskTransportConfig);
762
1037
  connect(): Promise<void>;
1038
+ private debugLog;
763
1039
  subscribeWildcard(): void;
764
1040
  subscribeToConversation(conversationId: string): void;
765
1041
  unsubscribeFromConversation(conversationId: string): void;
@@ -821,6 +1097,20 @@ export declare interface TiledeskTransportConfig {
821
1097
  fileTemplate?: TiledeskFileTemplateConfig;
822
1098
  recipientFullnameResolver?: (conversationId: string) => string | undefined;
823
1099
  senderFullname?: string;
1100
+ /**
1101
+ * If true (default), AikaaraChatClient publishes a `CHAT_INITIATED` event
1102
+ * to the conversation's outbound topic on first connect — but only when
1103
+ * the conversation history is empty (so reload of an in-flight chat
1104
+ * doesn't replay the kickoff).
1105
+ */
1106
+ autoInitiateOnEmpty?: boolean;
1107
+ /** Extra attributes merged into the auto-fired CHAT_INITIATED envelope. */
1108
+ chatInitiatedAttributes?: Record<string, unknown>;
1109
+ /**
1110
+ * Log decoded MQTT frames to console as they're sent/received.
1111
+ * Off by default — set true for debugging Tiledesk wire traffic.
1112
+ */
1113
+ debug?: boolean;
824
1114
  }
825
1115
 
826
1116
  export declare interface ToolCall {
@@ -891,6 +1181,92 @@ export declare interface WidgetConfig extends ChatClientConfig {
891
1181
  bubbleText?: string;
892
1182
  bubbleIcon?: string;
893
1183
  uploadAdapter?: UploadAdapter;
1184
+ historyAdapter?: ConversationHistoryAdapter;
1185
+ /**
1186
+ * Display mode:
1187
+ * - `popup` (default): floating bubble in the corner, click to open panel.
1188
+ * - `embed`: render the chat panel inline at the host element's location,
1189
+ * filling its container. Bubble + open/close animation are skipped.
1190
+ */
1191
+ display?: 'popup' | 'embed';
1192
+ }
1193
+
1194
+ export declare interface WidgetConfigDescriptor {
1195
+ /** Visuals */
1196
+ display?: 'popup' | 'embed';
1197
+ position?: 'bottom-right' | 'bottom-left';
1198
+ primaryColor?: string;
1199
+ title?: string;
1200
+ subtitle?: string;
1201
+ avatarUrl?: string;
1202
+ width?: number;
1203
+ height?: number;
1204
+ borderRadius?: number;
1205
+ fontFamily?: string;
1206
+ welcomeMessage?: string;
1207
+ placeholder?: string;
1208
+ showTimestamps?: boolean;
1209
+ persistConversation?: boolean;
1210
+ /** Transport selection */
1211
+ transport?: TransportMode;
1212
+ /** Tiledesk wire config (JSON-serializable subset of TiledeskTransportConfig) */
1213
+ tiledesk?: {
1214
+ mqttEndpoint: string;
1215
+ appId?: string;
1216
+ projectId: string;
1217
+ mqttUsername?: string;
1218
+ protocolId?: 'MQIsdp' | 'MQTT';
1219
+ protocolVersion?: 3 | 4 | 5;
1220
+ keepAliveSec?: number;
1221
+ connectTimeoutMs?: number;
1222
+ maxReconnectAttempts?: number;
1223
+ reconnectMaxDelayMs?: number;
1224
+ wildcardSubscribe?: boolean;
1225
+ enablePresence?: boolean;
1226
+ autoInitiateOnEmpty?: boolean;
1227
+ chatInitiatedAttributes?: Record<string, unknown>;
1228
+ messageDefaults?: TiledeskMessageDefaults;
1229
+ fileTemplate?: TiledeskFileTemplateConfig;
1230
+ topicTemplates?: TiledeskTopicTemplates;
1231
+ debug?: boolean;
1232
+ /**
1233
+ * Pattern for `support-group-…` requestId minted on first chat. Use
1234
+ * `{projectId}` and `{uuid}` placeholders. Defaults to bandhan's
1235
+ * `support-group-{projectId}-{uuid}`.
1236
+ */
1237
+ requestIdTemplate?: string;
1238
+ };
1239
+ /** Defaults merged into every form-action postback */
1240
+ templateActionAttributes?: Record<string, unknown>;
1241
+ /** Adapter endpoints — SDK builds the actual fetch calls */
1242
+ uploadEndpoint?: string;
1243
+ uploadFieldName?: string;
1244
+ uploadExtraFields?: Record<string, string>;
1245
+ historyApiBase?: string;
1246
+ historyPageSize?: number;
1247
+ historyPathTemplate?: string;
1248
+ /**
1249
+ * Server-side session-token exchange. When set, the SDK exchanges the
1250
+ * caller-supplied `sessionToken` for a chat JWT + conversation requestId
1251
+ * itself — the host app no longer needs a `tokenProvider` callback.
1252
+ */
1253
+ auth?: SessionAuthDescriptor;
1254
+ /**
1255
+ * Built-in upload strategy. `mode: "presigned-3step"` runs sign → PUT →
1256
+ * register entirely from descriptor config; `mode: "direct"` POSTs as
1257
+ * multipart to a single endpoint; `mode: "none"` disables uploads. Host
1258
+ * apps can still override with `opts.uploadAdapter`.
1259
+ */
1260
+ upload?: {
1261
+ mode: 'none';
1262
+ } | {
1263
+ mode: 'direct';
1264
+ endpoint: string;
1265
+ fieldName?: string;
1266
+ extraFields?: Record<string, string>;
1267
+ } | ({
1268
+ mode: 'presigned-3step';
1269
+ } & Presigned3StepAdapterConfig);
894
1270
  }
895
1271
 
896
1272
  export { }