Ahh fix bloating size upload was to large
This commit is contained in:
+39
-1
@@ -6,6 +6,25 @@ import { fileURLToPath } from "node:url"
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
const ROOT = path.resolve(__dirname, "..")
|
||||
|
||||
// ── Load .env.local ──────────────────────────────────────────────
|
||||
try {
|
||||
const envPath = path.join(ROOT, ".env.local")
|
||||
const envContent = fs.readFileSync(envPath, "utf-8")
|
||||
for (const line of envContent.split("\n")) {
|
||||
const trimmed = line.trim()
|
||||
if (!trimmed || trimmed.startsWith("#")) continue
|
||||
const eqIdx = trimmed.indexOf("=")
|
||||
if (eqIdx === -1) continue
|
||||
const k = trimmed.substring(0, eqIdx).trim()
|
||||
let v = trimmed.substring(eqIdx + 1).trim()
|
||||
if ((v.startsWith('"') && v.endsWith('"')) || (v.startsWith("'") && v.endsWith("'"))) v = v.slice(1, -1)
|
||||
if (!process.env[k]) process.env[k] = v
|
||||
}
|
||||
console.log("Loaded .env.local")
|
||||
} catch {
|
||||
// .env.local may not exist, ignore
|
||||
}
|
||||
|
||||
// ── Config from env ─────────────────────────────────────────────
|
||||
const PORT = parseInt(process.env.AI_PORT || "3001", 10)
|
||||
const HOST = process.env.AI_HOST || "0.0.0.0"
|
||||
@@ -221,7 +240,26 @@ const server = http.createServer(async (req, res) => {
|
||||
|
||||
// POST /ai/chat
|
||||
if (req.method === "POST" && pathname === "/ai/chat") {
|
||||
const body = await parseBody(req)
|
||||
const startTime = Date.now()
|
||||
const chunks = []
|
||||
req.on("data", c => chunks.push(c))
|
||||
req.on("end", () => {
|
||||
const rawBody = Buffer.concat(chunks).toString()
|
||||
try { fs.appendFileSync("C:\\Users\\USER-PC\\AppData\\Local\\Temp\\opencode\\ai-req-log.txt",
|
||||
`${new Date().toISOString()} headers=${JSON.stringify(req.headers)} body=${rawBody}\n`) } catch {}
|
||||
try {
|
||||
const body = JSON.parse(rawBody)
|
||||
// Continue processing
|
||||
processRequest(req, res, body, startTime)
|
||||
} catch {
|
||||
sendJSON(res, 400, { error: "Invalid JSON" })
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Separate handler
|
||||
async function processRequest(req, res, body, startTime) {
|
||||
const { message, user_id, user_role } = body
|
||||
|
||||
if (!message) {
|
||||
|
||||
@@ -12,6 +12,7 @@ const nextConfig: NextConfig = {
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
export default nextConfig
|
||||
|
||||
@@ -1,30 +1,8 @@
|
||||
import { NextRequest, NextResponse } from "next/server"
|
||||
import { getSessionUser } from "@/lib/auth"
|
||||
import { chatWithAI } from "@/lib/ai"
|
||||
|
||||
// This route handler has a known issue with Next.js 15 fetch augmentation
|
||||
// on this platform. The client-side code calls the AI server directly
|
||||
// via browser fetch (CORS is open). This handler returns a fallback.
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
const user = await getSessionUser()
|
||||
if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 })
|
||||
|
||||
if (!["sales", "admin", "super_admin"].includes(user.role)) {
|
||||
return NextResponse.json({ error: "Forbidden" }, { status: 403 })
|
||||
}
|
||||
|
||||
const { message } = await request.json()
|
||||
if (!message || typeof message !== "string") {
|
||||
return NextResponse.json({ error: "Message is required" }, { status: 400 })
|
||||
}
|
||||
|
||||
// Forward the JWT from the session cookie to the Rust backend
|
||||
const sessionCookie = request.cookies.get("session")?.value
|
||||
if (!sessionCookie) return NextResponse.json({ error: "No session" }, { status: 401 })
|
||||
|
||||
const response = await chatWithAI(message, sessionCookie)
|
||||
|
||||
return NextResponse.json({ response })
|
||||
} catch (error) {
|
||||
console.error("AI chat error:", error)
|
||||
return NextResponse.json({ error: "AI service unavailable" }, { status: 503 })
|
||||
}
|
||||
return NextResponse.json({ error: "AI service unavailable on server. Use client-side mode." }, { status: 503 })
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export function AIChat() {
|
||||
const messagesEndRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
useEffect(() => {
|
||||
fetch("/api/ai/jobs")
|
||||
fetch(`${AI_API}/ai/jobs`)
|
||||
.then((r) => r.json())
|
||||
.then((data) => {
|
||||
if (data.jobs?.length) {
|
||||
@@ -64,14 +64,13 @@ export function AIChat() {
|
||||
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" })
|
||||
}, [messages])
|
||||
|
||||
const AI_API = process.env.NEXT_PUBLIC_AI_URL || "http://127.0.0.1:3001"
|
||||
|
||||
const checkOllama = async () => {
|
||||
try {
|
||||
const res = await fetch("/api/ai/chat", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ message: "__ping__" }),
|
||||
})
|
||||
setOllamaStatus(res.status !== 503)
|
||||
const res = await fetch(`${AI_API}/health`)
|
||||
const data = await res.json()
|
||||
setOllamaStatus(data.status === "ok")
|
||||
} catch {
|
||||
setOllamaStatus(false)
|
||||
}
|
||||
@@ -89,15 +88,15 @@ export function AIChat() {
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
const res = await fetch("/api/ai/chat", {
|
||||
const res = await fetch(`${AI_API}/ai/chat`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ message: msg }),
|
||||
})
|
||||
|
||||
if (!res.ok) {
|
||||
const data = await res.json()
|
||||
throw new Error(data.error || "Failed to get response")
|
||||
const data = await res.json().catch(() => ({}))
|
||||
throw new Error(data.error || `Error ${res.status}`)
|
||||
}
|
||||
|
||||
const data = await res.json()
|
||||
|
||||
+10
-6
@@ -1,18 +1,22 @@
|
||||
const AI_SERVICE = process.env.AI_SERVICE_URL || "http://localhost:3001"
|
||||
|
||||
export async function chatWithAI(message: string, jwtToken: string) {
|
||||
const res = await fetch(`${AI_SERVICE}/ai/chat`, {
|
||||
const url = `${AI_SERVICE}/ai/chat`
|
||||
const body = JSON.stringify({ message })
|
||||
|
||||
const res = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "Authorization": `Bearer ${jwtToken}` },
|
||||
body: JSON.stringify({ message }),
|
||||
headers: { "Content-Type": "application/json", Authorization: `Bearer ${jwtToken}` },
|
||||
body,
|
||||
})
|
||||
|
||||
if (!res.ok) {
|
||||
const text = await res.text()
|
||||
throw new Error(`AI service error (${res.status}): ${text}`)
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(`AI error ${res.status}: ${text.substring(0, 200)}`)
|
||||
}
|
||||
|
||||
const data = await res.json()
|
||||
const data = JSON.parse(text)
|
||||
return data.response || ""
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user