Membuat AI Asisten di laptop online/offline seperti jarvis
Anda berbicara dengan laptop, dan ia langsung merespons - membuka aplikasi, mencari file, menganalisis data, bahkan memprediksi kebutuhan Anda.
Tidak lagi sekadar perangkat, tapi partner cerdas yang memahami setiap perintah, baik dengan atau tanpa internet.💡 Fakta Mengejutkan:
90% pengguna laptop hanya menggunakan 30% potensi sebenarnya dari perangkat mereka. Sisa 70% itu? Kini bisa diaktifkan dengan AI - menjadikan setiap klik, setiap tugas, setiap operasi menjadi lebih cepat, lebih pintar, dan lebih intuitif.🚀 APA YANG AKAN ANDA DAPATKAN?
OFFLINE MODE - AI Mandiri di Perangkat Anda:
"Privasi 100%, Kecepatan Instant, Kontrol Penuh"
Kendalikan laptop dengan suara atau teks
Otomatiskan tugas harian dengan kecerdasan lokal
Analisis file dan sistem tanpa kirim data ke cloud
Respons instan tanpa latency
ONLINE MODE - Kekuatan AI Global:
"Akses Pengetahuan Dunia, Kemampuan Tak Terbatas"
Tanya real-time data (cuaca, berita, pasar)
Terjemahan 100+ bahasa secara live
Analisis data dengan model AI terbaru
Integrasi dengan layanan cloud
HYBRID INTELLIGENCE - Yang Terbaik dari Keduanya:
"Cerdas Memilih: Kapan Offline, Kapan Online"
AI yang secara otomatis memilih mode optimal
Switching seamless antara lokal dan cloud
Backup intelligence saat offline
Optimalisasi biaya dan privasi
🎬 SKENARIO PENGGUNAAN NYATA:
📅 Pagi Hari:
"Hey AI, buka email dan ringkas prioritas hari ini"
➡️ AI membuka Gmail, menganalisis email, menyajikan 3 tugas utama💼 Bekerja:
"Cari file laporan Q3 dan analisis trend penjualan"
➡️ AI mencari file, membuat visualisasi, memberikan insight🌙 Malam:
"Backup semua dokumen penting dan matikan dalam 30 menit"
➡️ AI menjalankan backup otomatis, kemudian shutdown🎯 ARSITEKTUR SISTEM HYBRIDDiagram Arsitektur:
text[User Input] → [Router AI] → {Offline Mode / Online Mode} ↓ [Local Processing] [Cloud Processing] ↓ ↓ [Response Combiner] → [Final Output]🚀 SETUP KOMPLIT STEP-BY-STEP
A. INSTALASI DASAR (Windows/Linux/Mac)
1. Install Python & Dependencies:
bash# Windows (PowerShell sebagai Admin) winget install Python.Python.3.12 pip install virtualenv # Buat environment python -m venv ai_assistant .\ai_assistant\Scripts\activate # Install semua library pip install ollama openai pyautogui speechrecognition pip install pyttsx3 whisper pygame pyaudio pip install psutil requests beautifulsoup4 pip install customtkinter plyer2. Setup Model AI Lokal (Offline):
bash# Install Ollama # Windows: unduh dari ollama.ai # Linux: curl -fsSL https://ollama.ai/install.sh | sh # Download model (pilih sesuai RAM Anda) ollama pull llama3.2:3b # Minimal (3GB RAM) ollama pull qwen2.5:7b # Recommended (8GB RAM) ollama pull deepseek-coder # Untuk programming tasks # Alternatif: GPT4All (lebih ringan) # Download dari gpt4all.io3. Setup Voice Recognition:
bash# Offline STT (Speech-to-Text) pip install whisper.cpp # Download model kecil whisper --model tiny # Online STT opsional pip install google-cloud-speechB. KODE UTAMA:
ai_assistant.pypythonimport os import sys import json import threading import queue import subprocess from datetime import datetime from enum import Enum import pyautogui import psutil import requests import speech_recognition as sr import pyttsx3 import whisper from typing import Optional, Dict, Any class Mode(Enum): OFFLINE = "offline" ONLINE = "online" AUTO = "auto" class LaptopAI: def __init__(self): self.mode = Mode.AUTO self.is_voice_enabled = True self.command_history = [] # Inisialisasi TTS self.tts_engine = pyttsx3.init() self.tts_engine.setProperty('rate', 150) # Inisialisasi STT self.recognizer = sr.Recognizer() self.microphone = sr.Microphone() # Model Whisper untuk offline STT try: self.whisper_model = whisper.load_model("tiny") except: print("Warning: Whisper model not loaded") # Komponen sistem self.system_monitor = SystemMonitor() self.task_automator = TaskAutomator() self.file_manager = FileManager() self.web_controller = WebController() # Queue untuk multi-threading self.command_queue = queue.Queue() # API Keys (simpan di .env) self.online_apis = { "openai": os.getenv("OPENAI_API_KEY", ""), "google": os.getenv("GOOGLE_API_KEY", ""), "huggingface": os.getenv("HF_TOKEN", "") } def listen(self, timeout=5) -> Optional[str]: """Dengarkan perintah suara""" if not self.is_voice_enabled: return None try: with self.microphone as source: print("🎤 Listening...") self.recognizer.adjust_for_ambient_noise(source) audio = self.recognizer.listen(source, timeout=timeout) if self.mode == Mode.OFFLINE: # Gunakan whisper offline result = self.whisper_model.transcribe(audio.get_wav_data()) return result["text"] else: # Gunakan Google Speech (online) return self.recognizer.recognize_google(audio) except Exception as e: print(f"Error listening: {e}") return None def speak(self, text: str): """Bicara dengan TTS""" print(f"🤖: {text}") if self.is_voice_enabled: self.tts_engine.say(text) self.tts_engine.runAndWait() def process_command(self, command: str) -> str: """Proses perintah dengan routing cerdas""" self.command_history.append({ "time": datetime.now().isoformat(), "command": command, "mode": self.mode.value }) # Auto mode selection if self.mode == Mode.AUTO: use_online = self.should_use_online(command) current_mode = Mode.ONLINE if use_online else Mode.OFFLINE else: current_mode = self.mode # Process based on mode if current_mode == Mode.OFFLINE: return self.process_offline(command) else: return self.process_online(command) def should_use_online(self, command: str) -> bool: """Deterministik: kapan gunakan online mode""" online_keywords = [ "real-time", "search", "latest", "current", "weather", "news", "translate", "stock", "sports", "research" ] # Cek koneksi internet if not self.check_internet(): return False # Cek jika memerlukan data real-time return any(keyword in command.lower() for keyword in online_keywords) def check_internet(self) -> bool: """Cek koneksi internet""" try: requests.get("https://8.8.8.8", timeout=2) return True except: return False def process_offline(self, command: str) -> str: """Proses perintah secara offline""" # Local commands database commands_db = { # Sistem Operasi "shutdown": self.system_shutdown, "restart": self.system_restart, "sleep": self.system_sleep, "lock": self.system_lock, # Aplikasi "open chrome": self.open_chrome, "open notepad": self.open_notepad, "open calculator": self.open_calculator, # File Management "list files": self.list_files, "clean desktop": self.clean_desktop, "find file": self.find_file, # System Info "battery status": self.check_battery, "memory usage": self.check_memory, "cpu temperature": self.check_cpu_temp, # Automation "take screenshot": self.take_screenshot, "type text": self.type_text, "click": self.mouse_click, # Custom "hello": lambda: "Hello! I'm your offline assistant", "what can you do": self.list_capabilities } # Fuzzy matching untuk command cmd_lower = command.lower() for cmd_key, cmd_func in commands_db.items(): if cmd_key in cmd_lower: try: return cmd_func() except Exception as e: return f"Error executing {cmd_key}: {e}" # Default: gunakan model lokal return self.use_local_llm(command) def process_online(self, command: str) -> str: """Proses perintah secara online""" # Prioritas: gunakan OpenAI jika ada API key if self.online_apis["openai"]: return self.use_openai(command) elif self.online_apis["google"]: return self.use_google_ai(command) else: # Fallback ke offline return self.process_offline(command) def use_local_llm(self, prompt: str) -> str: """Gunakan model lokal via Ollama""" try: import ollama # System prompt untuk operasi laptop system_prompt = """You are a laptop AI assistant. Help with: 1. File operations 2. System commands 3. Application control 4. Troubleshooting 5. Automation scripts Provide concise, executable answers.""" response = ollama.chat(model='llama3.2:3b', messages=[ {'role': 'system', 'content': system_prompt}, {'role': 'user', 'content': prompt} ]) return response['message']['content'] except Exception as e: return f"Local LLM error: {e}. Falling back to basic response." def use_openai(self, prompt: str) -> str: """Gunakan OpenAI API""" try: from openai import OpenAI client = OpenAI(api_key=self.online_apis["openai"]) response = client.chat.completions.create( model="gpt-4-turbo", messages=[ {"role": "system", "content": "You are a laptop AI assistant."}, {"role": "user", "content": prompt} ], max_tokens=500 ) return response.choices[0].message.content except Exception as e: return f"OpenAI error: {e}" def use_google_ai(self, prompt: str) -> str: """Gunakan Google Gemini""" try: import google.generativeai as genai genai.configure(api_key=self.online_apis["google"]) model = genai.GenerativeModel('gemini-pro') response = model.generate_content(prompt) return response.text except: return "Google AI not available" # ===== SYSTEM COMMANDS ===== def system_shutdown(self): """Matikan laptop""" self.speak("Shutting down in 10 seconds") os.system("shutdown /s /t 10") return "System will shutdown in 10 seconds" def system_restart(self): """Restart laptop""" os.system("shutdown /r /t 10") return "Restarting in 10 seconds" def system_sleep(self): """Sleep mode""" os.system("rundll32.exe powrprof.dll,SetSuspendState 0,1,0") return "Entering sleep mode" def system_lock(self): """Lock screen""" if sys.platform == "win32": os.system("rundll32.exe user32.dll,LockWorkStation") return "Screen locked" # ===== FILE MANAGEMENT ===== def list_files(self, directory="."): """List files in directory""" files = os.listdir(directory) return f"Files in {directory}: {', '.join(files[:10])}" def clean_desktop(self): """Organize desktop files""" desktop = os.path.join(os.path.expanduser("~"), "Desktop") for file in os.listdir(desktop): # Simple organization by extension if '.' in file: ext = file.split('.')[-1] folder = os.path.join(desktop, ext.upper()) os.makedirs(folder, exist_ok=True) os.rename( os.path.join(desktop, file), os.path.join(folder, file) ) return "Desktop organized by file type" # ===== SYSTEM INFO ===== def check_battery(self): """Check battery status""" battery = psutil.sensors_battery() if battery: percent = battery.percent plugged = battery.power_plugged status = "Charging" if plugged else "Discharging" return f"Battery: {percent}% - {status}" return "Battery info not available" def check_memory(self): """Check memory usage""" memory = psutil.virtual_memory() return f"Memory: {memory.percent}% used ({memory.used/1e9:.1f} GB)" def check_cpu_temp(self): """Check CPU temperature""" try: temps = psutil.sensors_temperatures() if 'coretemp' in temps: temp = temps['coretemp'][0].current return f"CPU Temperature: {temp}°C" except: pass return "Temperature info not available" # ===== AUTOMATION ===== def take_screenshot(self): """Take screenshot""" screenshot_dir = os.path.join(os.path.expanduser("~"), "Pictures", "Screenshots") os.makedirs(screenshot_dir, exist_ok=True) timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") filename = os.path.join(screenshot_dir, f"screenshot_{timestamp}.png") screenshot = pyautogui.screenshot() screenshot.save(filename) return f"Screenshot saved: {filename}" def mouse_click(self, x=None, y=None): """Click mouse at position""" if x and y: pyautogui.click(x, y) else: pyautogui.click() return "Mouse clicked" def type_text(self, text="Hello World"): """Type text""" pyautogui.write(text, interval=0.1) return f"Typed: {text}" def list_capabilities(self): """List semua kemampuan""" return """I can help with: 1. System control (shutdown, restart, sleep) 2. File management (organize, search) 3. Application control (open apps) 4. Automation (screenshot, typing) 5. System monitoring (battery, memory, CPU) 6. Voice commands 7. Web control (online mode) 8. AI conversations (offline/online)""" # ===== APPLICATION CONTROL ===== def open_chrome(self): """Open Chrome browser""" try: subprocess.Popen(["chrome.exe"] if sys.platform == "win32" else ["google-chrome"]) return "Opening Chrome" except: return "Chrome not found" def open_notepad(self): """Open Notepad""" subprocess.Popen(["notepad.exe"] if sys.platform == "win32" else ["gedit"]) return "Opening Notepad" def open_calculator(self): """Open Calculator""" subprocess.Popen(["calc.exe"] if sys.platform == "win32" else ["gnome-calculator"]) return "Opening Calculator" class SystemMonitor: """Monitor system resources""" def __init__(self): pass def get_system_info(self): info = { "cpu_usage": psutil.cpu_percent(), "memory_usage": psutil.virtual_memory().percent, "disk_usage": psutil.disk_usage('/').percent, "battery": psutil.sensors_battery().percent if hasattr(psutil, "sensors_battery") else None } return info class TaskAutomator: """Automate common tasks""" def __init__(self): self.tasks = [] def schedule_task(self, task, time): """Schedule automated task""" self.tasks.append({"task": task, "time": time}) return f"Task scheduled for {time}" class FileManager: """Manage files intelligently""" def __init__(self): pass def smart_search(self, query): """Search files with AI""" # Implementasi search dengan embeddings lokal pass class WebController: """Control web browser""" def __init__(self): pass def search_web(self, query): """Search the web""" import webbrowser webbrowser.open(f"https://www.google.com/search?q={query}") return f"Searching for: {query}" # ===== GUI INTERFACE ===== import tkinter as tk from tkinter import ttk, scrolledtext import threading class AIAssistantGUI: def __init__(self, master): self.master = master master.title("🤖 Laptop AI Assistant") master.geometry("800x600") self.ai = LaptopAI() # Setup GUI self.setup_gui() # Start voice listener thread self.listening = False self.start_voice_listener() def setup_gui(self): # Mode Selection mode_frame = ttk.Frame(self.master) mode_frame.pack(pady=10) ttk.Label(mode_frame, text="Mode:").pack(side=tk.LEFT) self.mode_var = tk.StringVar(value="auto") modes = [("Auto", "auto"), ("Offline", "offline"), ("Online", "online")] for text, value in modes: ttk.Radiobutton(mode_frame, text=text, variable=self.mode_var, value=value, command=self.change_mode).pack(side=tk.LEFT, padx=5) # Voice Toggle self.voice_var = tk.BooleanVar(value=True) ttk.Checkbutton(mode_frame, text="Voice", variable=self.voice_var, command=self.toggle_voice).pack(side=tk.LEFT, padx=20) # Chat Display self.chat_display = scrolledtext.ScrolledText(self.master, height=20, width=70) self.chat_display.pack(pady=10, padx=20, fill=tk.BOTH, expand=True) # Input Frame input_frame = ttk.Frame(self.master) input_frame.pack(pady=10, fill=tk.X, padx=20) self.input_text = ttk.Entry(input_frame, width=50) self.input_text.pack(side=tk.LEFT, fill=tk.X, expand=True) self.input_text.bind("<Return>", self.send_text_command) ttk.Button(input_frame, text="Send", command=self.send_text_command).pack(side=tk.LEFT, padx=5) ttk.Button(input_frame, text="🎤 Listen", command=self.start_listening).pack(side=tk.LEFT) # Quick Commands quick_frame = ttk.Frame(self.master) quick_frame.pack(pady=10) commands = ["Battery", "Screenshot", "Open Chrome", "Clean Desktop", "Shutdown"] for cmd in commands: ttk.Button(quick_frame, text=cmd, command=lambda c=cmd: self.send_quick_command(c)).pack(side=tk.LEFT, padx=5) def change_mode(self): mode_map = { "auto": Mode.AUTO, "offline": Mode.OFFLINE, "online": Mode.ONLINE } self.ai.mode = mode_map[self.mode_var.get()] self.add_to_chat(f"Mode changed to {self.ai.mode.value}") def toggle_voice(self): self.ai.is_voice_enabled = self.voice_var.get() status = "enabled" if self.ai.is_voice_enabled else "disabled" self.add_to_chat(f"Voice {status}") def add_to_chat(self, text, sender="System"): self.chat_display.insert(tk.END, f"\n[{sender}]: {text}") self.chat_display.see(tk.END) def send_text_command(self, event=None): command = self.input_text.get() if command.strip(): self.add_to_chat(command, "You") self.input_text.delete(0, tk.END) # Process in background thread threading.Thread(target=self.process_command, args=(command,)).start() def send_quick_command(self, command): self.add_to_chat(command, "Quick Command") threading.Thread(target=self.process_command, args=(command,)).start() def process_command(self, command): response = self.ai.process_command(command) self.master.after(0, self.add_to_chat, response, "AI") def start_listening(self): if not self.listening: threading.Thread(target=self.voice_listen_loop).start() def voice_listen_loop(self): self.listening = True while self.listening: command = self.ai.listen() if command: self.master.after(0, self.add_to_chat, command, "You (Voice)") self.master.after(0, self.process_command, command) def start_voice_listener(self): # Start voice listener in background threading.Thread(target=self.voice_listen_loop, daemon=True).start() # ===== CONFIGURATION FILE ===== CONFIG_TEMPLATE = { "assistant": { "name": "LaptopAI", "voice_enabled": True, "default_mode": "auto", "hotkey": "Ctrl+Shift+A" }, "paths": { "screenshots": "~/Pictures/Screenshots", "logs": "~/Documents/AI_Assistant/logs", "models": "~/Documents/AI_Assistant/models" }, "online_services": { "openai_api_key": "", "google_api_key": "", "huggingface_token": "" }, "local_models": { "llm": "llama3.2:3b", "stt": "whisper-tiny", "tts": "pyttsx3" } } def save_config(config): config_dir = os.path.join(os.path.expanduser("~"), ".ai_assistant") os.makedirs(config_dir, exist_ok=True) config_file = os.path.join(config_dir, "config.json") with open(config_file, 'w') as f: json.dump(config, f, indent=2) def load_config(): config_file = os.path.join(os.path.expanduser("~"), ".ai_assistant", "config.json") if os.path.exists(config_file): with open(config_file, 'r') as f: return json.load(f) return CONFIG_TEMPLATE # ===== MAIN EXECUTION ===== def main(): print("🚀 Starting Laptop AI Assistant...") # Load configuration config = load_config() # Choose interface if len(sys.argv) > 1 and sys.argv[1] == "--cli": # Command Line Interface run_cli() else: # Graphical Interface root = tk.Tk() app = AIAssistantGUI(root) root.mainloop() def run_cli(): """Run in command line mode""" ai = LaptopAI() print("\n" + "="*50) print("🤖 Laptop AI Assistant - CLI Mode") print("Commands: 'voice on/off', 'mode offline/online/auto', 'exit'") print("="*50 + "\n") ai.speak("AI Assistant ready") while True: try: command = input("You: ").strip() if command.lower() == 'exit': break elif command.lower() == 'voice on': ai.is_voice_enabled = True print("Voice enabled") elif command.lower() == 'voice off': ai.is_voice_enabled = False print("Voice disabled") elif command.startswith('mode '): mode = command.split(' ')[1] if mode in ['offline', 'online', 'auto']: ai.mode = Mode(mode) print(f"Mode set to {mode}") else: response = ai.process_command(command) print(f"AI: {response}") except KeyboardInterrupt: print("\nGoodbye!") break except Exception as e: print(f"Error: {e}") if __name__ == "__main__": main()Tutorial📁 STRUKTUR PROYEK
textai_assistant/ │ ├── main.py # Kode utama ├── requirements.txt # Dependencies ├── config.json # Konfigurasi │ ├── modules/ │ ├── voice.py # Voice processing │ ├── automation.py # Automation scripts │ ├── llm_local.py # Local AI models │ └── web_tools.py # Online tools │ ├── models/ # Model AI lokal │ ├── whisper/ │ └── llama/ │ ├── scripts/ # Automation scripts │ ├── backup.py │ ├── cleanup.py │ └── monitor.py │ └── logs/ # Log aktivitas📋
requirements.txttxt# Core python>=3.8 ollama>=0.1.0 openai>=1.0.0 pyautogui>=0.9.0 speechrecognition>=3.10.0 pyttsx3>=2.90 whisper>=1.0 openai-whisper>=20231117 # System psutil>=5.9.0 pygetwindow>=0.0.9 pyperclip>=1.8.2 keyboard>=0.13.5 # GUI customtkinter>=5.2.0 Pillow>=10.0.0 # Web requests>=2.31.0 beautifulsoup4>=4.12.0 selenium>=4.15.0 # Utilities python-dotenv>=1.0.0 schedule>=1.2.0 plyer>=2.1.0⚙️ SETUP INSTALASI CEPAT
Windows (PowerShell Admin):
powershell# 1. Install Python dan Ollama winget install Python.Python.3.12 winget install Ollama.Ollama # 2. Clone repo git clone https://github.com/your-repo/ai-assistant.git cd ai-assistant # 3. Setup virtual environment python -m venv venv .\venv\Scripts\activate # 4. Install dependencies pip install -r requirements.txt # 5. Download model ollama pull llama3.2:3b # 6. Run python main.pyLinux/Mac:
bash# 1. Install dependencies sudo apt-get install portaudio19-dev python3-pyaudio # Linux brew install portaudio # Mac # 2. Setup bash setup.sh🎮 PERINTAH CONTOH
Offline Mode:
text"buka chrome" "ambil screenshot" "berapa persen baterai" "rapikan desktop" "matikan laptop dalam 5 menit" "cari file pdf" "buat folder baru proyek"Online Mode:
text"cuaca hari ini" "berita terbaru teknologi" "terjemahkan halo ke bahasa jepang" "harga bitcoin sekarang" "cari tutorial python di youtube"Advanced:
text"jadwalkan backup setiap jam 3 pagi" "monitor penggunaan CPU dan beri tahu jika >80%" "otomatis matikan jika suhu >90 derajat" "buat laporan penggunaan laptop mingguan"🔧 TROUBLESHOOTING
Masalah Umum & Solusi:
Suara tidak bekerja:
bash# Windows: Install PyAudio wheel pip install pipwin pipwin install pyaudio # Linux: Install ALSA sudo apt-get install alsa-utilsOllama tidak jalan:
bash# Restart service ollama serve # Download model ulang ollama rm llama3.2 ollama pull llama3.2:3bGPU tidak terdeteksi:
bash# CUDA untuk NVIDIA pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # ROCm untuk AMD pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/rocm5.6🚀 FITUR LANJUTAN
1. Scheduled Tasks:
python# Tambahkan di main.py import schedule import time def daily_backup(): ai.speak("Running daily backup") # Backup script here schedule.every().day.at("03:00").do(daily_backup) while True: schedule.run_pending() time.sleep(60)2. Remote Control:
python# Control via smartphone from flask import Flask, request app = Flask(__name__) @app.route('/command', methods=['POST']) def remote_command(): command = request.json.get('command') response = ai.process_command(command) return {'response': response}3. Learning Mode:
python# AI belajar dari kebiasaan user class LearningModule: def learn_pattern(self, command, time_of_day): # Simpan pattern ke database lokal pass def predict_command(self, context): # Prediksi perintah berikutnya pass📊 OPTIMASI PERFORMANCE
Untuk Laptop Rendah Spesifikasi:
python# config.json { "optimization": { "use_4bit_quantization": true, "cache_model_in_ram": false, "max_ram_usage": "2GB", "disable_animations": true } }Untuk Gaming Laptop:
python{ "gpu_acceleration": true, "vram_priority": "high", "thermal_throttling": 85, "game_mode": true # Kurangi AI saat gaming }🔒 KEAMANAN
python# security.py class SecurityLayer: def authenticate_user(self): # Face recognition/Windows Hello pass def encrypt_sensitive_data(self): # Encrypt API keys dan logs pass def permission_manager(self): # Kontrol akses perintah pass🎯 ROADMAP PENGEMBANGAN
Phase 1 - Basic Assistant (Selesai)
Phase 2 - Multi-language Support
Phase 3 - Computer Vision Integration
Phase 4 - Predictive Automation
Phase 5 - Distributed AI Network
📞 DUKUNGAN
Jika ada masalah:
Cek log di
~/.ai_assistant/logs/Update dependencies:
pip install --upgrade -r requirements.txtReset config: Hapus
~/.ai_assistant/config.jsonIssues: Buat issue di GitHub repo
Tips Final:
Mulai dengan mode offline untuk privasi maksimal
Gunakan online mode hanya untuk tugas spesifik
Backup konfigurasi secara berkala
Update model AI lokal setiap bulan
Sistem ini akan mengubah laptop Anda menjadi asisten AI yang powerful, bekerja seamless antara offline dan online mode! 🚀
