@aikaara/chat-sdk 0.1.4 → 0.3.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/index.d.ts CHANGED
@@ -22,6 +22,8 @@ export declare interface ActionCableMessage {
22
22
  message?: unknown;
23
23
  }
24
24
 
25
+ export declare type AgentAction = EditEntityAction | SaveEntityAction | TestToolAction | NavigateAction;
26
+
25
27
  export declare interface AgentEvent {
26
28
  type: AgentEventType;
27
29
  [key: string]: unknown;
@@ -39,20 +41,72 @@ export declare class AikaaraChatBubble extends HTMLElement {
39
41
 
40
42
  export declare class AikaaraChatClient extends EventEmitter<ChatEvents> {
41
43
  private connection;
44
+ private tiledesk;
42
45
  private api;
43
46
  private messageStore;
44
47
  private conversationManager;
45
48
  private subscription;
46
49
  private config;
47
- constructor(config: ChatClientConfig);
50
+ private mode;
51
+ private uploadAdapter;
52
+ private tiledeskUnsubs;
53
+ constructor(config: ChatClientConfig, opts?: {
54
+ uploadAdapter?: UploadAdapter;
55
+ });
56
+ private usesAikaara;
57
+ private usesTiledesk;
58
+ private initTiledeskTransport;
48
59
  connect(): Promise<void>;
49
60
  sendMessage(content: string): Promise<void>;
61
+ /**
62
+ * Upload a file via the configured UploadAdapter (client-side: file goes
63
+ * to the tenant's own backend, never through Aikaara). Then publish the
64
+ * Tiledesk file-message envelope so hooks_controller picks it up.
65
+ */
66
+ sendFile(file: File | Blob, opts?: {
67
+ caption?: string;
68
+ }): Promise<void>;
69
+ /**
70
+ * Trigger Tiledesk's CHAT_INITIATED event — required to kick off a bot flow
71
+ * for newly-created Tiledesk request groups.
72
+ */
73
+ initiateTiledeskChat(extraAttributes?: Record<string, unknown>): void;
74
+ /** Mark a Tiledesk message as read (publishes status=300 update). */
75
+ markTiledeskRead(messageId: string): void;
76
+ setUploadAdapter(adapter: UploadAdapter): void;
50
77
  sendUserEvent(eventKey: string, value?: object, source?: string): Promise<void>;
51
78
  loadHistory(): Promise<Message[]>;
52
79
  get messages(): Message[];
53
80
  get conversationId(): string | null;
54
81
  get isConnected(): boolean;
82
+ /**
83
+ * Update the agent's context with information about the host app's current state.
84
+ * Call this on route changes so the agent knows what page/entity the user is viewing.
85
+ *
86
+ * The context is stored in conversation metadata and interpolated into the system prompt.
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * // On route change
91
+ * client.setContext({
92
+ * currentPage: '/products/42',
93
+ * entityType: 'product',
94
+ * entityId: '42',
95
+ * availableRoutes: { products: '/products', orders: '/orders' },
96
+ * });
97
+ * ```
98
+ */
99
+ setContext(context: AppContext): Promise<void>;
55
100
  disconnect(): Promise<void>;
101
+ private handleTiledeskMessage;
102
+ private handleTiledeskStatusUpdate;
103
+ /**
104
+ * Parse structured action results from tool execution output.
105
+ * When the agent calls tools like `edit_current_entity`, `save_current_entity`,
106
+ * `navigate_to`, or `test_tool_by_id`, the result contains an action payload
107
+ * that the SDK emits as a typed event for the host app to handle.
108
+ */
109
+ private parseActionResult;
56
110
  private handleBroadcast;
57
111
  }
58
112
 
@@ -93,8 +147,11 @@ export declare class AikaaraChatWidget extends HTMLElement {
93
147
  attributeChangedCallback(_name: string, oldVal: string, newVal: string): void;
94
148
  configure(config: Partial<WidgetConfig>): void;
95
149
  private getConfig;
150
+ setUploadAdapter(adapter: UploadAdapter): void;
96
151
  private render;
97
152
  private initController;
153
+ sendUserEvent(eventKey: string, value?: Record<string, unknown>, source?: string): void;
154
+ getClient(): AikaaraChatClient | null;
98
155
  private darkenColor;
99
156
  }
100
157
 
@@ -110,11 +167,19 @@ export declare class AikaaraErrorBanner extends HTMLElement {
110
167
 
111
168
  export declare class AikaaraMessageBubble extends HTMLElement {
112
169
  private shadow;
170
+ private templatePayload;
171
+ private attachments;
113
172
  static get observedAttributes(): string[];
114
173
  constructor();
115
174
  connectedCallback(): void;
116
175
  attributeChangedCallback(): void;
176
+ setTemplatePayload(payload: unknown): void;
177
+ setAttachments(attachments: Array<{
178
+ fileName: string;
179
+ fileUrl: string;
180
+ }>): void;
117
181
  private render;
182
+ private renderAttachments;
118
183
  }
119
184
 
120
185
  export declare class AikaaraMessageList extends HTMLElement {
@@ -133,6 +198,13 @@ export declare class AikaaraMessageList extends HTMLElement {
133
198
  showTypingIndicator(): void;
134
199
  removeTypingIndicator(): void;
135
200
  private appendMessageElement;
201
+ /**
202
+ * Replace an existing rendered message (matched by id or externalId) in place.
203
+ * Used when a Tiledesk self-echo reconciles with an optimistic bubble or when
204
+ * a status update flips delivered → read.
205
+ */
206
+ upsertMessage(message: Message): void;
207
+ private findRenderedMessage;
136
208
  private scrollToBottom;
137
209
  private formatTime;
138
210
  }
@@ -157,19 +229,36 @@ export declare class AikaaraTypingIndicator extends HTMLElement {
157
229
  export declare class ApiClient {
158
230
  private baseUrl;
159
231
  private apiKey?;
232
+ private authToken?;
160
233
  private userToken;
161
- constructor(baseUrl: string, userToken: string, apiKey?: string);
234
+ constructor(baseUrl: string, userToken: string, apiKey?: string, authToken?: string);
162
235
  createConversation(params: {
163
236
  systemPromptId?: number;
164
237
  channel?: string;
165
238
  title?: string;
166
239
  extUid?: string;
167
240
  }): Promise<CreateConversationResponse>;
241
+ updateContext(conversationId: string, context: Record<string, unknown>): Promise<void>;
168
242
  getMessages(conversationId: string): Promise<Message[]>;
169
243
  private mapMessage;
170
244
  private request;
171
245
  }
172
246
 
247
+ export declare interface AppContext {
248
+ /** Current page/route path in the host app (e.g., '/products/42') */
249
+ currentPage: string;
250
+ /** Entity type on the current page (e.g., 'product', 'agent') */
251
+ entityType?: string;
252
+ /** Entity ID on the current page */
253
+ entityId?: string | number;
254
+ /** Project/workspace ID if applicable */
255
+ projectId?: string | number;
256
+ /** Routes the agent can navigate to — map of label → path */
257
+ availableRoutes?: Record<string, string>;
258
+ /** Additional context for the agent (e.g., form field names, entity schema) */
259
+ custom?: Record<string, unknown>;
260
+ }
261
+
173
262
  export declare class ChannelSubscription {
174
263
  readonly identifier: string;
175
264
  private callbacks;
@@ -188,15 +277,35 @@ export declare class ChannelSubscription {
188
277
 
189
278
  export declare interface ChatClientConfig extends ConnectionConfig {
190
279
  apiKey?: string;
280
+ authToken?: string;
191
281
  extUid?: string;
192
282
  conversationId?: string;
193
283
  systemPromptId?: number;
194
- channel?: 'widget' | 'api';
284
+ channel?: 'widget' | 'api' | 'sidekick';
285
+ /**
286
+ * Transport selection.
287
+ * - `aikaara` (default): ActionCable to Aikaara Rails (AI streaming).
288
+ * - `tiledesk`: MQTT direct to a self-hosted Tiledesk + chat21 stack.
289
+ * - `dual`: both — Aikaara cable for AI, Tiledesk MQTT for live-agent + file events.
290
+ */
291
+ transport?: TransportMode;
292
+ /**
293
+ * Tiledesk-side identity. Required when `transport` is `tiledesk` or `dual`.
294
+ * `userId` here is the Tiledesk user `_id` and is also used as the SDK conversation
295
+ * subject — Aikaara conversations bound to this user via ext_uid mapping.
296
+ */
297
+ tiledeskIdentity?: {
298
+ userId: string;
299
+ userName?: string;
300
+ departmentId?: string;
301
+ senderFullname?: string;
302
+ };
195
303
  onMessage?: (message: Message) => void;
196
304
  onStatusChange?: (status: string) => void;
197
305
  onError?: (error: Error) => void;
198
306
  onStreamUpdate?: (delta: string, fullContent: string) => void;
199
307
  onConnectionStateChange?: (state: ConnectionState) => void;
308
+ onTemplateMessage?: (template: TemplateMessageEvent) => void;
200
309
  }
201
310
 
202
311
  export declare interface ChatEvents {
@@ -222,12 +331,26 @@ export declare interface ChatEvents {
222
331
  'typing:stop': void;
223
332
  'error': Error;
224
333
  'status': string;
334
+ 'action:edit_entity': EditEntityAction;
335
+ 'action:save_entity': SaveEntityAction;
336
+ 'action:test_tool': TestToolAction;
337
+ 'action:navigate': NavigateAction;
338
+ 'tool:start': {
339
+ toolName: string;
340
+ args: Record<string, unknown>;
341
+ };
342
+ 'tool:end': {
343
+ toolName: string;
344
+ result: unknown;
345
+ isError: boolean;
346
+ };
225
347
  }
226
348
 
227
349
  export declare interface ConnectionConfig {
228
350
  baseUrl: string;
229
351
  wsUrl?: string;
230
352
  userToken: string;
353
+ tiledesk?: TiledeskTransportConfig;
231
354
  reconnect?: boolean;
232
355
  maxReconnectAttempts?: number;
233
356
  reconnectInterval?: number;
@@ -270,6 +393,15 @@ declare interface CreateConversationResponse {
270
393
  status: string;
271
394
  }
272
395
 
396
+ export declare function createFetchUploadAdapter(config: FetchUploadAdapterConfig): UploadAdapter;
397
+
398
+ export declare interface EditEntityAction {
399
+ action: 'edit_entity';
400
+ entity_type: string;
401
+ entity_id: string | number;
402
+ fields: FieldUpdate[];
403
+ }
404
+
273
405
  export declare class EventEmitter<Events extends Record<string, any>> {
274
406
  private handlers;
275
407
  on<K extends keyof Events & string>(event: K, handler: (data: Events[K]) => void): () => void;
@@ -278,10 +410,153 @@ export declare class EventEmitter<Events extends Record<string, any>> {
278
410
  removeAllListeners(): void;
279
411
  }
280
412
 
413
+ export declare function extractTiledeskFileEnvelope(message: TiledeskMessage): TiledeskFileEnvelope | null;
414
+
415
+ export declare interface FetchUploadAdapterConfig {
416
+ endpoint: string;
417
+ method?: 'POST' | 'PUT';
418
+ fieldName?: string;
419
+ headers?: Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);
420
+ credentials?: RequestCredentials;
421
+ extraFields?: Record<string, string> | ((ctx: UploadAdapterContext) => Record<string, string>);
422
+ parseResponse?: (raw: unknown, ctx: UploadAdapterContext) => UploadAdapterResult;
423
+ }
424
+
425
+ export declare interface FieldUpdate {
426
+ field: string;
427
+ value: unknown;
428
+ previousValue?: unknown;
429
+ }
430
+
431
+ export declare class FormBridge extends EventEmitter<FormBridgeEvents> {
432
+ private registration;
433
+ private pendingEdits;
434
+ constructor(client: AikaaraChatClient);
435
+ /**
436
+ * Register a form to receive AI-driven edits.
437
+ * Only one form can be registered at a time (the active page).
438
+ */
439
+ registerForm(reg: FormRegistration): void;
440
+ /**
441
+ * Unregister the form (call on unmount).
442
+ */
443
+ unregisterForm(entityType: string, entityId: string | number): void;
444
+ /**
445
+ * Get the current form registration (if any).
446
+ */
447
+ get currentForm(): FormRegistration | null;
448
+ /**
449
+ * Manually push field updates (for custom tool handling).
450
+ */
451
+ pushFieldUpdates(entityType: string, entityId: string | number, fields: FieldUpdate[]): void;
452
+ /**
453
+ * Request the current form to save.
454
+ */
455
+ requestSave(): Promise<{
456
+ success: boolean;
457
+ error?: string;
458
+ }>;
459
+ /**
460
+ * Request the current form to run a test.
461
+ */
462
+ requestTest(params?: Record<string, unknown>): Promise<{
463
+ success: boolean;
464
+ error?: string;
465
+ }>;
466
+ private setupListeners;
467
+ }
468
+
469
+ /**
470
+ * FormBridge — Enables AI agents to visually edit forms in the host application.
471
+ *
472
+ * This bridges the gap between AI tool results and UI form state. When the agent
473
+ * calls tools like `edit_current_entity`, the FormBridge receives the action and
474
+ * pushes field updates to the registered form.
475
+ *
476
+ * ## Usage (any framework)
477
+ *
478
+ * ```typescript
479
+ * import { AikaaraChatClient, FormBridge } from '@aikaara/chat-sdk/headless';
480
+ *
481
+ * const client = new AikaaraChatClient({ baseUrl, userToken, authToken });
482
+ * const bridge = new FormBridge(client);
483
+ *
484
+ * // Register a form (call when your form mounts)
485
+ * bridge.registerForm({
486
+ * entityType: 'product',
487
+ * entityId: 42,
488
+ * onFieldUpdate: (fields) => {
489
+ * for (const { field, value } of fields) {
490
+ * formState[field] = value; // update your form framework
491
+ * }
492
+ * },
493
+ * onSave: async () => await api.saveProduct(42, formState),
494
+ * getCurrentValues: () => ({ ...formState }),
495
+ * });
496
+ *
497
+ * // Unregister when form unmounts
498
+ * bridge.unregisterForm('product', 42);
499
+ * ```
500
+ *
501
+ * ## React hook (provided by dashboard, but easy to replicate)
502
+ *
503
+ * ```tsx
504
+ * function useFormBridge(bridge, { entityType, entityId, onFieldUpdate, onSave }) {
505
+ * useEffect(() => {
506
+ * bridge.registerForm({ entityType, entityId, onFieldUpdate, onSave, getCurrentValues });
507
+ * return () => bridge.unregisterForm(entityType, entityId);
508
+ * }, [entityType, entityId]);
509
+ * }
510
+ * ```
511
+ */
512
+ export declare interface FormBridgeEvents {
513
+ 'edit:applied': {
514
+ entityType: string;
515
+ entityId: string | number;
516
+ fields: FieldUpdate[];
517
+ };
518
+ 'edit:pending': {
519
+ entityType: string;
520
+ entityId: string | number;
521
+ fields: FieldUpdate[];
522
+ };
523
+ 'save:success': {
524
+ entityType: string;
525
+ entityId: string | number;
526
+ };
527
+ 'save:error': {
528
+ entityType: string;
529
+ entityId: string | number;
530
+ error: string;
531
+ };
532
+ 'test:triggered': {
533
+ toolId: number;
534
+ parameters: Record<string, unknown>;
535
+ };
536
+ }
537
+
538
+ export declare interface FormRegistration {
539
+ entityType: string;
540
+ entityId: string | number;
541
+ onFieldUpdate: (fields: FieldUpdate[]) => void;
542
+ onSave: () => Promise<void>;
543
+ onTest?: (params?: Record<string, unknown>) => Promise<void>;
544
+ getCurrentValues: () => Record<string, unknown>;
545
+ }
546
+
547
+ export declare function inferTiledeskRole(message: TiledeskMessage, cfg: TiledeskRoleConfig): TiledeskRole;
548
+
549
+ /**
550
+ * Self-echo detector — Tiledesk fans the user's outgoing publish back
551
+ * as a `clientadded` event on the same connection. UI must dedupe against
552
+ * the optimistic local message rather than rendering twice.
553
+ */
554
+ export declare function isTiledeskSelfEcho(message: TiledeskMessage, userId: string): boolean;
555
+
281
556
  export declare interface Message {
282
557
  id: string;
283
558
  conversationId: string;
284
- role: 'user' | 'assistant' | 'system' | 'tool';
559
+ role: 'user' | 'assistant' | 'system' | 'tool' | 'agent';
285
560
  content: string;
286
561
  toolCalls?: ToolCall[];
287
562
  toolCallResults?: ToolCallResult;
@@ -289,7 +564,19 @@ export declare interface Message {
289
564
  tokensOutput?: number;
290
565
  metadata?: Record<string, unknown>;
291
566
  createdAt: string;
292
- status?: 'sending' | 'sent' | 'streaming' | 'complete' | 'error';
567
+ status?: 'sending' | 'sent' | 'delivered' | 'read' | 'streaming' | 'complete' | 'error';
568
+ externalId?: string;
569
+ template?: {
570
+ contentType?: string;
571
+ templateId?: string;
572
+ payload?: unknown;
573
+ };
574
+ attachments?: Array<{
575
+ fileName: string;
576
+ fileUrl: string;
577
+ cloudFileId?: string;
578
+ contentType?: string;
579
+ }>;
293
580
  }
294
581
 
295
582
  export declare class MessageStore {
@@ -297,6 +584,22 @@ export declare class MessageStore {
297
584
  private optimisticCounter;
298
585
  get messages(): Message[];
299
586
  addOptimistic(role: 'user', content: string, conversationId: string): Message;
587
+ /**
588
+ * Reconcile a remote message against an outstanding optimistic message.
589
+ * Tiledesk fans the user's outgoing publish back as an inbound clientadded —
590
+ * dedupe by exact content + recency window so the optimistic bubble keeps
591
+ * its position and we don't render duplicates.
592
+ */
593
+ reconcileOptimistic(remote: Message, recencyMs?: number): Message | null;
594
+ /**
595
+ * Append a remote-originated message (e.g. from Tiledesk MQTT). If a matching
596
+ * optimistic message exists it is reconciled in place; otherwise appended.
597
+ */
598
+ upsertRemoteMessage(remote: Message): {
599
+ message: Message;
600
+ deduped: boolean;
601
+ };
602
+ updateMessageStatus(externalId: string, status: Message['status']): Message | undefined;
300
603
  confirmOptimistic(tempId: string): void;
301
604
  addStreamingMessage(conversationId: string): Message;
302
605
  updateStreaming(content: string): void;
@@ -313,10 +616,213 @@ export declare class MessageStore {
313
616
 
314
617
  export declare function mount(config: WidgetConfig): AikaaraChatWidget;
315
618
 
619
+ export declare interface NavigateAction {
620
+ navigate_to: string;
621
+ }
622
+
623
+ export declare function parseTiledeskTemplate(message: TiledeskMessage): TiledeskParsedTemplate;
624
+
316
625
  export declare function registerComponents(): void;
317
626
 
627
+ export declare interface SaveEntityAction {
628
+ action: 'save_entity';
629
+ }
630
+
318
631
  declare type SubscriptionCallback = (data: unknown) => void;
319
632
 
633
+ declare interface TemplateMessageEvent {
634
+ messageId: string;
635
+ conversationId: string;
636
+ role: 'user' | 'assistant' | 'system' | 'agent';
637
+ contentType?: string;
638
+ templateId?: string;
639
+ payload?: unknown;
640
+ innerMessage?: string;
641
+ raw: unknown;
642
+ }
643
+
644
+ export declare interface TestToolAction {
645
+ action: 'test_tool';
646
+ tool_id: number;
647
+ parameters: Record<string, unknown>;
648
+ }
649
+
650
+ export declare interface TiledeskFileEnvelope {
651
+ fileName?: string;
652
+ fileUrl?: string;
653
+ cloudFileId?: string;
654
+ templateId?: string;
655
+ }
656
+
657
+ export declare interface TiledeskFileMessageInput {
658
+ fileName: string;
659
+ fileUrl: string;
660
+ cloudFileId?: string;
661
+ templateId?: string;
662
+ headerImgSrc?: string;
663
+ type?: 'link' | 'image';
664
+ isDeepLink?: boolean;
665
+ description?: string;
666
+ attributes?: Record<string, unknown>;
667
+ metadata?: Record<string, unknown>;
668
+ }
669
+
670
+ export declare interface TiledeskFileTemplateConfig {
671
+ templateId: string;
672
+ headerImgSrc?: string;
673
+ type?: 'link' | 'image';
674
+ isDeepLink?: boolean;
675
+ }
676
+
677
+ export declare interface TiledeskMessage {
678
+ text?: string;
679
+ type?: string;
680
+ sender?: string;
681
+ senderFullname?: string;
682
+ sender_fullname?: string;
683
+ recipient?: string;
684
+ recipient_fullname?: string;
685
+ channel_type?: string;
686
+ timestamp?: number;
687
+ app_id?: string;
688
+ message_id?: string;
689
+ status?: number;
690
+ attributes?: Record<string, unknown>;
691
+ metadata?: Record<string, unknown>;
692
+ [key: string]: unknown;
693
+ }
694
+
695
+ export declare interface TiledeskMessageContext {
696
+ topic: string;
697
+ conversationId?: string;
698
+ messageId?: string;
699
+ kind: 'clientadded' | 'update' | 'unknown';
700
+ }
701
+
702
+ export declare interface TiledeskMessageDefaults {
703
+ channelType?: string;
704
+ channel?: string;
705
+ requestChannel?: string;
706
+ platform?: string;
707
+ medium?: string;
708
+ departmentId?: string;
709
+ attributes?: Record<string, unknown>;
710
+ }
711
+
712
+ export declare interface TiledeskParsedTemplate {
713
+ contentType?: string;
714
+ templateId?: string;
715
+ payload?: unknown;
716
+ innerMessage?: string;
717
+ raw: TiledeskMessage;
718
+ }
719
+
720
+ export declare type TiledeskRole = 'user' | 'assistant' | 'system' | 'agent';
721
+
722
+ export declare interface TiledeskRoleConfig {
723
+ userId: string;
724
+ systemSenders?: string[];
725
+ botSenderPrefix?: string;
726
+ }
727
+
728
+ export declare interface TiledeskStatusUpdate {
729
+ conversationId: string;
730
+ messageId: string;
731
+ status: number;
732
+ raw: Record<string, unknown>;
733
+ }
734
+
735
+ export declare interface TiledeskTopicTemplates {
736
+ inbound?: string;
737
+ inboundUpdate?: string;
738
+ outbound?: string;
739
+ presence?: string;
740
+ wildcardSubscribe?: string;
741
+ }
742
+
743
+ export declare class TiledeskTransport {
744
+ private client;
745
+ private config;
746
+ private currentToken;
747
+ private clientId;
748
+ private appId;
749
+ private topics;
750
+ private messageHandlers;
751
+ private stateHandlers;
752
+ private statusUpdateHandlers;
753
+ private subscribedTopics;
754
+ private reconnectAttempt;
755
+ private maxReconnectAttempts;
756
+ private reconnectMaxDelayMs;
757
+ private disposed;
758
+ private reconnectTimer;
759
+ private inboundRegex;
760
+ private inboundUpdateRegex;
761
+ constructor(config: TiledeskTransportConfig);
762
+ connect(): Promise<void>;
763
+ subscribeWildcard(): void;
764
+ subscribeToConversation(conversationId: string): void;
765
+ unsubscribeFromConversation(conversationId: string): void;
766
+ publishMessage(conversationId: string, text: string, overrides?: Partial<TiledeskMessage>): void;
767
+ publishFileMessage(conversationId: string, file: TiledeskFileMessageInput): void;
768
+ publishRaw(conversationId: string, message: TiledeskMessage): void;
769
+ /**
770
+ * Send a read receipt for a message. Tiledesk widgets publish
771
+ * `{"status":300}` to apps/{appId}/users/{userId}/messages/{convId}/{msgId}/update.
772
+ */
773
+ publishReadReceipt(conversationId: string, messageId: string, status?: number): void;
774
+ /**
775
+ * Trigger conversation kickoff. Tiledesk bot routing waits for the
776
+ * widget to publish a CHAT_INITIATED event before the bot replies.
777
+ */
778
+ publishChatInitiated(conversationId: string, extraAttributes?: Record<string, unknown>): void;
779
+ onMessage(handler: TransportMessageHandler): () => void;
780
+ onStateChange(handler: TransportStateHandler): () => void;
781
+ onStatusUpdate(handler: TransportStatusUpdateHandler): () => void;
782
+ disconnect(): void;
783
+ get isConnected(): boolean;
784
+ private scheduleReconnect;
785
+ private notifyStateChange;
786
+ private dispatchInbound;
787
+ private buildOutgoingEnvelope;
788
+ private publishEnvelope;
789
+ private renderInboundTopic;
790
+ private renderOutboundTopic;
791
+ private renderPresenceTopic;
792
+ private renderTemplate;
793
+ private buildTopicRegex;
794
+ }
795
+
796
+ export declare interface TiledeskTransportConfig {
797
+ mqttEndpoint: string;
798
+ jwtToken: string;
799
+ userId: string;
800
+ userName?: string;
801
+ projectId: string;
802
+ appId?: string;
803
+ clientId?: string;
804
+ protocolVersion?: 3 | 4 | 5;
805
+ protocolId?: 'MQIsdp' | 'MQTT';
806
+ mqttUsername?: string;
807
+ connectTimeoutMs?: number;
808
+ keepAliveSec?: number;
809
+ maxReconnectAttempts?: number;
810
+ reconnectMaxDelayMs?: number;
811
+ tokenProvider?: () => Promise<string>;
812
+ wildcardSubscribe?: boolean;
813
+ subscribeQos?: 0 | 1 | 2;
814
+ publishQos?: 0 | 1 | 2;
815
+ publishRetain?: boolean;
816
+ enablePresence?: boolean;
817
+ presencePayloadConnected?: Record<string, unknown>;
818
+ presencePayloadDisconnected?: Record<string, unknown>;
819
+ topicTemplates?: TiledeskTopicTemplates;
820
+ messageDefaults?: TiledeskMessageDefaults;
821
+ fileTemplate?: TiledeskFileTemplateConfig;
822
+ recipientFullnameResolver?: (conversationId: string) => string | undefined;
823
+ senderFullname?: string;
824
+ }
825
+
320
826
  export declare interface ToolCall {
321
827
  id: string;
322
828
  type: 'function';
@@ -331,8 +837,37 @@ export declare interface ToolCallResult {
331
837
  content: string;
332
838
  }
333
839
 
840
+ export declare type TransportMessageHandler = (message: TiledeskMessage, ctx: TiledeskMessageContext) => void;
841
+
842
+ declare type TransportMode = 'aikaara' | 'tiledesk' | 'dual';
843
+
844
+ export declare type TransportStateHandler = (connected: boolean) => void;
845
+
846
+ export declare type TransportStatusUpdateHandler = (update: TiledeskStatusUpdate) => void;
847
+
334
848
  export declare function unmount(): void;
335
849
 
850
+ export declare interface UploadAdapter {
851
+ upload(file: File | Blob, ctx: UploadAdapterContext): Promise<UploadAdapterResult>;
852
+ }
853
+
854
+ export declare interface UploadAdapterContext {
855
+ conversationId: string;
856
+ userId: string;
857
+ projectId?: string;
858
+ appId?: string;
859
+ }
860
+
861
+ export declare interface UploadAdapterResult {
862
+ url: string;
863
+ fileName: string;
864
+ cloudFileId?: string;
865
+ relativePath?: string;
866
+ contentType?: string;
867
+ byteSize?: number;
868
+ meta?: Record<string, unknown>;
869
+ }
870
+
336
871
  export declare interface WidgetConfig extends ChatClientConfig {
337
872
  position?: 'bottom-right' | 'bottom-left';
338
873
  offset?: {
@@ -355,6 +890,7 @@ export declare interface WidgetConfig extends ChatClientConfig {
355
890
  showBubble?: boolean;
356
891
  bubbleText?: string;
357
892
  bubbleIcon?: string;
893
+ uploadAdapter?: UploadAdapter;
358
894
  }
359
895
 
360
896
  export { }