예제 소스
SGF 기보로 학습하는 바둑 LLM 인공지능 · 파일 169개
route.ts
import { NextRequest, NextResponse } from "next/server";
import { spawn } from "node:child_process";
import path from "node:path";
import type { MoveRec } from "@/lib/gameTypes";
export const runtime = "nodejs";
export const maxDuration = 60;
type Body = {
moves?: MoveRec[];
komi?: number;
maxVisits?: number;
};
function pyBin(): string {
const venv = path.join(process.cwd(), "..", ".venv", "bin", "python");
return venv;
}
export async function POST(req: NextRequest) {
const body = (await req.json().catch(() => null)) as Body | null;
if (!body || !Array.isArray(body.moves)) {
return NextResponse.json({ error: "moves required" }, { status: 400 });
}
const script = path.join(process.cwd(), "..", "scripts", "katago_analyze.py");
const payload = JSON.stringify({
moves: body.moves,
komi: body.komi ?? 6.5,
maxVisits: body.maxVisits ?? 80,
});
return new Promise<Response>((resolve) => {
const proc = spawn(pyBin(), [script], {
cwd: path.join(process.cwd(), ".."),
stdio: ["pipe", "pipe", "pipe"],
});
let out = "";
let err = "";
proc.stdout.on("data", (d) => {
out += String(d);
});
proc.stderr.on("data", (d) => {
err += String(d);
});
const timer = setTimeout(() => {
proc.kill("SIGTERM");
resolve(
NextResponse.json({ error: "KataGo 분석 시간 초과" }, { status: 504 }),
);
}, 55_000);
proc.on("close", (code) => {
clearTimeout(timer);
if (code !== 0) {
resolve(
NextResponse.json(
{
error: "KataGo 분석 실패",
detail: err.slice(-800) || `exit ${code}`,
},
{ status: 502 },
),
);
return;
}
try {
const line = out.trim().split("\n").filter(Boolean).pop() || "{}";
const data = JSON.parse(line) as Record<string, unknown>;
resolve(NextResponse.json(data));
} catch (e) {
resolve(
NextResponse.json(
{ error: "분석 결과 파싱 실패", detail: String(e), raw: out.slice(-500) },
{ status: 502 },
),
);
}
});
proc.stdin.write(payload);
proc.stdin.end();
});
}