Ahh fix bloating size upload was to large

This commit is contained in:
Ace
2026-06-24 09:54:28 +02:00
parent 2b4749e5e1
commit b2a2f7e40f
5 changed files with 63 additions and 43 deletions
+39 -1
View File
@@ -6,6 +6,25 @@ import { fileURLToPath } from "node:url"
const __dirname = path.dirname(fileURLToPath(import.meta.url)) const __dirname = path.dirname(fileURLToPath(import.meta.url))
const ROOT = path.resolve(__dirname, "..") 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 ───────────────────────────────────────────── // ── Config from env ─────────────────────────────────────────────
const PORT = parseInt(process.env.AI_PORT || "3001", 10) const PORT = parseInt(process.env.AI_PORT || "3001", 10)
const HOST = process.env.AI_HOST || "0.0.0.0" const HOST = process.env.AI_HOST || "0.0.0.0"
@@ -221,7 +240,26 @@ const server = http.createServer(async (req, res) => {
// POST /ai/chat // POST /ai/chat
if (req.method === "POST" && pathname === "/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 const { message, user_id, user_role } = body
if (!message) { if (!message) {
+1
View File
@@ -12,6 +12,7 @@ const nextConfig: NextConfig = {
}, },
], ],
}, },
} }
export default nextConfig export default nextConfig
+4 -26
View File
@@ -1,30 +1,8 @@
import { NextRequest, NextResponse } from "next/server" 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) { export async function POST(request: NextRequest) {
try { return NextResponse.json({ error: "AI service unavailable on server. Use client-side mode." }, { status: 503 })
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 })
}
} }
+9 -10
View File
@@ -28,7 +28,7 @@ export function AIChat() {
const messagesEndRef = useRef<HTMLDivElement>(null) const messagesEndRef = useRef<HTMLDivElement>(null)
useEffect(() => { useEffect(() => {
fetch("/api/ai/jobs") fetch(`${AI_API}/ai/jobs`)
.then((r) => r.json()) .then((r) => r.json())
.then((data) => { .then((data) => {
if (data.jobs?.length) { if (data.jobs?.length) {
@@ -64,14 +64,13 @@ export function AIChat() {
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }) messagesEndRef.current?.scrollIntoView({ behavior: "smooth" })
}, [messages]) }, [messages])
const AI_API = process.env.NEXT_PUBLIC_AI_URL || "http://127.0.0.1:3001"
const checkOllama = async () => { const checkOllama = async () => {
try { try {
const res = await fetch("/api/ai/chat", { const res = await fetch(`${AI_API}/health`)
method: "POST", const data = await res.json()
headers: { "Content-Type": "application/json" }, setOllamaStatus(data.status === "ok")
body: JSON.stringify({ message: "__ping__" }),
})
setOllamaStatus(res.status !== 503)
} catch { } catch {
setOllamaStatus(false) setOllamaStatus(false)
} }
@@ -89,15 +88,15 @@ export function AIChat() {
setLoading(true) setLoading(true)
try { try {
const res = await fetch("/api/ai/chat", { const res = await fetch(`${AI_API}/ai/chat`, {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message: msg }), body: JSON.stringify({ message: msg }),
}) })
if (!res.ok) { if (!res.ok) {
const data = await res.json() const data = await res.json().catch(() => ({}))
throw new Error(data.error || "Failed to get response") throw new Error(data.error || `Error ${res.status}`)
} }
const data = await res.json() const data = await res.json()
+10 -6
View File
@@ -1,18 +1,22 @@
const AI_SERVICE = process.env.AI_SERVICE_URL || "http://localhost:3001" const AI_SERVICE = process.env.AI_SERVICE_URL || "http://localhost:3001"
export async function chatWithAI(message: string, jwtToken: string) { 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", method: "POST",
headers: { "Content-Type": "application/json", "Authorization": `Bearer ${jwtToken}` }, headers: { "Content-Type": "application/json", Authorization: `Bearer ${jwtToken}` },
body: JSON.stringify({ message }), body,
}) })
if (!res.ok) {
const text = await res.text() 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 || "" return data.response || ""
} }