@foisit/angular-wrapper 2.0.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 +586 -31
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,9 +1,41 @@
1
1
  # @foisit/angular-wrapper
2
2
 
3
- Power your Angular apps with an AI-driven text assistant.
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)
5
+
6
+ > **The AI-Powered Conversational Assistant for Angular Applications**
7
+
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.
4
9
 
5
10
  > [!NOTE]
6
- > πŸŽ™οΈ **Coming Soon**: Voice recognition and responses are planned for a future release. Current support is focused on text-based interactions and AI intent matching.
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.
12
+
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)
26
+
27
+ ---
28
+
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
7
39
 
8
40
  ---
9
41
 
@@ -13,29 +45,38 @@ Power your Angular apps with an AI-driven text assistant.
13
45
  npm install @foisit/angular-wrapper
14
46
  ```
15
47
 
16
- ---
48
+ ### Peer Dependencies
17
49
 
18
- ## πŸ”§ Basic Setup
50
+ ```json
51
+ {
52
+ "@angular/core": "^17.0.0 || ^18.0.0",
53
+ "@angular/common": "^17.0.0 || ^18.0.0"
54
+ }
55
+ ```
19
56
 
20
- ### 1. Import `AssistantModule`
57
+ ---
58
+
59
+ ## 🏁 Quick Start
21
60
 
22
- Add `AssistantModule.forRoot()` to your `app.config.ts` (for Standalone) or `app.module.ts`.
61
+ ### Step 1: Import the Module
23
62
 
24
- #### `app.config.ts` (Standalone)
63
+ #### For Standalone Apps (Recommended)
25
64
 
26
65
  ```typescript
66
+ // app.config.ts
67
+ import { ApplicationConfig, importProvidersFrom } from '@angular/core';
27
68
  import { AssistantModule } from '@foisit/angular-wrapper';
28
69
 
29
70
  export const appConfig: ApplicationConfig = {
30
71
  providers: [
31
72
  importProvidersFrom(
32
73
  AssistantModule.forRoot({
74
+ introMessage: 'Welcome! How can I assist you today?',
33
75
  enableSmartIntent: true,
34
- introMessage: 'Welcome! How can I help?',
35
76
  commands: [
36
77
  {
37
- command: 'profile',
38
- action: () => router.navigate(['/profile']),
78
+ command: 'navigate to profile',
79
+ action: () => console.log('Navigating to profile...'),
39
80
  },
40
81
  ],
41
82
  })
@@ -44,55 +85,569 @@ export const appConfig: ApplicationConfig = {
44
85
  };
45
86
  ```
46
87
 
88
+ #### For Module-Based Apps
89
+
90
+ ```typescript
91
+ // app.module.ts
92
+ import { NgModule } from '@angular/core';
93
+ import { AssistantModule } from '@foisit/angular-wrapper';
94
+
95
+ @NgModule({
96
+ imports: [
97
+ AssistantModule.forRoot({
98
+ introMessage: 'Welcome! How can I assist you today?',
99
+ commands: [
100
+ /* your commands */
101
+ ],
102
+ }),
103
+ ],
104
+ })
105
+ export class AppModule {}
106
+ ```
107
+
108
+ ### Step 2: Use the Service
109
+
110
+ ```typescript
111
+ // my-component.ts
112
+ import { Component } from '@angular/core';
113
+ import { AssistantService } from '@foisit/angular-wrapper';
114
+
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
+
47
128
  ---
48
129
 
49
- ## πŸ›‘οΈ Critical Actions
130
+ ## 🎯 Core Concepts
131
+
132
+ ### 1. Commands
50
133
 
51
- Commands marked as `critical` will automatically trigger a confirmation flow in the UI.
134
+ Commands are the building blocks of your assistant. Each command represents an action users can trigger through natural language.
52
135
 
53
136
  ```typescript
54
- const config = {
55
- commands: [
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 }
156
+ ],
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
+ }
224
+ ```
225
+
226
+ ---
227
+
228
+ ## πŸ“˜ API Reference
229
+
230
+ ### `AssistantService`
231
+
232
+ Injectable service for programmatic control:
233
+
234
+ #### Methods
235
+
236
+ ##### `toggle(onSubmit?, onClose?)`
237
+
238
+ Opens or closes the assistant overlay.
239
+
240
+ ```typescript
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: [
56
267
  {
57
- command: 'delete post',
58
- critical: true,
59
- description: 'permanently delete this post',
60
- action: () => this.postService.delete(),
268
+ name: 'format',
269
+ type: 'select',
270
+ options: [
271
+ { label: 'PDF', value: 'pdf' },
272
+ { label: 'Excel', value: 'xlsx' },
273
+ ],
61
274
  },
62
275
  ],
63
- };
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);
64
298
  ```
65
299
 
66
300
  ---
67
301
 
68
- ## 🧠 AI Intent Matching
302
+ ## πŸ”§ Configuration Options
303
+
304
+ ### `AssistantConfig`
69
305
 
70
- Enable `enableSmartIntent: true` to allow the assistant to understand natural language.
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;
71
316
 
72
- **User says:** _"Go to my profile"_
73
- **Matched Command:** `{ command: 'profile', keywords: ['account', 'user settings'], ... }`
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
+ ```
74
335
 
75
336
  ---
76
337
 
77
- ## πŸ› οΈ Service Usage: `AssistantService`
338
+ ## 🎨 Advanced Usage
78
339
 
79
- Interact with the assistant dynamically from your components.
340
+ ### Example 1: Multi-Step Booking System
80
341
 
81
342
  ```typescript
343
+ import { Component } from '@angular/core';
82
344
  import { AssistantService } from '@foisit/angular-wrapper';
83
345
 
84
- @Component({...})
346
+ @Component({
347
+ selector: 'app-booking',
348
+ template: `<button (click)="setupBooking()">Enable Booking</button>`,
349
+ })
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
+ },
391
+ });
392
+ }
393
+ }
394
+ ```
395
+
396
+ ### Example 2: E-Commerce Product Search
397
+
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 },
423
+ });
424
+ return `Found ${results.length} products matching "${params.query}"`;
425
+ },
426
+ });
427
+ ```
428
+
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
+ });
470
+ ```
471
+
472
+ ---
473
+
474
+ ## πŸ“ TypeScript Support
475
+
476
+ ### Full Type Definitions
477
+
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
+ };
504
+ ```
505
+
506
+ ---
507
+
508
+ ## 🎯 Best Practices
509
+
510
+ ### 1. Command Naming
511
+
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
+
85
559
  export class MyComponent {
86
- constructor(private assistant: AssistantService) {}
560
+ theme = signal<'light' | 'dark'>('light');
87
561
 
88
- addCommand() {
89
- this.assistant.addCommand('clear', () => this.clearAll());
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
+ });
90
568
  }
91
569
  }
92
570
  ```
93
571
 
94
572
  ---
95
573
 
96
- ## πŸ‘‹ Gesture Activation
574
+ ## πŸ§ͺ Testing
575
+
576
+ ### Unit Testing Commands
577
+
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...
601
+
602
+ expect(executed).toBe(true);
603
+ });
604
+ });
605
+ ```
606
+
607
+ ---
608
+
609
+ ## οΏ½ Related Packages
610
+
611
+ - **[@foisit/core](../core)** - Core engine (auto-installed)
612
+ - **[@foisit/react-wrapper](../react-wrapper)** - React integration
613
+ - **[@foisit/vue-wrapper](../vue-wrapper)** - Vue integration
614
+
615
+ ---
616
+
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
624
+
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)
636
+
637
+ ---
638
+
639
+ ## 🀝 Contributing
640
+
641
+ Contributions are welcome! Please read our [Contributing Guide](../../CONTRIBUTING.md) first.
642
+
643
+ ---
644
+
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
+ ---
97
652
 
98
- Once integrated, a subtle **"Powered by Foisit"** watermark appears. **Double-click** it to open the chat overlay.
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": "2.0.0",
3
+ "version": "2.1.1",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^19.0.0",
6
6
  "@angular/core": "^19.0.0"