IA / app_mobile.py
Barouia's picture
Create app_mobile.py
b12cab9 verified
Raw
History Blame Contribute Delete
17.9 kB
#!/usr/bin/env python3
"""
Application Mobile Barouia-Cortex Ultimate
Interface complète avec chat, monitoring et contrôle
"""
from fastapi import FastAPI, WebSocket, HTTPException, BackgroundTasks
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.middleware.cors import CORSMiddleware
import uvicorn
import asyncio
import json
import logging
from datetime import datetime
from typing import Dict, List, Any, Optional
import uuid
# Configuration
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("barouia_mobile")
app = FastAPI(title="Barouia-Cortex Mobile", version="3.0.0")
# CORS pour mobile
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Gestionnaire de conversations
class ConversationManager:
def __init__(self):
self.conversations: Dict[str, List[Dict]] = {}
self.user_profiles: Dict[str, Dict] = {}
async def start_conversation(self, user_id: str) -> str:
conv_id = str(uuid.uuid4())
self.conversations[conv_id] = [{
'timestamp': datetime.now(),
'role': 'system',
'content': 'Conversation Barouia-Cortex initialisée'
}]
return conv_id
async def add_message(self, conv_id: str, role: str, content: str):
if conv_id in self.conversations:
self.conversations[conv_id].append({
'timestamp': datetime.now(),
'role': role,
'content': content
})
conv_manager = ConversationManager()
# Interface Web Mobile Optimisée
@app.get("/", response_class=HTMLResponse)
async def mobile_interface():
return """
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Barouia-Cortex Mobile</title>
<style>
:root {
--primary: #667eea;
--secondary: #764ba2;
--accent: #f093fb;
--dark: #0f0f23;
--light: #1a1a2e;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, var(--dark) 0%, var(--light) 100%);
color: white;
height: 100vh;
overflow: hidden;
}
.app-container {
height: 100vh;
display: flex;
flex-direction: column;
max-width: 500px;
margin: 0 auto;
background: rgba(15, 15, 35, 0.95);
}
.header {
background: rgba(26, 26, 46, 0.9);
backdrop-filter: blur(20px);
padding: 1rem;
border-bottom: 1px solid rgba(102, 126, 234, 0.3);
text-align: center;
}
.header h1 {
font-size: 1.5rem;
background: linear-gradient(45deg, var(--primary), var(--accent));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.chat-container {
flex: 1;
overflow-y: auto;
padding: 1rem;
display: flex;
flex-direction: column;
gap: 1rem;
}
.message {
max-width: 80%;
padding: 0.8rem 1rem;
border-radius: 1.2rem;
animation: messageAppear 0.3s ease-out;
}
@keyframes messageAppear {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.user-message {
align-self: flex-end;
background: linear-gradient(45deg, var(--primary), var(--secondary));
margin-left: auto;
}
.ai-message {
align-self: flex-start;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border: 1px solid rgba(102, 126, 234, 0.3);
}
.input-container {
padding: 1rem;
background: rgba(26, 26, 46, 0.9);
backdrop-filter: blur(20px);
border-top: 1px solid rgba(102, 126, 234, 0.3);
}
.input-group {
display: flex;
gap: 0.5rem;
}
#messageInput {
flex: 1;
padding: 0.8rem 1rem;
border: none;
border-radius: 1.5rem;
background: rgba(255, 255, 255, 0.1);
color: white;
font-size: 1rem;
backdrop-filter: blur(10px);
}
#messageInput:focus {
outline: none;
background: rgba(255, 255, 255, 0.15);
}
#sendButton {
padding: 0.8rem 1.2rem;
border: none;
border-radius: 1.5rem;
background: linear-gradient(45deg, var(--primary), var(--secondary));
color: white;
cursor: pointer;
transition: transform 0.2s;
}
#sendButton:active {
transform: scale(0.95);
}
.typing-indicator {
display: none;
align-self: flex-start;
padding: 0.8rem 1rem;
background: rgba(255, 255, 255, 0.1);
border-radius: 1.2rem;
font-style: italic;
color: #a0a0ff;
}
.menu-bar {
display: flex;
justify-content: space-around;
padding: 0.5rem;
background: rgba(26, 26, 46, 0.9);
border-top: 1px solid rgba(102, 126, 234, 0.3);
}
.menu-item {
padding: 0.5rem 1rem;
border: none;
background: transparent;
color: #a0a0ff;
cursor: pointer;
border-radius: 0.8rem;
transition: all 0.3s;
}
.menu-item.active {
background: rgba(102, 126, 234, 0.2);
color: white;
}
.tab-content {
display: none;
flex: 1;
padding: 1rem;
overflow-y: auto;
}
.tab-content.active {
display: block;
}
.stats-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.8rem;
margin-bottom: 1rem;
}
.stat-card {
background: rgba(255, 255, 255, 0.05);
padding: 1rem;
border-radius: 0.8rem;
text-align: center;
border: 1px solid rgba(102, 126, 234, 0.2);
}
.stat-value {
font-size: 1.5rem;
font-weight: bold;
background: linear-gradient(45deg, var(--primary), var(--accent));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.quantum-visualization {
width: 100%;
height: 150px;
background: rgba(0, 0, 0, 0.3);
border-radius: 0.8rem;
margin: 1rem 0;
position: relative;
overflow: hidden;
}
.qubit {
position: absolute;
width: 8px;
height: 8px;
background: var(--accent);
border-radius: 50%;
animation: quantumFloat 3s infinite ease-in-out;
}
@keyframes quantumFloat {
0%, 100% { transform: translateY(0px) rotate(0deg); }
50% { transform: translateY(-20px) rotate(180deg); }
}
</style>
</head>
<body>
<div class="app-container">
<div class="header">
<h1>🧠 Barouia-Cortex</h1>
</div>
<div id="chatTab" class="tab-content active">
<div class="chat-container" id="chatMessages">
<div class="message ai-message">
Bonjour ! Je suis Barouia-Cortex. Comment puis-je vous aider aujourd'hui ?
</div>
</div>
<div class="typing-indicator" id="typingIndicator">
Barouia-Cortex réfléchit...
</div>
<div class="input-container">
<div class="input-group">
<input type="text" id="messageInput" placeholder="Tapez votre message..." autocomplete="off">
<button id="sendButton">📤</button>
</div>
</div>
</div>
<div id="statsTab" class="tab-content">
<div class="stats-grid">
<div class="stat-card">
<div class="stat-value" id="consciousnessLevel">0.75</div>
<div>Conscience</div>
</div>
<div class="stat-card">
<div class="stat-value" id="quantumActivity">85%</div>
<div>Activité Quantique</div>
</div>
<div class="stat-card">
<div class="stat-value" id="messageCount">1</div>
<div>Messages</div>
</div>
<div class="stat-card">
<div class="stat-value" id="responseTime">0.2s</div>
<div>Temps Réponse</div>
</div>
</div>
<div class="quantum-visualization" id="quantumViz">
<!-- Qubits animés -->
</div>
<div style="text-align: center; margin-top: 1rem;">
<button class="menu-item" onclick="refreshStats()">🔄 Actualiser</button>
</div>
</div>
<div class="menu-bar">
<button class="menu-item active" onclick="switchTab('chatTab')">💬 Chat</button>
<button class="menu-item" onclick="switchTab('statsTab')">📊 Stats</button>
<button class="menu-item" onclick="switchTab('settingsTab')">⚙️ Paramètres</button>
<button class="menu-item" onclick="exportConversation()">📤 Exporter</button>
</div>
</div>
<script>
let conversationId = null;
let messageCount = 1;
// Initialisation
document.addEventListener('DOMContentLoaded', function() {
initializeConversation();
createQuantumVisualization();
startStatsUpdate();
});
async function initializeConversation() {
const response = await fetch('/api/conversation/start', {
method: 'POST',
headers: { 'Content-Type': 'application/json' }
});
const data = await response.json();
conversationId = data.conversation_id;
}
// Gestion de l'envoi des messages
document.getElementById('sendButton').addEventListener('click', sendMessage);
document.getElementById('messageInput').addEventListener('keypress', function(e) {
if (e.key === 'Enter') sendMessage();
});
async function sendMessage() {
const input = document.getElementById('messageInput');
const message = input.value.trim();
if (!message) return;
// Ajouter le message de l'utilisateur
addMessageToChat('user', message);
input.value = '';
messageCount++;
updateStats();
// Indicateur de frappe
showTypingIndicator();
try {
const response = await fetch('/api/chat/send', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
conversation_id: conversationId,
message: message
})
});
const data = await response.json();
hideTypingIndicator();
addMessageToChat('ai', data.response);
} catch (error) {
hideTypingIndicator();
addMessageToChat('ai', 'Désolé, une erreur est survenue.');
}
}
function addMessageToChat(role, content) {
const chatContainer = document.getElementById('chatMessages');
const messageDiv = document.createElement('div');
messageDiv.className = `message ${role}-message`;
messageDiv.textContent = content;
chatContainer.appendChild(messageDiv);
chatContainer.scrollTop = chatContainer.scrollHeight;
}
function showTypingIndicator() {
document.getElementById('typingIndicator').style.display = 'block';
}
function hideTypingIndicator() {
document.getElementById('typingIndicator').style.display = 'none';
}
function switchTab(tabName) {
// Masquer tous les onglets
document.querySelectorAll('.tab-content').forEach(tab => {
tab.classList.remove('active');
});
// Désactiver tous les boutons de menu
document.querySelectorAll('.menu-item').forEach(btn => {
btn.classList.remove('active');
});
// Activer l'onglet sélectionné
document.getElementById(tabName).classList.add('active');
event.target.classList.add('active');
}
function createQuantumVisualization() {
const container = document.getElementById('quantumViz');
for (let i = 0; i < 20; i++) {
const qubit = document.createElement('div');
qubit.className = 'qubit';
qubit.style.left = `${Math.random() * 100}%`;
qubit.style.top = `${Math.random() * 100}%`;
qubit.style.animationDelay = `${Math.random() * 3}s`;
container.appendChild(qubit);
}
}
function startStatsUpdate() {
setInterval(updateStats, 2000);
}
function updateStats() {
document.getElementById('messageCount').textContent = messageCount;
document.getElementById('consciousnessLevel').textContent =
(0.75 + Math.random() * 0.1).toFixed(2);
document.getElementById('quantumActivity').textContent =
(80 + Math.random() * 10).toFixed(0) + '%';
}
function refreshStats() {
updateStats();
// Ajouter une animation de rafraîchissement
document.querySelectorAll('.stat-card').forEach(card => {
card.style.animation = 'pulse 0.5s';
setTimeout(() => card.style.animation = '', 500);
});
}
async function exportConversation() {
if (!conversationId) return;
const response = await fetch(`/api/conversation/${conversationId}/export`);
const data = await response.json();
// Créer un fichier de téléchargement
const blob = new Blob([JSON.stringify(data, null, 2)], {type: 'application/json'});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `barouia-conversation-${new Date().toISOString().split('T')[0]}.json`;
a.click();
URL.revokeObjectURL(url);
}
</script>
</body>
</html>
"""