Ai Chat Integration

Ecosistema completo para organización y gestión de contenido con interfaces espaciales

AI Chat Integration

This document explains how AI chat and generation features are integrated into our monorepo applications.

Overview

Our monorepo includes comprehensive AI integration through the @gograb-ai library, which provides:

Architecture

@gograb-ai Library
├── Services
│   ├── AIFactoryService       - Main factory for AI operations
│   ├── OpenAIService          - OpenAI integration
│   ├── AnthropicService       - Anthropic Claude integration
│   ├── GeminiService          - Google Gemini integration
│   └── MenuGenerationService  - Specialized menu generation
├── Models
│   ├── AIProvider enum
│   ├── Message interfaces
│   └── Generation interfaces
└── Proxy
    ├── Anthropic proxy server
    └── OpenAI proxy server

Using AI Generation

1. Basic Setup

import { AIFactoryService, AIProvider, MessageRole } from '@gograb-ai';

export class MyComponent {
  private aiFactory = inject(AIFactoryService);
  
  async generateContent(prompt: string): Promise<string> {
    const messages = [
      {
        role: MessageRole.System,
        content: 'You are a helpful assistant.'
      },
      {
        role: MessageRole.User,
        content: prompt
      }
    ];
    
    try {
      const response = await this.aiFactory.chat(
        messages,
        { provider: AIProvider.ANTHROPIC }
      );
      return response;
    } catch (error) {
      console.error('AI generation failed:', error);
      return this.generateFallbackContent(prompt);
    }
  }
}

2. Menu Generation Example

The UX Menu component demonstrates advanced AI integration:

import { MenuGenerationService } from '@gograb-ai';

export class UxMenuComponent {
  private menuGenService = inject(MenuGenerationService);
  
  async generateMenu(prompt: string): Promise<void> {
    const request = {
      purpose: prompt,
      includeIcons: true,
      includeBadges: true,
      includeSubmenus: true,
      style: 'navigation'
    };
    
    this.menuGenService.generateMenu(request).subscribe(result => {
      if (result) {
        this.applyGeneratedMenu(result);
      }
    });
  }
}

AI Providers

OpenAI

// Configuration
const openAIConfig = {
  apiKey: process.env['OPENAI_API_KEY'],
  model: 'gpt-4',
  temperature: 0.7
};

Anthropic (Claude)

// Configuration
const anthropicConfig = {
  apiKey: process.env['ANTHROPIC_API_KEY'],
  model: 'claude-3-opus-20240229',
  maxTokens: 4000
};

Mock Provider

For development without API keys:

// Automatically used when API keys are not available
const mockConfig = {
  provider: AIProvider.MOCK,
  delay: 1000 // Simulate processing time
};

Proxy Servers

Anthropic Proxy

Located at libs/gograb-ai/src/proxy/anthropic-proxy.js:

// Start the proxy server
node libs/gograb-ai/src/proxy/anthropic-proxy.js

// Default port: 3001
// Endpoint: http://localhost:3001/api/anthropic/messages

Environment Variables

# .env.local
ANTHROPIC_API_KEY=your-api-key-here
OPENAI_API_KEY=your-api-key-here
GEMINI_API_KEY=your-api-key-here

Widget AI Generation Pattern

Each widget should follow this pattern for AI generation:

1. Create AI Service

@Injectable({
  providedIn: 'root'
})
export class WidgetAIService {
  private aiFactory = inject(AIFactoryService);
  
  async generateConfiguration(prompt: string): Promise<WidgetConfig> {
    // Build system prompt
    const systemPrompt = this.buildSystemPrompt();
    
    // Create messages
    const messages = [
      { role: MessageRole.System, content: systemPrompt },
      { role: MessageRole.User, content: prompt }
    ];
    
    try {
      // Try real AI first
      const response = await this.aiFactory.chat(messages);
      return this.parseResponse(response);
    } catch (error) {
      // Fall back to mock generation
      return this.generateMockConfiguration(prompt);
    }
  }
  
  private generateMockConfiguration(prompt: string): WidgetConfig {
    // Intelligent mock generation based on prompt analysis
    const lowerPrompt = prompt.toLowerCase();
    
    if (lowerPrompt.includes('dashboard')) {
      return this.generateDashboardConfig();
    } else if (lowerPrompt.includes('form')) {
      return this.generateFormConfig();
    }
    
    return this.generateDefaultConfig();
  }
}

2. Storage Integration

AI-generated content should be automatically saved:

async generateWithAI(): Promise<void> {
  const result = await this.aiService.generateConfiguration(this.prompt);
  
  if (result) {
    // Apply configuration
    this.widgetConfig.set(result.config);
    
    // Auto-save to storage
    const variation = {
      id: `ai-${Date.now()}`,
      name: `AI: ${this.prompt.slice(0, 30)}...`,
      config: result.config,
      createdAt: Date.now()
    };
    
    this.storageService.saveVariation(variation).subscribe();
  }
}

Best Practices

1. Error Handling

Always implement fallback strategies:

try {
  // Try real AI
  const result = await this.aiFactory.chat(messages);
  return this.parseResponse(result);
} catch (error) {
  console.error('AI generation failed:', error);
  
  // Check error type
  if (error.message.includes('401')) {
    this.showError('Invalid API key');
  } else if (error.message.includes('429')) {
    this.showError('Rate limit exceeded');
  }
  
  // Use mock generation
  return this.generateMockContent(prompt);
}

2. Prompt Engineering

Structure prompts for better results:

private buildSystemPrompt(): string {
  return `You are an expert UI/UX designer specializing in ${this.widgetType}.
  
  Guidelines:
  - Generate modern, accessible designs
  - Use appropriate color schemes
  - Follow Material Design principles
  - Include proper spacing and typography
  
  Respond with valid JSON matching this structure:
  ${JSON.stringify(this.getExpectedStructure(), null, 2)}`;
}

3. Response Parsing

Safely parse AI responses:

private parseResponse(response: string): WidgetConfig | null {
  try {
    // Extract JSON from response
    const jsonMatch = response.match(/\{[\s\S]*\}/);
    if (!jsonMatch) {
      throw new Error('No JSON found in response');
    }
    
    const parsed = JSON.parse(jsonMatch[0]);
    
    // Validate structure
    if (!this.isValidConfig(parsed)) {
      throw new Error('Invalid configuration structure');
    }
    
    return parsed;
  } catch (error) {
    console.error('Failed to parse AI response:', error);
    return null;
  }
}

4. User Experience

Provide feedback during generation:

aiGenerationStatus = signal<string>('');

async generateContent(): Promise<void> {
  this.aiGenerationStatus.set('Initializing AI...');
  
  try {
    this.aiGenerationStatus.set('Analyzing request...');
    await this.delay(500);
    
    this.aiGenerationStatus.set('Generating content...');
    const result = await this.aiService.generate(this.prompt);
    
    this.aiGenerationStatus.set('Processing result...');
    await this.applyResult(result);
    
    this.aiGenerationStatus.set('');
    this.showSuccess('Content generated successfully!');
  } catch (error) {
    this.aiGenerationStatus.set('');
    this.showError('Generation failed');
  }
}

Mock Generation Strategy

Implement intelligent mock generation:

private analyzePurpose(prompt: string): WidgetPurpose {
  const lower = prompt.toLowerCase();
  
  const purposes = {
    navigation: ['menu', 'nav', 'sidebar'],
    data: ['table', 'grid', 'list'],
    form: ['form', 'input', 'field'],
    dashboard: ['dashboard', 'chart', 'metric'],
    settings: ['settings', 'config', 'preferences']
  };
  
  for (const [purpose, keywords] of Object.entries(purposes)) {
    if (keywords.some(keyword => lower.includes(keyword))) {
      return purpose as WidgetPurpose;
    }
  }
  
  return 'general';
}

private generateMockContent(prompt: string): WidgetConfig {
  const purpose = this.analyzePurpose(prompt);
  const templates = this.getTemplatesForPurpose(purpose);
  
  // Select appropriate template
  const template = templates.find(t => 
    this.matchesPrompt(t, prompt)
  ) || templates[0];
  
  // Customize based on prompt
  return this.customizeTemplate(template, prompt);
}

Testing AI Features

Unit Tests

describe('WidgetAIService', () => {
  let service: WidgetAIService;
  let aiFactory: jasmine.SpyObj<AIFactoryService>;
  
  beforeEach(() => {
    const spy = jasmine.createSpyObj('AIFactoryService', ['chat']);
    
    TestBed.configureTestingModule({
      providers: [
        WidgetAIService,
        { provide: AIFactoryService, useValue: spy }
      ]
    });
    
    service = TestBed.inject(WidgetAIService);
    aiFactory = TestBed.inject(AIFactoryService) as jasmine.SpyObj<AIFactoryService>;
  });
  
  it('should generate configuration from prompt', async () => {
    const mockResponse = JSON.stringify({
      config: { theme: 'dark' },
      items: []
    });
    
    aiFactory.chat.and.returnValue(Promise.resolve(mockResponse));
    
    const result = await service.generateConfiguration('dark theme menu');
    
    expect(result.config.theme).toBe('dark');
  });
  
  it('should fall back to mock on error', async () => {
    aiFactory.chat.and.returnValue(Promise.reject(new Error('API error')));
    
    const result = await service.generateConfiguration('test menu');
    
    expect(result).toBeDefined();
    expect(result.config).toBeDefined();
  });
});

Troubleshooting

Common Issues

  1. 401 Unauthorized

    • Check API key is set correctly
    • Verify proxy server is running
    • Check API key validity
  2. Rate Limiting

    • Implement exponential backoff
    • Cache responses when appropriate
    • Use mock generation during development
  3. Parsing Errors

    • Log raw responses for debugging
    • Implement robust JSON extraction
    • Validate response structure

Debug Mode

Enable detailed logging:

const DEBUG_AI = true;

if (DEBUG_AI) {
  console.log('AI Request:', { messages, options });
  console.log('AI Response:', response);
  console.log('Parsed Result:', result);
}

Future Enhancements

  1. Streaming Responses

    • Implement streaming for long generations
    • Show partial results as they arrive
  2. Context Management

    • Maintain conversation history
    • Implement context windows
  3. Fine-tuning

    • Collect user feedback
    • Improve prompts based on usage
  4. Multi-modal Support

    • Image generation for UI mockups
    • Voice input for commands

Conclusion

AI integration in our monorepo provides:

Follow these patterns to ensure consistent, reliable AI features across all applications.