[TSM.ID].[11031972] PXE : Platform X Ecosystem I [118 Module -LIVE-]
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import Redis from "ioredis";
|
||||
|
||||
// Klien Redis untuk Publisher
|
||||
const redisUrl = process.env.REDIS_URL || "redis://localhost:6379";
|
||||
const redis = new Redis(redisUrl);
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
const body = await req.json();
|
||||
const { channel, event, payload } = body;
|
||||
|
||||
if (!channel || !event) {
|
||||
return NextResponse.json({ error: "Missing channel or event" }, { status: 400 });
|
||||
}
|
||||
|
||||
// IAM tidak menangani host_approve_guest secara langsung dengan DB pg
|
||||
|
||||
const message = JSON.stringify({ event, payload, timestamp: Date.now() });
|
||||
|
||||
// Pancarkan ke Redis PubSub, yang akan ditangkap oleh endpoint SSE
|
||||
await redis.publish(channel, message);
|
||||
|
||||
console.log(`[EMIT] Memancarkan '${event}' ke '${channel}'`);
|
||||
|
||||
return NextResponse.json({ success: true, message: "Signal transmitted" });
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : "Gagal memancarkan sinyal";
|
||||
console.error("[EMIT] Gagal memancarkan sinyal:", message);
|
||||
return NextResponse.json({ error: message }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
|
||||
export async function POST(req: Request) {
|
||||
try {
|
||||
const body = await req.json();
|
||||
const { history, prompt, sender } = body;
|
||||
|
||||
// Environment variables routing
|
||||
const engine = process.env.OMNIBRAIN_ENGINE || "XCU_DEEP_CORE";
|
||||
const openaiKey = process.env.OPENAI_API_KEY;
|
||||
const geminiKey = process.env.GEMINI_API_KEY;
|
||||
const grokKey = process.env.GROK_API_KEY;
|
||||
|
||||
// Proxy URLs for State Audit Compliance
|
||||
const openaiUrl = process.env.OPENAI_API_URL || "http://127.0.0.1:11434/v1/chat/completions";
|
||||
const geminiUrl = process.env.GEMINI_API_URL || "http://127.0.0.1:11434/v1/chat/completions";
|
||||
const grokUrl = process.env.GROK_API_URL || "http://127.0.0.1:11434/v1/chat/completions";
|
||||
|
||||
// Format history for context
|
||||
const historyText = history.map((m: { sender: string; text: string }) => `${m.sender}: ${m.text}`).join('\n');
|
||||
const systemPrompt = 'You are Omni-Brain, an advanced AI telepathic observer inside an End-to-End Encrypted XCU Ultra chat room. Provide concise, highly analytical, and awe-inspiring responses in Indonesian. Use terms like "Jaringan Kuantum", "Matriks Telepati", etc.';
|
||||
const userPrompt = `[Decrypted Context - Top Secret]\n${historyText}\n\nUser [${sender}] commands: ${prompt}`;
|
||||
|
||||
let reply = "";
|
||||
|
||||
// DYNAMIC ROUTING ENGINE
|
||||
if (engine === "OPENAI" && openaiKey) {
|
||||
const response = await fetch(openaiUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${openaiKey}`
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: 'gpt-4o',
|
||||
messages: [
|
||||
{ role: 'system', content: systemPrompt },
|
||||
{ role: 'user', content: userPrompt }
|
||||
],
|
||||
max_tokens: 300
|
||||
})
|
||||
});
|
||||
const data = await response.json();
|
||||
reply = data.choices?.[0]?.message?.content || "";
|
||||
|
||||
} else if (engine === "GEMINI" && geminiKey) {
|
||||
const response = await fetch(geminiUrl, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
contents: [{ parts: [{ text: `${systemPrompt}\n\n${userPrompt}` }] }]
|
||||
})
|
||||
});
|
||||
const data = await response.json();
|
||||
reply = data.candidates?.[0]?.content?.parts?.[0]?.text || "";
|
||||
|
||||
} else if (engine === "GROK" && grokKey) {
|
||||
const response = await fetch(grokUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${grokKey}`
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: 'grok-beta',
|
||||
messages: [
|
||||
{ role: 'system', content: systemPrompt },
|
||||
{ role: 'user', content: userPrompt }
|
||||
]
|
||||
})
|
||||
});
|
||||
const data = await response.json();
|
||||
reply = data.choices?.[0]?.message?.content || "";
|
||||
|
||||
} else {
|
||||
// 1000% DEFAULT FALLBACK: XCU DEEP-CORE LOCAL LLM (OLLAMA / Llama3)
|
||||
// Jaringan Air-Gapped Sovereign murni
|
||||
try {
|
||||
const response = await fetch('http://127.0.0.1:11434/v1/chat/completions', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: 'llama3', // Atau deepseek-coder, mistral, dll.
|
||||
messages: [
|
||||
{ role: 'system', content: systemPrompt },
|
||||
{ role: 'user', content: userPrompt }
|
||||
]
|
||||
})
|
||||
});
|
||||
const data = await response.json();
|
||||
reply = data.choices?.[0]?.message?.content || "";
|
||||
} catch (_e) {
|
||||
return NextResponse.json({ reply: "Sistem XCU Deep-Core LLM terputus. Pastikan daemon Ollama berjalan di peladen (127.0.0.1:11434)." }, { status: 200 });
|
||||
}
|
||||
}
|
||||
|
||||
if (reply) {
|
||||
return NextResponse.json({ reply }, { status: 200 });
|
||||
} else {
|
||||
return NextResponse.json({ reply: "OmniBrain mengalami anomali dalam matriks kuantum. Gagal memproses data." }, { status: 200 });
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('OmniBrain Error:', error);
|
||||
return NextResponse.json({ reply: "Terjadi distorsi telepatik saat memproses neural-link." }, { status: 200 });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import Redis from "ioredis";
|
||||
|
||||
// Klien Redis khusus untuk Subscriber (Mendengarkan event OmniBrain)
|
||||
// Karena ini adalah endpoint streaming, kita membutuhkan instance Redis tersendiri per koneksi (opsional),
|
||||
// namun karena SSE bersifat long-lived, kita instansiasi dalam blok handler.
|
||||
const redisUrl = process.env.REDIS_URL || "redis://localhost:6379";
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
const searchParams = req.nextUrl.searchParams;
|
||||
const channel = searchParams.get("channel"); // Misalnya: "room_alpha_events"
|
||||
|
||||
if (!channel) {
|
||||
return NextResponse.json({ error: "Missing channel" }, { status: 400 });
|
||||
}
|
||||
|
||||
const redis = new Redis(redisUrl);
|
||||
|
||||
const stream = new ReadableStream({
|
||||
async start(controller) {
|
||||
// 1. Subscribe ke channel spesifik di Redis
|
||||
await redis.subscribe(channel, (err, _count) => {
|
||||
if (err) {
|
||||
console.error("[SSE] Gagal subscribe ke Redis:", err);
|
||||
controller.error(err);
|
||||
} else {
|
||||
console.log(`[SSE] OmniBrain terhubung ke saluran: ${channel}`);
|
||||
}
|
||||
});
|
||||
|
||||
// 2. Dengarkan pesan yang dipancarkan oleh API /emit
|
||||
redis.on("message", (subChannel, message) => {
|
||||
if (subChannel === channel) {
|
||||
// Format SSE: "data: {JSON}\n\n"
|
||||
controller.enqueue(`data: ${message}\n\n`);
|
||||
}
|
||||
});
|
||||
|
||||
// 3. Keep-Alive (Mencegah koneksi HTTP ditutup oleh Proxy/Nginx)
|
||||
const keepAlive = setInterval(() => {
|
||||
controller.enqueue(":\n\n"); // Komentar SSE untuk keep-alive
|
||||
}, 15000);
|
||||
|
||||
// 4. Deteksi klien putus
|
||||
req.signal.addEventListener("abort", () => {
|
||||
clearInterval(keepAlive);
|
||||
redis.disconnect();
|
||||
console.log(`[SSE] Klien terputus dari saluran: ${channel}`);
|
||||
});
|
||||
},
|
||||
cancel() {
|
||||
redis.disconnect();
|
||||
}
|
||||
});
|
||||
|
||||
return new NextResponse(stream, {
|
||||
headers: {
|
||||
"Content-Type": "text/event-stream",
|
||||
"Cache-Control": "no-cache, no-transform",
|
||||
"Connection": "keep-alive",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
},
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user