main
js 71 lines 1.93 KB
Raw
1 exports.handler = async function handler(event) {
2 if (event.httpMethod === "OPTIONS") {
3 return { statusCode: 204, headers: cors(), body: "" };
4 }
5 if (event.httpMethod !== "POST") {
6 return json(405, { error: "Method not allowed" });
7 }
8
9 const key = process.env.ANTHROPIC_API_KEY;
10 if (!key) {
11 return json(503, {
12 error: "ANTHROPIC_API_KEY is not set on this Netlify site.",
13 hint: "Site settings → Environment variables → ANTHROPIC_API_KEY, then redeploy."
14 });
15 }
16
17 let body;
18 try {
19 body = JSON.parse(event.body || "{}");
20 } catch {
21 return json(400, { error: "Invalid JSON body" });
22 }
23
24 const messages = Array.isArray(body.messages) ? body.messages.slice(-12) : [];
25 const system = typeof body.system === "string" ? body.system.slice(0, 4000) : "You are a precise technical assistant.";
26
27 try {
28 const response = await fetch("https://api.anthropic.com/v1/messages", {
29 method: "POST",
30 headers: {
31 "content-type": "application/json",
32 "x-api-key": key,
33 "anthropic-version": "2023-06-01"
34 },
35 body: JSON.stringify({
36 model: "claude-sonnet-4-20250514",
37 max_tokens: 1200,
38 system,
39 messages
40 })
41 });
42
43 const text = await response.text();
44 if (!response.ok) {
45 return json(response.status, { error: "Anthropic request failed", detail: text.slice(0, 800) });
46 }
47 return {
48 statusCode: 200,
49 headers: { ...cors(), "content-type": "application/json" },
50 body: text
51 };
52 } catch (error) {
53 return json(502, { error: error.message || "Proxy failed" });
54 }
55 };
56
57 function cors() {
58 return {
59 "access-control-allow-origin": "*",
60 "access-control-allow-headers": "content-type",
61 "access-control-allow-methods": "POST, OPTIONS"
62 };
63 }
64
65 function json(statusCode, payload) {
66 return {
67 statusCode,
68 headers: { ...cors(), "content-type": "application/json" },
69 body: JSON.stringify(payload)
70 };
71 }