1import Anthropic from "@anthropic-ai/sdk";
2
3export default {
4 async fetch(request, env): Promise<Response> {
5 const { question } = await request.json<{ question?: unknown }>();
6 if (typeof question !== "string" || question.length > 2000) {
7 return new Response("question must be a string under 2,000 characters", { status: 400 });
8 }
9 const client = new Anthropic({ apiKey: env.ANTHROPIC_API_KEY });
10 const stream = client.messages.stream({
11 model: "claude-haiku-5-5",
12 max_tokens: 1024,
13 output_config: { effort: "low" },
14 messages: [{ role: "user", content: question }],
15 });
16
17 const encoder = new TextEncoder();
18 const body = new ReadableStream({
19 async start(controller) {
20 try {
21 for await (const event of stream) {
22 if (event.type === "content_block_delta" && event.delta.type === "text_delta") {
23 controller.enqueue(encoder.encode(event.delta.text));
24 }
25 }
26 controller.close();
27 } catch (error) {
28 controller.error(error);
29 }
30 },
31 cancel() {
32 stream.abort(); // the reader left: stop paying for tokens nobody reads
33 },
34 });
35
36 return new Response(body, { headers: { "content-type": "text/plain; charset=utf-8" } });
37 },
38} satisfies ExportedHandler<Env>;