Spaces:
Sleeping
Sleeping
import Koa from "koa"; | |
import Router from "@koa/router"; | |
import compose from "koa-compose"; | |
import { koaBody } from "koa-body"; | |
import { | |
handleTimeStap, | |
handleBase64, | |
handleNewSession, | |
handleErrors, | |
initParams, | |
} from "./handles.js"; | |
import https from "https"; | |
import { createParser } from "eventsource-parser"; | |
const app = new Koa(); | |
const router = new Router(); | |
const params = {}; | |
const break_message = { | |
answer_message_id: null, | |
query_message_id: null, | |
scene: params.scene, | |
broken_pos: 0, | |
conversation_id: params.conversation_id, | |
local_message_id: params.local_message_id, | |
}; | |
const createNewSession = async (ctx, next) => { | |
const { messages } = ctx.request.body; | |
const sessionid = ctx.req.headers.authorization.split(" ")[1]; | |
if ( | |
messages[0].role === "system" && | |
messages.length === 2 && | |
break_message.answer_message_id !== null && | |
break_message.query_message_id !== null | |
) { | |
console.log("new session"); | |
await handleNewSession(break_message, sessionid); | |
params.conversation_id = | |
"7337495393033765890_7337496580645339154_2_" + handleTimeStap(); | |
params.local_message_id = handleBase64(); | |
} | |
await next(); | |
}; | |
// 事件源路由 | |
router.post("/api/v1/chat/completions", async (ctx) => { | |
ctx.respond = false; | |
ctx.type = "text/event-stream"; | |
ctx.status = 200; | |
// 初始化响应头 sse | |
ctx.set({ | |
"Cache-Control": "no-cache", | |
Connection: "keep-alive", | |
"Content-Encoding": "none", | |
}); | |
// 获取 post 请求的 body | |
const { messages, model } = ctx.request.body; | |
const sessionid = ctx.req.headers.authorization.split(" ")[1]; | |
// 返回的数据 | |
const sseData = { | |
id: null, | |
object: "chat.completion.chunk", | |
created: handleTimeStap(), | |
model: model, | |
system_fingerprint: null, | |
choices: [ | |
{ | |
index: 0, | |
delta: { content: null }, | |
logprobs: null, | |
finish_reason: null, | |
}, | |
], | |
}; | |
// 远程服务器配置 | |
const options = { | |
hostname: "www.coze.com", | |
path: "/api/conversation/chat", | |
port: 443, | |
method: "POST", | |
headers: { | |
"Content-Type": "application/json", | |
Cookie: `sessionid=${sessionid}`, | |
"User-Agent": | |
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", | |
}, | |
}; | |
params.query = messages[messages.length - 1].content; | |
const sse = https.request(options); | |
sse.on("response", async (res) => { | |
const parser = createParser((event) => { | |
if (event.event === "message") { | |
const data = JSON.parse(event.data); | |
if (data.message.type === "answer") { | |
sseData.id = data.conversation_id; | |
sseData.choices[0].delta.content = data.message.content; | |
if (data.is_finish) { | |
sseData.choices[0].finish_reason = "stop"; | |
} else { | |
sseData.choices[0].finish_reason = null; | |
} | |
ctx.res.write(`data:${JSON.stringify(sseData)}\n\n`); | |
if (data.is_finish) { | |
break_message.answer_message_id = data.message.reply_id; | |
break_message.query_message_id = data.message.message_id; | |
break_message.broken_pos = parseInt( | |
data.message.extra_info.output_tokens | |
); | |
ctx.res.end(); | |
} | |
} | |
} | |
}); | |
res.setEncoding("utf8"); | |
res.on("data", (d) => { | |
parser.feed(d); | |
}); | |
res.on("end", () => { | |
console.log("response end", new Date().toLocaleString()); | |
}); | |
}); | |
sse.on("error", async (e) => { | |
console.error(`problem with request: ${e.message}`); | |
}); | |
sse.on("close", async () => { | |
console.log("sse closed", new Date().toLocaleString()); | |
}); | |
sse.write(JSON.stringify(params)); | |
sse.end(); | |
ctx.respond = false; | |
}); | |
// 组合中间件 | |
const all = compose([ | |
handleErrors, | |
koaBody(), | |
createNewSession, | |
router.routes(), | |
router.allowedMethods(), | |
]); | |
// 注册中间件 | |
app.use(all); | |
// 启动Koa应用 | |
app.listen(3000, () => { | |
console.log("Server started on port 3000"); | |
initParams(params); | |
}); |