Documentation

AI Agent Application

AI Agent Application

AI-powered chat interface for intelligent assistance with code generation, content creation, and problem-solving capabilities.

Route: /admin/apps/ai-agent

Overview

The AI Agent application provides a sophisticated chat interface powered by artificial intelligence. It offers intelligent assistance for various tasks including code generation, content creation, problem-solving, and general queries with a modern, responsive design.

Features

Core AI Features

  • Natural Language Processing - Understand and respond to natural language queries
  • Code Generation - Generate code snippets in multiple programming languages
  • Content Creation - Help with writing, editing, and content generation
  • Problem Solving - Assist with technical and non-technical problems
  • Context Awareness - Maintain conversation context across multiple messages
  • Multi-language Support - Support for various programming languages
  • Code Highlighting - Syntax highlighting for generated code
  • Markdown Rendering - Rich text formatting for responses
  • File Attachment - Support for uploading files for analysis

UI/UX Features

  • Chat Interface - Modern, clean chat design
  • Message History - Persistent conversation history
  • Typing Indicators - Show when AI is processing
  • Message Actions - Copy, edit, regenerate responses
  • Dark/Light Mode - Automatic theme switching
  • Responsive Design - Works on all devices
  • Accessibility - WCAG compliant with proper ARIA labels

Chat Interface

Message Types

  • User Messages - User input and queries
  • AI Responses - AI-generated responses
  • Code Blocks - Syntax highlighted code snippets
  • System Messages - Status updates and notifications
  • Error Messages - Error handling and feedback

Message Features

  • Rich Formatting - Support for markdown formatting
  • Code Blocks - Syntax highlighted code with language detection
  • Links - Clickable links in responses
  • Lists - Bulleted and numbered lists
  • Tables - Formatted tables for data display
  • Images - Support for image display in responses

Conversation Management

  • New Chat - Start fresh conversations
  • Chat History - Access previous conversations
  • Chat Export - Export conversation history
  • Chat Search - Search through conversation history
  • Chat Sharing - Share conversations with others

AI Capabilities

Code Generation

  • Multiple Languages - Support for popular programming languages
  • Code Explanation - Explain how code works
  • Code Optimization - Suggest improvements and optimizations
  • Bug Fixing - Help identify and fix code issues
  • Code Review - Provide code review feedback
  • Best Practices - Suggest coding best practices

Content Creation

  • Writing Assistance - Help with writing and editing
  • Documentation - Generate technical documentation
  • Email Templates - Create professional email templates
  • Reports - Help with report writing
  • Presentations - Assist with presentation content
  • Creative Writing - Support for creative content

Problem Solving

  • Technical Issues - Help with technical problems
  • Debugging - Assist with debugging code
  • Architecture - Provide system design advice
  • Troubleshooting - Help troubleshoot issues
  • Research - Assist with research tasks
  • Analysis - Help analyze data and information

Integration Examples

Backend Integration

// AI Agent Controller
class AiAgentController extends Controller
{
    protected $aiService;

    public function __construct(AiService $aiService)
    {
        $this->aiService = $aiService;
    }

    public function index()
    {
        $conversations = Conversation::where('user_id', auth()->id())
            ->latest()
            ->paginate(20);

        return view('admin.apps.ai-agent', compact('conversations'));
    }

    public function sendMessage(Request $request)
    {
        $request->validate([
            'message' => 'required|string|max:4000',
            'conversation_id' => 'nullable|exists:conversations,id'
        ]);

        $conversation = $this->getOrCreateConversation($request->conversation_id);

        // Add user message
        $userMessage = $conversation->messages()->create([
            'role' => 'user',
            'content' => $request->message,
            'user_id' => auth()->id()
        ]);

        // Get AI response
        $aiResponse = $this->aiService->generateResponse(
            $conversation->messages()->latest()->take(10)->get(),
            $request->message
        );

        // Add AI message
        $aiMessage = $conversation->messages()->create([
            'role' => 'assistant',
            'content' => $aiResponse,
            'user_id' => auth()->id()
        ]);

        return response()->json([
            'conversation_id' => $conversation->id,
            'user_message' => $userMessage,
            'ai_message' => $aiMessage
        ]);
    }

    public function getConversation($id)
    {
        $conversation = Conversation::with('messages')
            ->where('user_id', auth()->id())
            ->findOrFail($id);

        return response()->json($conversation);
    }

    private function getOrCreateConversation($conversationId)
    {
        if ($conversationId) {
            return Conversation::where('user_id', auth()->id())
                ->findOrFail($conversationId);
        }

        return Conversation::create([
            'user_id' => auth()->id(),
            'title' => 'New Conversation',
            'type' => 'ai_chat'
        ]);
    }
}

AI Service Integration

// AI Service for different providers
class AiService
{
    protected $provider;

    public function __construct()
    {
        $this->provider = config('ai.default_provider');
    }

    public function generateResponse($messages, $newMessage)
    {
        switch ($this->provider) {
            case 'openai':
                return $this->generateOpenAIResponse($messages, $newMessage);
            case 'anthropic':
                return $this->generateAnthropicResponse($messages, $newMessage);
            case 'local':
                return $this->generateLocalResponse($messages, $newMessage);
            default:
                throw new \Exception('Unsupported AI provider');
        }
    }

    private function generateOpenAIResponse($messages, $newMessage)
    {
        $client = new \OpenAI\Client(config('ai.openai.api_key'));

        $formattedMessages = $this->formatMessagesForOpenAI($messages);
        $formattedMessages[] = ['role' => 'user', 'content' => $newMessage];

        $response = $client->chat()->create([
            'model' => 'gpt-4',
            'messages' => $formattedMessages,
            'max_tokens' => 2000,
            'temperature' => 0.7
        ]);

        return $response['choices'][0]['message']['content'];
    }

    private function generateAnthropicResponse($messages, $newMessage)
    {
        $client = new \Anthropic\Client(config('ai.anthropic.api_key'));

        $formattedMessages = $this->formatMessagesForAnthropic($messages);
        $formattedMessages[] = ['role' => 'user', 'content' => $newMessage];

        $response = $client->messages()->create([
            'model' => 'claude-3-sonnet-20240229',
            'messages' => $formattedMessages,
            'max_tokens' => 2000
        ]);

        return $response['content'][0]['text'];
    }

    private function generateLocalResponse($messages, $newMessage)
    {
        // Integration with local LLM (Ollama, etc.)
        $client = new \GuzzleHttp\Client();

        $response = $client->post(config('ai.local.endpoint'), [
            'json' => [
                'model' => config('ai.local.model'),
                'messages' => $this->formatMessagesForLocal($messages, $newMessage),
                'stream' => false
            ]
        ]);

        $data = json_decode($response->getBody(), true);
        return $data['choices'][0]['message']['content'];
    }

    private function formatMessagesForOpenAI($messages)
    {
        return $messages->map(function($message) {
            return [
                'role' => $message->role,
                'content' => $message->content
            ];
        })->toArray();
    }

    private function formatMessagesForAnthropic($messages)
    {
        return $messages->map(function($message) {
            return [
                'role' => $message->role,
                'content' => $message->content
            ];
        })->toArray();
    }

    private function formatMessagesForLocal($messages, $newMessage)
    {
        $formatted = $messages->map(function($message) {
            return [
                'role' => $message->role,
                'content' => $message->content
            ];
        })->toArray();

        $formatted[] = ['role' => 'user', 'content' => $newMessage];

        return $formatted;
    }
}

Livewire Integration

// AI Agent Livewire Component
class AiAgent extends Component
{
    public $conversations = [];
    public $activeConversation = null;
    public $messages = [];
    public $newMessage = '';
    public $isTyping = false;
    public $search = '';

    public function mount()
    {
        $this->loadConversations();
    }

    public function loadConversations()
    {
        $this->conversations = Conversation::where('user_id', auth()->id())
            ->latest()
            ->take(20)
            ->get();
    }

    public function selectConversation($conversationId)
    {
        $this->activeConversation = $conversationId;
        $this->loadMessages();
    }

    public function loadMessages()
    {
        if ($this->activeConversation) {
            $this->messages = Message::where('conversation_id', $this->activeConversation)
                ->orderBy('created_at')
                ->get();
        }
    }

    public function sendMessage()
    {
        if (empty($this->newMessage)) return;

        $this->isTyping = true;

        // Create or get conversation
        if (!$this->activeConversation) {
            $conversation = Conversation::create([
                'user_id' => auth()->id(),
                'title' => 'New Conversation',
                'type' => 'ai_chat'
            ]);
            $this->activeConversation = $conversation->id;
        }

        // Add user message
        $userMessage = Message::create([
            'conversation_id' => $this->activeConversation,
            'role' => 'user',
            'content' => $this->newMessage,
            'user_id' => auth()->id()
        ]);

        $this->messages->push($userMessage);
        $this->newMessage = '';

        // Generate AI response
        $this->generateAiResponse();
    }

    public function generateAiResponse()
    {
        $aiService = app(AiService::class);

        $recentMessages = $this->messages->take(-10);
        $lastMessage = $recentMessages->last();

        $aiResponse = $aiService->generateResponse($recentMessages, $lastMessage->content);

        $aiMessage = Message::create([
            'conversation_id' => $this->activeConversation,
            'role' => 'assistant',
            'content' => $aiResponse,
            'user_id' => auth()->id()
        ]);

        $this->messages->push($aiMessage);
        $this->isTyping = false;
    }

    public function newConversation()
    {
        $this->activeConversation = null;
        $this->messages = collect();
        $this->newMessage = '';
    }

    public function deleteConversation($conversationId)
    {
        Conversation::where('user_id', auth()->id())
            ->where('id', $conversationId)
            ->delete();

        $this->loadConversations();

        if ($this->activeConversation == $conversationId) {
            $this->newConversation();
        }
    }

    public function render()
    {
        return view('livewire.ai-agent');
    }
}

Customization

Styling

// Custom AI Agent styles
.ai-agent-container {
    .chat-sidebar {
        background: var(--bg-sidebar);
        border-right: 1px solid var(--border-color);

        .conversation-item {
            &:hover {
                background: var(--bg-hover);
            }

            &.active {
                background: var(--primary-color);
                color: white;
            }
        }
    }

    .chat-area {
        .message-list {
            .message {
                &.user-message {
                    background: var(--primary-color);
                    color: white;
                    margin-left: auto;
                    border-radius: 18px 18px 4px 18px;
                }

                &.ai-message {
                    background: var(--bg-card);
                    color: var(--text-color);
                    border: 1px solid var(--border-color);
                    border-radius: 18px 18px 18px 4px;
                }

                .message-content {
                    pre {
                        background: var(--code-bg);
                        color: var(--code-color);
                        border-radius: 8px;
                        padding: 1rem;
                        overflow-x: auto;
                    }

                    code {
                        background: var(--code-inline-bg);
                        color: var(--code-inline-color);
                        padding: 0.2rem 0.4rem;
                        border-radius: 4px;
                        font-size: 0.875rem;
                    }
                }
            }
        }

        .message-input {
            border-top: 1px solid var(--border-color);

            .input-group {
                .form-control {
                    border: none;
                    background: transparent;
                    resize: none;

                    &:focus {
                        box-shadow: none;
                    }
                }
            }
        }
    }
}

JavaScript Functionality

// AI Agent functionality
class AiAgent {
    constructor() {
        this.activeConversation = null;
        this.messages = [];
        this.isTyping = false;
        this.initEventListeners();
    }

    initEventListeners() {
        // Send message on Enter key
        document.getElementById('messageInput').addEventListener('keypress', (e) => {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                this.sendMessage();
            }
        });

        // Send button click
        document.getElementById('sendBtn').addEventListener('click', () => {
            this.sendMessage();
        });

        // Conversation selection
        document.addEventListener('click', (e) => {
            if (e.target.classList.contains('conversation-item')) {
                const conversationId = e.target.dataset.conversationId;
                this.selectConversation(conversationId);
            }
        });
    }

    async sendMessage() {
        const input = document.getElementById('messageInput');
        const message = input.value.trim();

        if (!message) return;

        // Add user message to UI
        this.addMessageToUI({
            role: 'user',
            content: message,
            timestamp: new Date().toISOString()
        });

        input.value = '';

        // Show typing indicator
        this.showTypingIndicator();

        try {
            // Send to server
            const response = await fetch('/api/ai-agent/send-message', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
                },
                body: JSON.stringify({
                    message: message,
                    conversation_id: this.activeConversation
                })
            });

            const data = await response.json();

            // Hide typing indicator
            this.hideTypingIndicator();

            // Add AI response to UI
            this.addMessageToUI({
                role: 'assistant',
                content: data.ai_message.content,
                timestamp: data.ai_message.created_at
            });

            // Update conversation ID
            this.activeConversation = data.conversation_id;

        } catch (error) {
            console.error('Error sending message:', error);
            this.hideTypingIndicator();
            this.addMessageToUI({
                role: 'system',
                content: 'Sorry, there was an error processing your request.',
                timestamp: new Date().toISOString()
            });
        }
    }

    addMessageToUI(message) {
        const messageList = document.getElementById('messageList');
        const messageElement = this.createMessageElement(message);
        messageList.appendChild(messageElement);
        messageList.scrollTop = messageList.scrollHeight;
    }

    createMessageElement(message) {
        const div = document.createElement('div');
        div.className = `message ${message.role}-message`;

        const content = this.formatMessageContent(message.content);

        div.innerHTML = `
            <div class="message-content">
                ${content}
                <small class="message-time">${this.formatTime(message.timestamp)}</small>
            </div>
        `;

        return div;
    }

    formatMessageContent(content) {
        // Convert markdown to HTML
        content = this.convertMarkdownToHTML(content);

        // Highlight code blocks
        content = this.highlightCodeBlocks(content);

        return content;
    }

    convertMarkdownToHTML(content) {
        // Simple markdown to HTML conversion
        content = content.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
        content = content.replace(/\*(.*?)\*/g, '<em>$1</em>');
        content = content.replace(/`(.*?)`/g, '<code>$1</code>');
        content = content.replace(/\n/g, '<br>');

        return content;
    }

    highlightCodeBlocks(content) {
        // Find code blocks and apply syntax highlighting
        content = content.replace(/```(\w+)?\n([\s\S]*?)```/g, (match, lang, code) => {
            return `<pre><code class="language-${lang || 'text'}">${code}</code></pre>`;
        });

        return content;
    }

    showTypingIndicator() {
        const messageList = document.getElementById('messageList');
        const typingDiv = document.createElement('div');
        typingDiv.className = 'message ai-message typing-indicator';
        typingDiv.id = 'typingIndicator';
        typingDiv.innerHTML = `
            <div class="message-content">
                <div class="typing-dots">
                    <span></span>
                    <span></span>
                    <span></span>
                </div>
            </div>
        `;

        messageList.appendChild(typingDiv);
        messageList.scrollTop = messageList.scrollHeight;
    }

    hideTypingIndicator() {
        const typingIndicator = document.getElementById('typingIndicator');
        if (typingIndicator) {
            typingIndicator.remove();
        }
    }

    formatTime(timestamp) {
        const date = new Date(timestamp);
        return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
    }
}

Best Practices

  1. Rate Limiting: Implement rate limiting to prevent abuse
  2. Content Filtering: Filter inappropriate or harmful content
  3. Token Management: Monitor and limit API token usage
  4. Security: Validate all inputs and sanitize outputs
  5. Performance: Cache responses and optimize API calls
  6. User Experience: Provide clear feedback and error handling
  7. Privacy: Implement proper data protection and user consent

Production Deployment

The AI Agent application is ready for production use in both static HTML and Laravel Livewire editions. For production deployment:

  1. AI Provider Setup - Configure OpenAI, Anthropic, or local LLM
  2. Database Setup - Create necessary tables for conversations and messages
  3. API Keys - Secure storage of AI provider API keys
  4. Rate Limiting - Implement proper rate limiting and usage monitoring
  5. Content Moderation - Set up content filtering and moderation
  6. Monitoring - Monitor API usage and costs
  7. Backup - Implement conversation backup and recovery