160 lines
5.5 KiB
Python
160 lines
5.5 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Integrasi MikroTik MCP Data dengan Gemini AI - Versi Sederhana
|
|
"""
|
|
|
|
import os
|
|
import json
|
|
from google import genai
|
|
from dotenv import load_dotenv
|
|
from datetime import datetime
|
|
from context_optimizer import ContextOptimizer
|
|
from update_data import gather_all_info, save_data
|
|
|
|
# Load environment
|
|
load_dotenv()
|
|
|
|
class MikroTikGeminiAssistant:
|
|
def __init__(self, data_file="data/mikrotik_mcp_data.json"):
|
|
# Setup Gemini Client (SDK Baru)
|
|
api_key = os.getenv("GEMINI_API_KEY")
|
|
if not api_key:
|
|
raise ValueError("GEMINI_API_KEY tidak ditemukan di .env")
|
|
|
|
self.client = genai.Client(api_key=api_key)
|
|
self.model_id = "gemini-2.0-flash"
|
|
|
|
|
|
# Load data
|
|
self.data_file = data_file
|
|
self.data = self._load_data()
|
|
|
|
# Setup Optimizer
|
|
self.optimizer = ContextOptimizer()
|
|
|
|
# Inisialisasi Chat Session
|
|
self.chat_session = None
|
|
self._reset_chat()
|
|
|
|
def refresh_data(self):
|
|
"""Ambil data terbaru langsung dari MikroTik API"""
|
|
print("\n⏳ Sedang mengambil data terbaru dari router...")
|
|
new_data = gather_all_info()
|
|
if new_data:
|
|
save_data(new_data, self.data_file)
|
|
self.data = new_data
|
|
self._reset_chat()
|
|
print("✅ Data berhasil diperbarui dan sesi chat di-reset.")
|
|
return True
|
|
print("❌ Gagal memperbarui data.")
|
|
return False
|
|
|
|
def _reset_chat(self):
|
|
"""Reset session chat dengan konteks MikroTik terbaru yang dioptimasi"""
|
|
optimized = self.optimizer.create_optimized_context(self.data)
|
|
|
|
context = f"""Anda adalah asisten ahli MikroTik. Gunakan data JSON berikut sebagai SATU-SATUNYA sumber kebenaran kondisi router saat ini.
|
|
JANGAN membuat-buat nama interface, IP, atau status yang tidak ada di data ini.
|
|
|
|
DATA ROUTER (OPTIMIZED JSON):
|
|
{json.dumps(optimized, indent=2)}
|
|
|
|
INSTRUKSI:
|
|
1. Jika user bertanya tentang hal spesifik (seperti interface atau route), lihat di bagian 'details' pada JSON di atas.
|
|
2. Jika data tidak ada, katakan jujur bahwa data tersebut tidak tersedia di snapshot saat ini.
|
|
3. Jawab selalu dalam Bahasa Indonesia yang profesional dan format markdown.
|
|
4. Utamakan akurasi data daripada memberikan nasihat umum.
|
|
5. Jika user meminta data paling baru ("live" atau "sekarang"), beritahukan bahwa Anda menggunakan data terakhir yang diambil. User bisa mengetik `sync` atau `refresh` untuk melakukan sinkronisasi ulang data langsung dari router."""
|
|
|
|
self.chat_session = self.client.chats.create(model=self.model_id, history=[])
|
|
# Kirim konteks awal
|
|
self.chat_session.send_message(context)
|
|
|
|
def _load_data(self):
|
|
try:
|
|
with open(self.data_file, 'r') as f:
|
|
return json.load(f)
|
|
except:
|
|
return {"error": "Data tidak ditemukan"}
|
|
|
|
def get_summary(self):
|
|
"""Ringkasan data MikroTik"""
|
|
d = self.data
|
|
system = d.get("system", {})
|
|
|
|
# Handle cases where resource might be a list or missing
|
|
resource = system.get("resource", {})
|
|
if isinstance(resource, list):
|
|
resource = resource[0] if len(resource) > 0 else {}
|
|
|
|
return {
|
|
"device": resource.get("board-name", "N/A"),
|
|
"cpu": resource.get("cpu-load", "N/A"),
|
|
"memory": resource.get("free-memory", "N/A"),
|
|
"uptime": resource.get("uptime", "N/A"),
|
|
"version": resource.get("version", "N/A"),
|
|
"interfaces": len(d.get("interfaces", {}).get("interfaces", [])),
|
|
"ppp_secrets": len(d.get("ppp", {}).get("secrets", [])),
|
|
"timestamp": d.get("metadata", {}).get("timestamp", "N/A")
|
|
}
|
|
|
|
def ask(self, question):
|
|
"""Tanya Gemini menggunakan session chat yang aktif"""
|
|
if not self.chat_session:
|
|
self._reset_chat()
|
|
|
|
try:
|
|
response = self.chat_session.send_message(question)
|
|
return response.text
|
|
except Exception as e:
|
|
return f"Error: {e}"
|
|
|
|
def chat(self):
|
|
"""Mode interaktif yang mendukung history"""
|
|
print("\n" + "="*40)
|
|
print("🤖 MIKROTIK GEMINI INTERACTIVE CHAT")
|
|
print("="*40)
|
|
print("Ketik 'exit' untuk keluar")
|
|
print("Ketik 'reset' untuk mengulang percakapan\n")
|
|
|
|
while True:
|
|
q = input("👤 Anda: ").strip()
|
|
|
|
if not q:
|
|
continue
|
|
|
|
if q.lower() in ['exit', 'quit', 'keluar']:
|
|
print("\nSampai jumpa! 👋")
|
|
break
|
|
|
|
if q.lower() in ['reset', 'refresh', 'sync', 'update']:
|
|
self.refresh_data()
|
|
continue
|
|
|
|
print("\n🤖 AI: Thinking...")
|
|
answer = self.ask(q)
|
|
print(f"\n{answer}\n")
|
|
print("-" * 20)
|
|
|
|
# Main execution
|
|
if __name__ == "__main__":
|
|
import sys
|
|
|
|
if not os.getenv("GEMINI_API_KEY"):
|
|
print("ERROR: Set GEMINI_API_KEY di .env file")
|
|
sys.exit(1)
|
|
|
|
try:
|
|
assistant = MikroTikGeminiAssistant()
|
|
|
|
if len(sys.argv) > 1:
|
|
# Command line mode
|
|
question = " ".join(sys.argv[1:])
|
|
answer = assistant.ask(question)
|
|
print(answer)
|
|
else:
|
|
# Interactive mode
|
|
assistant.chat()
|
|
except Exception as e:
|
|
print(f"Error: {e}")
|