sfun commited on
Commit
33668ef
·
verified ·
1 Parent(s): 7a6f43b

Create server.js

Browse files
Files changed (1) hide show
  1. server.js +150 -0
server.js ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import Koa from "koa";
2
+ import Router from "@koa/router";
3
+ import compose from "koa-compose";
4
+ import { koaBody } from "koa-body";
5
+ import {
6
+ handleTimeStap,
7
+ handleBase64,
8
+ handleNewSession,
9
+ handleErrors,
10
+ initParams,
11
+ } from "./handles.js";
12
+ import https from "https";
13
+ import { createParser } from "eventsource-parser";
14
+ const app = new Koa();
15
+ const router = new Router();
16
+ const params = {};
17
+ const break_message = {
18
+ answer_message_id: null,
19
+ query_message_id: null,
20
+ scene: params.scene,
21
+ broken_pos: 0,
22
+ conversation_id: params.conversation_id,
23
+ local_message_id: params.local_message_id,
24
+ };
25
+
26
+ const createNewSession = async (ctx, next) => {
27
+ const { messages } = ctx.request.body;
28
+ const sessionid = ctx.req.headers.authorization.split(" ")[1];
29
+ if (
30
+ messages[0].role === "system" &&
31
+ messages.length === 2 &&
32
+ break_message.answer_message_id !== null &&
33
+ break_message.query_message_id !== null
34
+ ) {
35
+ console.log("new session");
36
+ await handleNewSession(break_message, sessionid);
37
+ params.conversation_id =
38
+ "7337495393033765890_7337496580645339154_2_" + handleTimeStap();
39
+ params.local_message_id = handleBase64();
40
+ }
41
+ await next();
42
+ };
43
+
44
+ // 事件源路由
45
+ router.post("/api/v1/chat/completions", async (ctx) => {
46
+ ctx.respond = false;
47
+ ctx.type = "text/event-stream";
48
+ ctx.status = 200;
49
+ // 初始化响应头 sse
50
+ ctx.set({
51
+ "Cache-Control": "no-cache",
52
+ Connection: "keep-alive",
53
+ "Content-Encoding": "none",
54
+ });
55
+ // 获取 post 请求的 body
56
+ const { messages, model } = ctx.request.body;
57
+ const sessionid = ctx.req.headers.authorization.split(" ")[1];
58
+ // 返回的数据
59
+ const sseData = {
60
+ id: null,
61
+ object: "chat.completion.chunk",
62
+ created: handleTimeStap(),
63
+ model: model,
64
+ system_fingerprint: null,
65
+ choices: [
66
+ {
67
+ index: 0,
68
+ delta: { content: null },
69
+ logprobs: null,
70
+ finish_reason: null,
71
+ },
72
+ ],
73
+ };
74
+ // 远程服务器配置
75
+ const options = {
76
+ hostname: "www.coze.com",
77
+ path: "/api/conversation/chat",
78
+ port: 443,
79
+ method: "POST",
80
+ headers: {
81
+ "Content-Type": "application/json",
82
+ Cookie: `sessionid=${sessionid}`,
83
+ "User-Agent":
84
+ "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",
85
+ },
86
+ };
87
+ params.query = messages[messages.length - 1].content;
88
+ const sse = https.request(options);
89
+
90
+ sse.on("response", async (res) => {
91
+ const parser = createParser((event) => {
92
+ if (event.event === "message") {
93
+ const data = JSON.parse(event.data);
94
+ if (data.message.type === "answer") {
95
+ sseData.id = data.conversation_id;
96
+ sseData.choices[0].delta.content = data.message.content;
97
+ if (data.is_finish) {
98
+ sseData.choices[0].finish_reason = "stop";
99
+ } else {
100
+ sseData.choices[0].finish_reason = null;
101
+ }
102
+ ctx.res.write(`data:${JSON.stringify(sseData)}\n\n`);
103
+ if (data.is_finish) {
104
+ break_message.answer_message_id = data.message.reply_id;
105
+ break_message.query_message_id = data.message.message_id;
106
+ break_message.broken_pos = parseInt(
107
+ data.message.extra_info.output_tokens
108
+ );
109
+ ctx.res.end();
110
+ }
111
+ }
112
+ }
113
+ });
114
+ res.setEncoding("utf8");
115
+ res.on("data", (d) => {
116
+ parser.feed(d);
117
+ });
118
+ res.on("end", () => {
119
+ console.log("response end", new Date().toLocaleString());
120
+ });
121
+ });
122
+ sse.on("error", async (e) => {
123
+ console.error(`problem with request: ${e.message}`);
124
+ });
125
+ sse.on("close", async () => {
126
+ console.log("sse closed", new Date().toLocaleString());
127
+ });
128
+
129
+ sse.write(JSON.stringify(params));
130
+ sse.end();
131
+ ctx.respond = false;
132
+ });
133
+
134
+ // 组合中间件
135
+ const all = compose([
136
+ handleErrors,
137
+ koaBody(),
138
+ createNewSession,
139
+ router.routes(),
140
+ router.allowedMethods(),
141
+ ]);
142
+
143
+ // 注册中间件
144
+ app.use(all);
145
+
146
+ // 启动Koa应用
147
+ app.listen(3000, () => {
148
+ console.log("Server started on port 3000");
149
+ initParams(params);
150
+ });