feat(ai): provider OpenAI-compatible + DeepSeek, AI Telegram, self-healing dengan toggle (port upstream)

- telegramAiService/adminAiTools: dukung openai, deepseek, groq, openrouter, custom (base URL + key + model)
- selfHealingService: billing vs isolir, konsistensi secret PPPoE, sesi RADIUS stale, IP ACS kosong
- mikrotikService: getActivePppoeUsers, isolateCustomerPppoe, unisolateCustomerPppoe (upstream memanggil fungsi yang tidak ada)
- cron 30 menit hanya jalan bila ai_self_healing_enabled=true (default off) + scan brute force MikroTik tiap 2 menit
- Pengaturan: kartu AI & Self-Healing (provider, key/model, toggle, tombol Diagnosa/Perbaiki)
- bot Telegram: pesan non-command dari admin dijawab AI
This commit is contained in:
oxpoe
2026-11-05 01:48:50 +07:00
parent 1c40e6a0e8
commit 4003149046
9 changed files with 2022 additions and 4 deletions

View File

@@ -2128,6 +2128,44 @@ async function getBackup(routerId = null) {
}
}
// ─── KOMPATIBILITAS AI / SELF-HEALING ───────────────────────────────────────
async function getActivePppoeUsers() {
const map = await getActivePppoeSessionsMap();
const out = [];
map.forEach((v, user) => out.push({
user,
address: v.ip || '',
uptime: v.uptime || '',
callerId: v.callerId || '',
routerId: v.routerId ?? null,
routerName: v.routerName || ''
}));
return out;
}
async function isolateCustomerPppoe(routerId, username, opts = {}) {
const profile = String(opts.pppoeProfile || 'ISOLIR');
await setPppoeProfile(username, profile, routerId ?? null);
await kickPppoeUser(username, routerId ?? null).catch(() => {});
return true;
}
async function unisolateCustomerPppoe(routerId, username) {
const name = String(username || '').trim();
if (!name) return false;
const row = db.prepare(`
SELECT p.name as package_name
FROM customers c
LEFT JOIN packages p ON c.package_id = p.id
WHERE c.pppoe_username = ? COLLATE NOCASE
LIMIT 1
`).get(name);
const profile = row && row.package_name ? row.package_name : 'default';
await setPppoeProfile(name, profile, routerId ?? null);
return true;
}
module.exports = {
checkConnection,
getConnection,
@@ -2149,6 +2187,9 @@ module.exports = {
getHotspotProfiles,
getPppoeActive,
getActivePppoeSessionsMap,
getActivePppoeUsers,
isolateCustomerPppoe,
unisolateCustomerPppoe,
getAllActiveSessionsMap,
getHotspotActive,
getIpPools,