@foisit/angular-wrapper 1.2.0 β†’ 2.1.1

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.
Files changed (2) hide show
  1. package/README.md +558 -121
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,216 +1,653 @@
1
- # πŸŽ™οΈ Foisit Angular Wrapper: Speak, and it’s Done.
1
+ # @foisit/angular-wrapper
2
2
 
3
- The **Foisit Angular Wrapper** brings voice interactivity to your Angular apps with the power of the **Foisit Assistant**. Imagine saying "background red" and watching your app come aliveβ€”now that's ✨magic✨!
3
+ [![npm version](https://img.shields.io/npm/v/@foisit/angular-wrapper.svg)](https://www.npmjs.com/package/@foisit/angular-wrapper)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
5
 
5
- ### **Why Foisit Angular Wrapper?**
6
+ > **The AI-Powered Conversational Assistant for Angular Applications**
6
7
 
7
- - 🧩 **Dynamic Commands**: Add or remove commands on the fly.
8
- - 🎨 **Visual Feedback**: Show visual cues when the assistant is active.
9
- - πŸš€ **Effortless Integration**: Set up voice commands in minutes with minimal code.
10
- - πŸ—£οΈ **Voice Feedback**: Interactive voice responses make the assistant engaging.
11
- - πŸ”„ **Double Activation**: Activate or put the assistant to sleep with a double-tap.
8
+ Transform your Angular app into an intelligent, voice-ready platform. Foisit provides a drop-in AI layer that understands natural language, manages multi-step workflows, and executes actionsβ€”all with zero backend required.
12
9
 
13
- ### 🌐 **Live Demo**
10
+ > [!NOTE]
11
+ > πŸŽ™οΈ **Voice Support Status**: Voice recognition and responses are currently in development and will be released in a future update. The current version focuses on high-performance text-based interactions and AI intent matching.
14
12
 
15
- πŸŽ‰ [Test the Angular Assistant here!](https://ng-foisit-demo.netlify.app/)
13
+ ---
14
+
15
+ ## πŸ“‹ Table of Contents
16
+
17
+ - [Features](#-features)
18
+ - [Installation](#-installation)
19
+ - [Quick Start](#-quick-start)
20
+ - [Core Concepts](#-core-concepts)
21
+ - [API Reference](#-api-reference)
22
+ - [Advanced Usage](#-advanced-usage)
23
+ - [Examples](#-examples)
24
+ - [TypeScript Support](#-typescript-support)
25
+ - [Best Practices](#-best-practices)
16
26
 
17
27
  ---
18
28
 
19
- ## πŸš€ Installation
29
+ ## ✨ Features
30
+
31
+ - **🧠 Natural Language Understanding** - AI-powered intent matching using GPT-4o mini (proxied securely)
32
+ - **πŸ“ Smart Slot Filling** - Auto-generates forms for missing parameters
33
+ - **⚠️ Critical Action Protection** - Built-in confirmation dialogs for dangerous operations
34
+ - **🎨 Premium UI** - Glassmorphic overlay with dark/light mode support
35
+ - **πŸ”’ Zero Backend Required** - Secure proxy architecture keeps API keys server-side
36
+ - **⚑ Angular Native** - Uses Dependency Injection, Signals, and RxJS
37
+ - **🎯 Type-Safe** - Full TypeScript support with comprehensive types
38
+ - **πŸ“± Responsive** - Works flawlessly on desktop and mobile
39
+
40
+ ---
20
41
 
21
- Get started by installing the library:
42
+ ## πŸš€ Installation
22
43
 
23
44
  ```bash
24
45
  npm install @foisit/angular-wrapper
25
46
  ```
26
47
 
27
- or
48
+ ### Peer Dependencies
28
49
 
29
- ```bash
30
- yarn add @foisit/angular-wrapper
50
+ ```json
51
+ {
52
+ "@angular/core": "^17.0.0 || ^18.0.0",
53
+ "@angular/common": "^17.0.0 || ^18.0.0"
54
+ }
31
55
  ```
32
56
 
33
57
  ---
34
58
 
35
- ## πŸ”§ Setup
59
+ ## 🏁 Quick Start
60
+
61
+ ### Step 1: Import the Module
36
62
 
37
- Here's how you can integrate the Foisit Assistant into your Angular app in just a few steps:
63
+ #### For Standalone Apps (Recommended)
38
64
 
39
- ### Step 1: Import the `AssistantModule`
65
+ ```typescript
66
+ // app.config.ts
67
+ import { ApplicationConfig, importProvidersFrom } from '@angular/core';
68
+ import { AssistantModule } from '@foisit/angular-wrapper';
40
69
 
41
- #### Using `forRoot` in `app.module.ts`
70
+ export const appConfig: ApplicationConfig = {
71
+ providers: [
72
+ importProvidersFrom(
73
+ AssistantModule.forRoot({
74
+ introMessage: 'Welcome! How can I assist you today?',
75
+ enableSmartIntent: true,
76
+ commands: [
77
+ {
78
+ command: 'navigate to profile',
79
+ action: () => console.log('Navigating to profile...'),
80
+ },
81
+ ],
82
+ })
83
+ ),
84
+ ],
85
+ };
86
+ ```
87
+
88
+ #### For Module-Based Apps
42
89
 
43
90
  ```typescript
91
+ // app.module.ts
44
92
  import { NgModule } from '@angular/core';
45
- import { BrowserModule } from '@angular/platform-browser';
46
- import { AppComponent } from './app.component';
47
93
  import { AssistantModule } from '@foisit/angular-wrapper';
48
94
 
49
95
  @NgModule({
50
- declarations: [AppComponent],
51
96
  imports: [
52
- BrowserModule,
53
97
  AssistantModule.forRoot({
54
- activationCommand: 'John',
55
- fallbackResponse: 'Sorry, I didn’t understand that.',
98
+ introMessage: 'Welcome! How can I assist you today?',
56
99
  commands: [
57
- { command: 'show profile', action: () => console.log('Showing profile...') },
58
- { command: 'log out', action: () => console.log('Logging out...') },
100
+ /* your commands */
59
101
  ],
60
102
  }),
61
103
  ],
62
- bootstrap: [AppComponent],
63
104
  })
64
105
  export class AppModule {}
65
106
  ```
66
107
 
67
- #### Or Using `app.config.ts` (Latest Versions)
108
+ ### Step 2: Use the Service
68
109
 
69
110
  ```typescript
70
- import { ApplicationConfig, provideZoneChangeDetection, importProvidersFrom } from '@angular/core';
71
- import { provideRouter } from '@angular/router';
72
- import { appRoutes } from './app.routes';
73
- import { AssistantModule } from '@foisit/angular-wrapper';
111
+ // my-component.ts
112
+ import { Component } from '@angular/core';
113
+ import { AssistantService } from '@foisit/angular-wrapper';
74
114
 
75
- export const appConfig: ApplicationConfig = {
76
- providers: [
77
- provideZoneChangeDetection({ eventCoalescing: true }),
78
- provideRouter(appRoutes),
79
- importProvidersFrom(
80
- AssistantModule.forRoot({
81
- activationCommand: 'John',
82
- fallbackResponse: 'Sorry, I didn’t understand that.',
83
- commands: [
84
- { command: 'show profile', action: () => console.log('Showing profile...') },
85
- { command: 'log out', action: () => console.log('Logging out...') },
86
- ],
87
- })
88
- ),
115
+ @Component({
116
+ selector: 'app-my-component',
117
+ template: ` <button (click)="openAssistant()">Open Assistant</button> `,
118
+ })
119
+ export class MyComponent {
120
+ constructor(private assistant: AssistantService) {}
121
+
122
+ openAssistant() {
123
+ this.assistant.toggle();
124
+ }
125
+ }
126
+ ```
127
+
128
+ ---
129
+
130
+ ## 🎯 Core Concepts
131
+
132
+ ### 1. Commands
133
+
134
+ Commands are the building blocks of your assistant. Each command represents an action users can trigger through natural language.
135
+
136
+ ```typescript
137
+ {
138
+ command: 'delete account',
139
+ description: 'Permanently delete user account',
140
+ action: () => this.accountService.delete()
141
+ }
142
+ ```
143
+
144
+ ### 2. Parameters (Slot Filling)
145
+
146
+ Define parameters and Foisit will automatically generate forms to collect them:
147
+
148
+ ```typescript
149
+ {
150
+ command: 'create user',
151
+ description: 'Create a new user account',
152
+ parameters: [
153
+ { name: 'username', type: 'string', required: true },
154
+ { name: 'email', type: 'string', required: true },
155
+ { name: 'age', type: 'number', required: false }
89
156
  ],
90
- };
157
+ action: (params) => this.userService.create(params)
158
+ }
159
+ ```
160
+
161
+ **Supported Parameter Types:**
162
+
163
+ - `string` - Text input
164
+ - `number` - Numeric input
165
+ - `date` - Date picker
166
+ - `select` - Dropdown (static or async options)
167
+
168
+ ### 3. Critical Actions
169
+
170
+ Protect dangerous operations with automatic confirmation dialogs:
171
+
172
+ ```typescript
173
+ {
174
+ command: 'delete all data',
175
+ critical: true, // πŸ”’ Requires confirmation
176
+ description: 'Permanently delete all application data',
177
+ action: async () => {
178
+ await this.dataService.deleteAll();
179
+ return 'βœ… All data deleted successfully.';
180
+ }
181
+ }
182
+ ```
183
+
184
+ ### 4. Select Parameters (Static)
185
+
186
+ Provide predefined options:
187
+
188
+ ```typescript
189
+ {
190
+ command: 'set theme',
191
+ parameters: [{
192
+ name: 'theme',
193
+ type: 'select',
194
+ options: [
195
+ { label: 'Light Mode', value: 'light' },
196
+ { label: 'Dark Mode', value: 'dark' },
197
+ { label: 'Auto', value: 'auto' }
198
+ ]
199
+ }],
200
+ action: (params) => this.themeService.set(params.theme)
201
+ }
202
+ ```
203
+
204
+ ### 5. Dynamic Select Parameters
205
+
206
+ Load options from APIs:
207
+
208
+ ```typescript
209
+ {
210
+ command: 'assign to user',
211
+ parameters: [{
212
+ name: 'userId',
213
+ type: 'select',
214
+ getOptions: async () => {
215
+ const users = await this.userService.getAll();
216
+ return users.map(u => ({
217
+ label: `${u.name} (${u.email})`,
218
+ value: u.id
219
+ }));
220
+ }
221
+ }],
222
+ action: (params) => this.taskService.assign(params.userId)
223
+ }
91
224
  ```
92
225
 
93
226
  ---
94
227
 
95
- ### Step 2: Interact with the Service πŸ—£οΈ
228
+ ## πŸ“˜ API Reference
96
229
 
97
- Define and remove voice commands and inject the `AssistantService` into your components, start the party by calling `startListening()`.
230
+ ### `AssistantService`
98
231
 
99
- #### `app.component.ts`
232
+ Injectable service for programmatic control:
233
+
234
+ #### Methods
235
+
236
+ ##### `toggle(onSubmit?, onClose?)`
237
+
238
+ Opens or closes the assistant overlay.
100
239
 
101
240
  ```typescript
102
- import { Component, signal } from '@angular/core';
241
+ // Basic usage
242
+ this.assistant.toggle();
243
+
244
+ // With callbacks
245
+ this.assistant.toggle(
246
+ (userInput) => console.log('User said:', userInput),
247
+ () => console.log('Assistant closed')
248
+ );
249
+ ```
250
+
251
+ ##### `addCommand(command, action?)`
252
+
253
+ Dynamically add a command at runtime.
254
+
255
+ ```typescript
256
+ // Add a simple command
257
+ this.assistant.addCommand('refresh data', () => {
258
+ this.dataService.refresh();
259
+ return 'Data refreshed!';
260
+ });
261
+
262
+ // Add a command with full config
263
+ this.assistant.addCommand({
264
+ command: 'export report',
265
+ description: 'Export data as PDF',
266
+ parameters: [
267
+ {
268
+ name: 'format',
269
+ type: 'select',
270
+ options: [
271
+ { label: 'PDF', value: 'pdf' },
272
+ { label: 'Excel', value: 'xlsx' },
273
+ ],
274
+ },
275
+ ],
276
+ action: async (params) => {
277
+ await this.reportService.export(params.format);
278
+ return `Report exported as ${params.format}`;
279
+ },
280
+ });
281
+ ```
282
+
283
+ ##### `removeCommand(commandPhrase)`
284
+
285
+ Remove a registered command.
286
+
287
+ ```typescript
288
+ this.assistant.removeCommand('delete account');
289
+ ```
290
+
291
+ ##### `getCommands()`
292
+
293
+ Get list of all registered command names.
294
+
295
+ ```typescript
296
+ const commands = this.assistant.getCommands();
297
+ console.log('Available commands:', commands);
298
+ ```
299
+
300
+ ---
301
+
302
+ ## πŸ”§ Configuration Options
303
+
304
+ ### `AssistantConfig`
305
+
306
+ ```typescript
307
+ interface AssistantConfig {
308
+ // Activation keyword (optional)
309
+ activationCommand?: string;
310
+
311
+ // Welcome message shown when assistant opens
312
+ introMessage?: string;
313
+
314
+ // Response for unrecognized inputs
315
+ fallbackResponse?: string;
316
+
317
+ // Enable AI-powered natural language understanding
318
+ enableSmartIntent?: boolean;
319
+
320
+ // Input field placeholder text
321
+ inputPlaceholder?: string;
322
+
323
+ // List of commands
324
+ commands: AssistantCommand[];
325
+
326
+ // Floating button configuration
327
+ floatingButton?: {
328
+ visible?: boolean;
329
+ tooltip?: string;
330
+ customHtml?: string;
331
+ position?: { bottom: string; right: string };
332
+ };
333
+ }
334
+ ```
335
+
336
+ ---
337
+
338
+ ## 🎨 Advanced Usage
339
+
340
+ ### Example 1: Multi-Step Booking System
341
+
342
+ ```typescript
343
+ import { Component } from '@angular/core';
103
344
  import { AssistantService } from '@foisit/angular-wrapper';
104
345
 
105
346
  @Component({
106
- selector: 'app-root',
107
- templateUrl: './app.component.html',
108
- styleUrls: ['./app.component.scss'],
347
+ selector: 'app-booking',
348
+ template: `<button (click)="setupBooking()">Enable Booking</button>`,
109
349
  })
110
- export class AppComponent {
111
- title = 'Angular Assistant Demo';
112
- color = signal('transparent'); // Reactive color signal
113
-
114
- constructor(private assistantService: AssistantService) {
115
- // Define voice commands
116
- this.assistantService.addCommand('background red', () => {
117
- this.color.set('red');
350
+ export class BookingComponent {
351
+ constructor(private assistant: AssistantService, private bookingService: BookingService) {}
352
+
353
+ setupBooking() {
354
+ this.assistant.addCommand({
355
+ command: 'book appointment',
356
+ description: 'Schedule a new appointment',
357
+ parameters: [
358
+ {
359
+ name: 'service',
360
+ description: 'Type of service',
361
+ type: 'select',
362
+ required: true,
363
+ getOptions: async () => {
364
+ const services = await this.bookingService.getServices();
365
+ return services.map((s) => ({
366
+ label: s.name,
367
+ value: s.id,
368
+ }));
369
+ },
370
+ },
371
+ {
372
+ name: 'date',
373
+ description: 'Preferred date',
374
+ type: 'date',
375
+ required: true,
376
+ },
377
+ {
378
+ name: 'notes',
379
+ description: 'Additional notes',
380
+ type: 'string',
381
+ required: false,
382
+ },
383
+ ],
384
+ action: async (params) => {
385
+ const booking = await this.bookingService.create(params);
386
+ return {
387
+ type: 'success',
388
+ message: `βœ… Appointment booked for ${params.date}!`,
389
+ };
390
+ },
118
391
  });
392
+ }
393
+ }
394
+ ```
119
395
 
120
- this.assistantService.addCommand('remove background', () => {
121
- this.color.set('transparent');
122
- });
396
+ ### Example 2: E-Commerce Product Search
123
397
 
124
- this.assistantService.addCommand('sleep', () => {
125
- this.assistantService.stopListening();
398
+ ```typescript
399
+ this.assistant.addCommand({
400
+ command: 'search products',
401
+ parameters: [
402
+ { name: 'query', type: 'string', required: true },
403
+ {
404
+ name: 'category',
405
+ type: 'select',
406
+ required: false,
407
+ options: [
408
+ { label: 'Electronics', value: 'electronics' },
409
+ { label: 'Clothing', value: 'clothing' },
410
+ { label: 'Books', value: 'books' },
411
+ ],
412
+ },
413
+ {
414
+ name: 'minPrice',
415
+ type: 'number',
416
+ required: false,
417
+ },
418
+ ],
419
+ action: async (params) => {
420
+ const results = await this.productService.search(params);
421
+ this.router.navigate(['/products'], {
422
+ queryParams: { q: params.query },
126
423
  });
424
+ return `Found ${results.length} products matching "${params.query}"`;
425
+ },
426
+ });
427
+ ```
127
428
 
128
- // Start listening immediately
129
- this.assistantService.startListening();
130
- }
131
- }
429
+ ### Example 3: Form Validation with Error Handling
430
+
431
+ ```typescript
432
+ this.assistant.addCommand({
433
+ command: 'create account',
434
+ parameters: [
435
+ { name: 'email', type: 'string', required: true },
436
+ { name: 'password', type: 'string', required: true },
437
+ { name: 'age', type: 'number', required: true },
438
+ ],
439
+ action: async (params) => {
440
+ // Validation
441
+ if (params.age < 18) {
442
+ return {
443
+ type: 'error',
444
+ message: '❌ You must be 18 or older to create an account.',
445
+ };
446
+ }
447
+
448
+ if (!params.email.includes('@')) {
449
+ return {
450
+ type: 'error',
451
+ message: '❌ Please provide a valid email address.',
452
+ };
453
+ }
454
+
455
+ // Create account
456
+ try {
457
+ await this.authService.register(params);
458
+ return {
459
+ type: 'success',
460
+ message: 'βœ… Account created successfully! You can now log in.',
461
+ };
462
+ } catch (error) {
463
+ return {
464
+ type: 'error',
465
+ message: `❌ Registration failed: ${error.message}`,
466
+ };
467
+ }
468
+ },
469
+ });
132
470
  ```
133
471
 
134
472
  ---
135
473
 
136
- ### Step 3: Craft the UI 🎨
474
+ ## πŸ“ TypeScript Support
137
475
 
138
- Create a clean UI to showcase your assistant's magic.
476
+ ### Full Type Definitions
139
477
 
140
- #### `app.component.html`
141
-
142
- ```html
143
- <div
144
- class="content-container"
145
- [ngStyle]="{
146
- 'background-color': color(),
147
- 'padding': '20px'
148
- }"
149
- >
150
- <h1>πŸ§™β€β™‚οΈ Angular Assistant Demo</h1>
151
- <p>Say the magic words to see the assistant in action:</p>
152
- <ul>
153
- <li>πŸŸ₯ Say <strong>"background red"</strong> to make the background red.</li>
154
- <li>πŸ”„ Say <strong>"remove background"</strong> to reset the background.</li>
155
- <li>😴 Say <strong>"sleep"</strong> to put the assistant to rest.</li>
156
- </ul>
157
- <p>🎨 Current Background: <strong>{{ color() }}</strong></p>
158
- </div>
478
+ ```typescript
479
+ import { AssistantCommand, InteractiveResponse } from '@foisit/core';
480
+
481
+ // Type-safe command definition
482
+ const myCommand: AssistantCommand = {
483
+ command: 'update settings',
484
+ description: 'Update user preferences',
485
+ parameters: [
486
+ {
487
+ name: 'theme',
488
+ type: 'select',
489
+ required: true,
490
+ options: [
491
+ { label: 'Light', value: 'light' },
492
+ { label: 'Dark', value: 'dark' },
493
+ ],
494
+ },
495
+ ],
496
+ action: async (params: { theme: string }): Promise<InteractiveResponse> => {
497
+ await this.settingsService.update(params.theme);
498
+ return {
499
+ type: 'success',
500
+ message: `Theme updated to ${params.theme}`,
501
+ };
502
+ },
503
+ };
159
504
  ```
160
505
 
161
506
  ---
162
507
 
163
- ### Step 4: Run the App πŸƒ
508
+ ## 🎯 Best Practices
164
509
 
165
- Start your Angular app and watch the magic happen! ✨
510
+ ### 1. Command Naming
166
511
 
167
- ```bash
168
- ng serve
512
+ βœ… **Good:**
513
+
514
+ - "create user"
515
+ - "delete account"
516
+ - "export report"
517
+
518
+ ❌ **Avoid:**
519
+
520
+ - "CreateUser" (not natural)
521
+ - "usr_del" (not descriptive)
522
+ - "do the thing" (too vague)
523
+
524
+ ### 2. Descriptions
525
+
526
+ Always provide clear descriptions for AI matching:
527
+
528
+ ```typescript
529
+ {
530
+ command: 'reset password',
531
+ description: 'Reset the user password and send recovery email',
532
+ // AI can match: "forgot my password", "can't log in", etc.
533
+ }
534
+ ```
535
+
536
+ ### 3. Error Handling
537
+
538
+ Return user-friendly error messages:
539
+
540
+ ```typescript
541
+ action: async (params) => {
542
+ try {
543
+ await this.api.call(params);
544
+ return { type: 'success', message: 'βœ… Done!' };
545
+ } catch (error) {
546
+ return {
547
+ type: 'error',
548
+ message: `❌ Something went wrong: ${error.message}`,
549
+ };
550
+ }
551
+ };
552
+ ```
553
+
554
+ ### 4. Use Signals for Reactive State
555
+
556
+ ```typescript
557
+ import { signal } from '@angular/core';
558
+
559
+ export class MyComponent {
560
+ theme = signal<'light' | 'dark'>('light');
561
+
562
+ constructor(private assistant: AssistantService) {
563
+ this.assistant.addCommand('toggle theme', () => {
564
+ const newTheme = this.theme() === 'light' ? 'dark' : 'light';
565
+ this.theme.set(newTheme);
566
+ return `Theme switched to ${newTheme}`;
567
+ });
568
+ }
569
+ }
169
570
  ```
170
571
 
171
572
  ---
172
573
 
173
- ## πŸ› οΈ API Reference
574
+ ## πŸ§ͺ Testing
174
575
 
175
- ### `AssistantConfig`
576
+ ### Unit Testing Commands
176
577
 
177
- Configure your assistant's behavior with this object.
578
+ ```typescript
579
+ import { TestBed } from '@angular/core/testing';
580
+ import { AssistantService } from '@foisit/angular-wrapper';
581
+
582
+ describe('AssistantService', () => {
583
+ let service: AssistantService;
584
+
585
+ beforeEach(() => {
586
+ TestBed.configureTestingModule({
587
+ imports: [AssistantModule.forRoot({ commands: [] })],
588
+ });
589
+ service = TestBed.inject(AssistantService);
590
+ });
591
+
592
+ it('should add and execute command', () => {
593
+ let executed = false;
594
+ service.addCommand('test', () => {
595
+ executed = true;
596
+ });
597
+
598
+ // Trigger command execution
599
+ service.toggle();
600
+ // Test execution...
178
601
 
179
- | Property | Type | Description |
180
- | ------------------- | -------- | ------------------------------------------------- |
181
- | `activationCommand` | `string` | The keyword to wake the assistant. |
182
- | `fallbackResponse` | `string` | The message when a command isn’t recognized. |
183
- | `commands` | `Array` | A list of `{ command: string, action: Function }` |
602
+ expect(executed).toBe(true);
603
+ });
604
+ });
605
+ ```
184
606
 
185
607
  ---
186
608
 
187
- ### πŸ”‘ Service Methods
609
+ ## οΏ½ Related Packages
188
610
 
189
- | Method | Description |
190
- | ---------------- | --------------------------------------- |
191
- | `addCommand` | Dynamically add a new command. |
192
- | `removeCommand` | Remove an existing command dynamically. |
193
- | `startListening` | Start listening for voice commands. |
194
- | `stopListening` | Stop listening for voice commands. |
611
+ - **[@foisit/core](../core)** - Core engine (auto-installed)
612
+ - **[@foisit/react-wrapper](../react-wrapper)** - React integration
613
+ - **[@foisit/vue-wrapper](../vue-wrapper)** - Vue integration
195
614
 
196
615
  ---
197
616
 
198
- ## 🌟 Features
617
+ ## πŸ› Troubleshooting
618
+
619
+ ### Assistant not appearing
620
+
621
+ Ensure `AssistantModule.forRoot()` is imported in your app configuration and double-tap the floating button.
622
+
623
+ ### Commands not executing
199
624
 
200
- - 🧩 **Dynamic Commands**: Add or remove commands on the fly.
201
- - 🎨 **Visual Feedback**: Show visual cues when the assistant is active.
202
- - πŸš€ **Easy Integration**: Integrate the assistant with just a few lines of code.
203
- - πŸ—£οΈ **Voice Feedback**: The assistant can respond with voice feedback.
204
- - πŸ”„ **Double Activation**: The assistant can be activated with a double-click and also put to sleep with a double-click when active.
625
+ Check browser console for errors. Ensure `action` functions are returning values or promises.
626
+
627
+ ### TypeScript errors
628
+
629
+ Make sure you're using Angular 17+ and have `@angular/core` installed.
630
+
631
+ ---
632
+
633
+ ## πŸ“„ License
634
+
635
+ MIT Β© [Foisit](https://github.com/boluwatifee4/foisit)
205
636
 
206
637
  ---
207
638
 
208
639
  ## 🀝 Contributing
209
640
 
210
- Want to make the assistant even better? PRs are welcomed! πŸ™Œ
641
+ Contributions are welcome! Please read our [Contributing Guide](../../CONTRIBUTING.md) first.
211
642
 
212
643
  ---
213
644
 
214
- ## πŸ“„ License
645
+ ## πŸ“¬ Support
646
+
647
+ - πŸ“§ Email: support@foisit.com
648
+ - πŸ’¬ Discord: [Join our community](https://discord.gg/foisit)
649
+ - πŸ› Issues: [GitHub Issues](https://github.com/boluwatifee4/foisit/issues)
650
+
651
+ ---
215
652
 
216
- This library is licensed under the MIT License.
653
+ **Made with ❀️ by the Foisit Team**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foisit/angular-wrapper",
3
- "version": "1.2.0",
3
+ "version": "2.1.1",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^19.0.0",
6
6
  "@angular/core": "^19.0.0"