cf-ai-endpoint/dev/cf-WorkerAI_example.js
2025-03-04 13:09:40 +08:00

134 lines
4.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

export default {
async fetch(request, env) {
if (request.method === "POST" && request.url.includes("v1/chat/completions")) {
// todo 验证 key
try {
const requestData = await request.json();
const { model, messages } = requestData;
let isSteam = false;
if (requestData?.stream) {
isSteam = true;
}
// get the current time in epoch seconds
const created = Math.floor(Date.now() / 1000);
const uuid = crypto.randomUUID();
const stream = await env.AI.run("@cf/deepseek-ai/deepseek-r1-distill-qwen-32b", {
messages: messages,
stream: isSteam,
});
if (isSteam) {
// 创建一个转换流 (TransformStream) 以便实现流式返回
const { readable, writable } = new TransformStream();
const writer = writable.getWriter();
const reader = stream.getReader();
// 处理流读取数据并逐帧向客户端发送
async function processStream() {
const decoder = new TextDecoder();
const encoder = new TextEncoder();
try {
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
// 确保 value 被转换为字符串类型
const stringValue = decoder.decode(value);
// 处理每行数据
const lines = stringValue.split("\n").filter((line) => !!line);
for (const line of lines) {
// 跳过非 JSON 数据(例如 [DONE]
if (line.endsWith("data: [DONE]")) {
continue;
}
try {
const json = JSON.parse(line.replace(/^data: /, ""));
const formattedValue = `data: ${JSON.stringify({
id: uuid,
created,
object: "chat.completion.chunk",
model,
choices: [
{
delta: { content: json.response },
index: 0,
finish_reason: null,
},
],
})}\n\n`;
const encodedValue = encoder.encode(formattedValue);
await writer.write(encodedValue);
} catch (e) {
console.error("Failed to parse JSON: ", e);
}
}
}
// 发送完成标识
await writer.write(encoder.encode("data: [DONE]\n\n"));
writer.close();
} catch (err) {
console.error("Stream processing error: ", err);
// 确保 writer 在错误情况下关闭
writer.close();
}
}
// 调用处理流函数
processStream().catch((err) => {
console.error("Stream processing error: ", err);
});
return new Response(readable, {
headers: {
"content-type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive",
},
});
} else {
return Response.json({
id: uuid,
model,
created,
object: "chat.completion",
choices: [
{
index: 0,
message: {
role: "assistant",
content: stream.response,
},
finish_reason: "stop",
},
],
usage: {
prompt_tokens: 0,
completion_tokens: 0,
total_tokens: 0,
},
});
}
} catch (error) {
return new Response(JSON.stringify({ error: "Invalid request" }), {
status: 400,
headers: { "Content-Type": "application/json" },
});
}
}
return new Response("Not Found", { status: 404 });
},
};