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
- Rate Limiting: Implement rate limiting to prevent abuse
- Content Filtering: Filter inappropriate or harmful content
- Token Management: Monitor and limit API token usage
- Security: Validate all inputs and sanitize outputs
- Performance: Cache responses and optimize API calls
- User Experience: Provide clear feedback and error handling
- 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:
- AI Provider Setup - Configure OpenAI, Anthropic, or local LLM
- Database Setup - Create necessary tables for conversations and messages
- API Keys - Secure storage of AI provider API keys
- Rate Limiting - Implement proper rate limiting and usage monitoring
- Content Moderation - Set up content filtering and moderation
- Monitoring - Monitor API usage and costs
- Backup - Implement conversation backup and recovery