| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| const ALLOWED_ORIGINS = [ |
| "https://nph4rd-eleusis.static.hf.space", |
| "http://localhost:7861", |
| ]; |
|
|
| const MODEL = "mistralai/mistral-small-3.2-24b-instruct"; |
|
|
| const SYSTEM = `You translate natural-language card-game rules into a single Python predicate. |
| Available: card.rank (int, A=1,J=11,Q=12,K=13), card.suit ('hearts','diamonds','clubs','spades'), |
| card.color ('red','black'), card.is_face (rank 11-13), mainline (list of already-accepted cards, oldest to newest; may be empty). |
| Relational rules compare card to mainline[-1] and must be guarded: not mainline or <condition>. |
| Reply with ONLY the predicate expression, no backticks, no explanation.`; |
|
|
| function cors(origin) { |
| const allowed = ALLOWED_ORIGINS.includes(origin) ? origin : ALLOWED_ORIGINS[0]; |
| return { |
| "Access-Control-Allow-Origin": allowed, |
| "Access-Control-Allow-Methods": "POST, OPTIONS", |
| "Access-Control-Allow-Headers": "content-type", |
| "Content-Type": "application/json", |
| }; |
| } |
|
|
| export default { |
| async fetch(request, env) { |
| const origin = request.headers.get("Origin") || ""; |
| const headers = cors(origin); |
|
|
| if (request.method === "OPTIONS") return new Response(null, { headers }); |
| if (request.method !== "POST") |
| return new Response(JSON.stringify({ error: "POST only" }), { status: 405, headers }); |
|
|
| let text; |
| try { |
| ({ text } = await request.json()); |
| } catch { |
| return new Response(JSON.stringify({ error: "bad json" }), { status: 400, headers }); |
| } |
| if (typeof text !== "string" || !text.trim() || text.length > 300) |
| return new Response(JSON.stringify({ error: "text must be 1-300 chars" }), { status: 400, headers }); |
|
|
| const upstream = await fetch("https://api.pinference.ai/api/v1/chat/completions", { |
| method: "POST", |
| headers: { |
| Authorization: `Bearer ${env.PRIME_API_KEY}`, |
| "Content-Type": "application/json", |
| }, |
| body: JSON.stringify({ |
| model: MODEL, |
| max_tokens: 120, |
| temperature: 0, |
| messages: [ |
| { role: "system", content: SYSTEM }, |
| { role: "user", content: text.trim() }, |
| ], |
| }), |
| }); |
|
|
| if (!upstream.ok) { |
| return new Response( |
| JSON.stringify({ error: `upstream ${upstream.status}` }), |
| { status: 502, headers } |
| ); |
| } |
| const data = await upstream.json(); |
| let out = (data.choices?.[0]?.message?.content || "").trim(); |
| |
| out = out.replace(/^```(python)?|```$/g, "").trim(); |
| const lam = out.match(/^\(?\s*lambda\s+[^:]*:\s*([\s\S]*?)\)?\s*$/); |
| if (lam) out = lam[1].trim(); |
|
|
| return new Response(JSON.stringify({ predicate: out }), { headers }); |
| }, |
| }; |
|
|