@aikaara/chat-sdk 0.1.4 → 0.2.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.
@@ -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;
@@ -44,26 +46,68 @@ export declare class AikaaraChatClient extends EventEmitter<ChatEvents> {
44
46
  get messages(): Message[];
45
47
  get conversationId(): string | null;
46
48
  get isConnected(): boolean;
49
+ /**
50
+ * Update the agent's context with information about the host app's current state.
51
+ * Call this on route changes so the agent knows what page/entity the user is viewing.
52
+ *
53
+ * The context is stored in conversation metadata and interpolated into the system prompt.
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * // On route change
58
+ * client.setContext({
59
+ * currentPage: '/products/42',
60
+ * entityType: 'product',
61
+ * entityId: '42',
62
+ * availableRoutes: { products: '/products', orders: '/orders' },
63
+ * });
64
+ * ```
65
+ */
66
+ setContext(context: AppContext): Promise<void>;
47
67
  disconnect(): Promise<void>;
68
+ /**
69
+ * Parse structured action results from tool execution output.
70
+ * When the agent calls tools like `edit_current_entity`, `save_current_entity`,
71
+ * `navigate_to`, or `test_tool_by_id`, the result contains an action payload
72
+ * that the SDK emits as a typed event for the host app to handle.
73
+ */
74
+ private parseActionResult;
48
75
  private handleBroadcast;
49
76
  }
50
77
 
51
78
  export declare class ApiClient {
52
79
  private baseUrl;
53
80
  private apiKey?;
81
+ private authToken?;
54
82
  private userToken;
55
- constructor(baseUrl: string, userToken: string, apiKey?: string);
83
+ constructor(baseUrl: string, userToken: string, apiKey?: string, authToken?: string);
56
84
  createConversation(params: {
57
85
  systemPromptId?: number;
58
86
  channel?: string;
59
87
  title?: string;
60
88
  extUid?: string;
61
89
  }): Promise<CreateConversationResponse>;
90
+ updateContext(conversationId: string, context: Record<string, unknown>): Promise<void>;
62
91
  getMessages(conversationId: string): Promise<Message[]>;
63
92
  private mapMessage;
64
93
  private request;
65
94
  }
66
95
 
96
+ export declare interface AppContext {
97
+ /** Current page/route path in the host app (e.g., '/products/42') */
98
+ currentPage: string;
99
+ /** Entity type on the current page (e.g., 'product', 'agent') */
100
+ entityType?: string;
101
+ /** Entity ID on the current page */
102
+ entityId?: string | number;
103
+ /** Project/workspace ID if applicable */
104
+ projectId?: string | number;
105
+ /** Routes the agent can navigate to — map of label → path */
106
+ availableRoutes?: Record<string, string>;
107
+ /** Additional context for the agent (e.g., form field names, entity schema) */
108
+ custom?: Record<string, unknown>;
109
+ }
110
+
67
111
  export declare class ChannelSubscription {
68
112
  readonly identifier: string;
69
113
  private callbacks;
@@ -82,10 +126,11 @@ export declare class ChannelSubscription {
82
126
 
83
127
  export declare interface ChatClientConfig extends ConnectionConfig {
84
128
  apiKey?: string;
129
+ authToken?: string;
85
130
  extUid?: string;
86
131
  conversationId?: string;
87
132
  systemPromptId?: number;
88
- channel?: 'widget' | 'api';
133
+ channel?: 'widget' | 'api' | 'sidekick';
89
134
  onMessage?: (message: Message) => void;
90
135
  onStatusChange?: (status: string) => void;
91
136
  onError?: (error: Error) => void;
@@ -116,12 +161,26 @@ export declare interface ChatEvents {
116
161
  'typing:stop': void;
117
162
  'error': Error;
118
163
  'status': string;
164
+ 'action:edit_entity': EditEntityAction;
165
+ 'action:save_entity': SaveEntityAction;
166
+ 'action:test_tool': TestToolAction;
167
+ 'action:navigate': NavigateAction;
168
+ 'tool:start': {
169
+ toolName: string;
170
+ args: Record<string, unknown>;
171
+ };
172
+ 'tool:end': {
173
+ toolName: string;
174
+ result: unknown;
175
+ isError: boolean;
176
+ };
119
177
  }
120
178
 
121
179
  export declare interface ConnectionConfig {
122
180
  baseUrl: string;
123
181
  wsUrl?: string;
124
182
  userToken: string;
183
+ tiledesk?: TiledeskTransportConfig;
125
184
  reconnect?: boolean;
126
185
  maxReconnectAttempts?: number;
127
186
  reconnectInterval?: number;
@@ -164,6 +223,13 @@ declare interface CreateConversationResponse {
164
223
  status: string;
165
224
  }
166
225
 
226
+ export declare interface EditEntityAction {
227
+ action: 'edit_entity';
228
+ entity_type: string;
229
+ entity_id: string | number;
230
+ fields: FieldUpdate[];
231
+ }
232
+
167
233
  export declare class EventEmitter<Events extends Record<string, any>> {
168
234
  private handlers;
169
235
  on<K extends keyof Events & string>(event: K, handler: (data: Events[K]) => void): () => void;
@@ -172,6 +238,128 @@ export declare class EventEmitter<Events extends Record<string, any>> {
172
238
  removeAllListeners(): void;
173
239
  }
174
240
 
241
+ export declare interface FieldUpdate {
242
+ field: string;
243
+ value: unknown;
244
+ previousValue?: unknown;
245
+ }
246
+
247
+ export declare class FormBridge extends EventEmitter<FormBridgeEvents> {
248
+ private registration;
249
+ private pendingEdits;
250
+ constructor(client: AikaaraChatClient);
251
+ /**
252
+ * Register a form to receive AI-driven edits.
253
+ * Only one form can be registered at a time (the active page).
254
+ */
255
+ registerForm(reg: FormRegistration): void;
256
+ /**
257
+ * Unregister the form (call on unmount).
258
+ */
259
+ unregisterForm(entityType: string, entityId: string | number): void;
260
+ /**
261
+ * Get the current form registration (if any).
262
+ */
263
+ get currentForm(): FormRegistration | null;
264
+ /**
265
+ * Manually push field updates (for custom tool handling).
266
+ */
267
+ pushFieldUpdates(entityType: string, entityId: string | number, fields: FieldUpdate[]): void;
268
+ /**
269
+ * Request the current form to save.
270
+ */
271
+ requestSave(): Promise<{
272
+ success: boolean;
273
+ error?: string;
274
+ }>;
275
+ /**
276
+ * Request the current form to run a test.
277
+ */
278
+ requestTest(params?: Record<string, unknown>): Promise<{
279
+ success: boolean;
280
+ error?: string;
281
+ }>;
282
+ private setupListeners;
283
+ }
284
+
285
+ /**
286
+ * FormBridge — Enables AI agents to visually edit forms in the host application.
287
+ *
288
+ * This bridges the gap between AI tool results and UI form state. When the agent
289
+ * calls tools like `edit_current_entity`, the FormBridge receives the action and
290
+ * pushes field updates to the registered form.
291
+ *
292
+ * ## Usage (any framework)
293
+ *
294
+ * ```typescript
295
+ * import { AikaaraChatClient, FormBridge } from '@aikaara/chat-sdk/headless';
296
+ *
297
+ * const client = new AikaaraChatClient({ baseUrl, userToken, authToken });
298
+ * const bridge = new FormBridge(client);
299
+ *
300
+ * // Register a form (call when your form mounts)
301
+ * bridge.registerForm({
302
+ * entityType: 'product',
303
+ * entityId: 42,
304
+ * onFieldUpdate: (fields) => {
305
+ * for (const { field, value } of fields) {
306
+ * formState[field] = value; // update your form framework
307
+ * }
308
+ * },
309
+ * onSave: async () => await api.saveProduct(42, formState),
310
+ * getCurrentValues: () => ({ ...formState }),
311
+ * });
312
+ *
313
+ * // Unregister when form unmounts
314
+ * bridge.unregisterForm('product', 42);
315
+ * ```
316
+ *
317
+ * ## React hook (provided by dashboard, but easy to replicate)
318
+ *
319
+ * ```tsx
320
+ * function useFormBridge(bridge, { entityType, entityId, onFieldUpdate, onSave }) {
321
+ * useEffect(() => {
322
+ * bridge.registerForm({ entityType, entityId, onFieldUpdate, onSave, getCurrentValues });
323
+ * return () => bridge.unregisterForm(entityType, entityId);
324
+ * }, [entityType, entityId]);
325
+ * }
326
+ * ```
327
+ */
328
+ export declare interface FormBridgeEvents {
329
+ 'edit:applied': {
330
+ entityType: string;
331
+ entityId: string | number;
332
+ fields: FieldUpdate[];
333
+ };
334
+ 'edit:pending': {
335
+ entityType: string;
336
+ entityId: string | number;
337
+ fields: FieldUpdate[];
338
+ };
339
+ 'save:success': {
340
+ entityType: string;
341
+ entityId: string | number;
342
+ };
343
+ 'save:error': {
344
+ entityType: string;
345
+ entityId: string | number;
346
+ error: string;
347
+ };
348
+ 'test:triggered': {
349
+ toolId: number;
350
+ parameters: Record<string, unknown>;
351
+ };
352
+ }
353
+
354
+ export declare interface FormRegistration {
355
+ entityType: string;
356
+ entityId: string | number;
357
+ onFieldUpdate: (fields: FieldUpdate[]) => void;
358
+ onSave: () => Promise<void>;
359
+ onTest?: (params?: Record<string, unknown>) => Promise<void>;
360
+ getCurrentValues: () => Record<string, unknown>;
361
+ }
362
+
175
363
  export declare interface Message {
176
364
  id: string;
177
365
  conversationId: string;
@@ -205,8 +393,64 @@ export declare class MessageStore {
205
393
  clear(): void;
206
394
  }
207
395
 
396
+ export declare interface NavigateAction {
397
+ navigate_to: string;
398
+ }
399
+
400
+ export declare interface SaveEntityAction {
401
+ action: 'save_entity';
402
+ }
403
+
208
404
  declare type SubscriptionCallback = (data: unknown) => void;
209
405
 
406
+ export declare interface TestToolAction {
407
+ action: 'test_tool';
408
+ tool_id: number;
409
+ parameters: Record<string, unknown>;
410
+ }
411
+
412
+ export declare interface TiledeskMessage {
413
+ text?: string;
414
+ type?: string;
415
+ sender?: string;
416
+ senderFullname?: string;
417
+ recipient?: string;
418
+ timestamp?: number;
419
+ attributes?: Record<string, unknown>;
420
+ metadata?: Record<string, unknown>;
421
+ [key: string]: unknown;
422
+ }
423
+
424
+ export declare class TiledeskTransport {
425
+ private client;
426
+ private config;
427
+ private messageHandlers;
428
+ private stateHandlers;
429
+ private subscribedTopics;
430
+ private reconnectAttempt;
431
+ private maxReconnectAttempts;
432
+ private disposed;
433
+ constructor(config: TiledeskTransportConfig);
434
+ connect(): Promise<void>;
435
+ subscribeToConversation(conversationId: string): void;
436
+ unsubscribeFromConversation(conversationId: string): void;
437
+ publishMessage(conversationId: string, text: string): void;
438
+ onMessage(handler: TransportMessageHandler): () => void;
439
+ onStateChange(handler: TransportStateHandler): () => void;
440
+ disconnect(): void;
441
+ get isConnected(): boolean;
442
+ private scheduleReconnect;
443
+ private notifyStateChange;
444
+ }
445
+
446
+ export declare interface TiledeskTransportConfig {
447
+ mqttEndpoint: string;
448
+ jwtToken: string;
449
+ userId: string;
450
+ userName?: string;
451
+ projectId: string;
452
+ }
453
+
210
454
  export declare interface ToolCall {
211
455
  id: string;
212
456
  type: 'function';
@@ -221,6 +465,10 @@ export declare interface ToolCallResult {
221
465
  content: string;
222
466
  }
223
467
 
468
+ export declare type TransportMessageHandler = (message: TiledeskMessage) => void;
469
+
470
+ export declare type TransportStateHandler = (connected: boolean) => void;
471
+
224
472
  export declare interface WidgetConfig extends ChatClientConfig {
225
473
  position?: 'bottom-right' | 'bottom-left';
226
474
  offset?: {