import { OpenAI } from "https://esm.town/v/std/openai";
const openai = new OpenAI();
export default async function(req: Request): Promise<Response> {
log.info("Request received:", req.method, req.url);
try {
if (req.method === "OPTIONS") {
return handleCorsPreflightRequest();
}
const selection = await parseRequest(req);
log.info("Parsed selection:", selection);
const messages = prepareMessages(selection);
log.info("Prepared messages for OpenAI");
const openai = new OpenAI();
const stream = await openai.chat.completions.create({
messages,
model: config.MODEL_NAME,
max_tokens: config.MAX_TOKENS,
temperature: config.TEMPERATURE,
stream: true,
});
return streamResponse(stream);
} catch (error) {
return handleError(error);
}
}
export async function parseRequest(req: Request): Promise<string> {
const body = await req.text();
log.debug("Request body:", body);
const parsedBody = JSON.parse(body);
const selection = parsedBody.selection;
if (!selection || selection.trim() === "") {
throw new Error("Empty or invalid 'selection' in request body");
}
return selection;
}
export function prepareMessages(selection: string): Array<Object> {
return [
{
role: "system",
content:
`${config.SYSTEM_MESSAGE} When encountering HTML img tags with class "smilie", interpret them as emojis and include their meaning in your response.`,
},
{
role: "user",
content:
`Define in detail: "${selection}". Consider forum context if relevant, including any emojis represented by img tags.`,
},
];
}
export function streamResponse(stream: ReadableStream): Response {
const encoder = new TextEncoder();
const readableStream = new ReadableStream({
async start(controller) {
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content || "";
if (content) {
const encodedChunk = encoder.encode(JSON.stringify({ chunk: content }) + "\n");
controller.enqueue(encodedChunk);
}
}
controller.close();
},
});
return new Response(readableStream, {
headers: {
"Content-Type": "application/json; charset=utf-8",
"Access-Control-Allow-Origin": "*",
"Transfer-Encoding": "chunked",
},
});
}
export function handleError(error: Error): Response {
log.error("Error occurred:", error);
const errorMessage = "An error occurred while processing your request. Please try again.";
const errorResponse = JSON.stringify({ error: errorMessage });
return new Response(errorResponse, {
status: 500,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",