nanoppa commited on
Commit
b751bbe
·
verified ·
1 Parent(s): 9c87bfa

Create main.ts

Browse files
Files changed (1) hide show
  1. main.ts +134 -0
main.ts ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { serve } from "https://deno.land/std@0.192.0/http/server.ts";
2
+
3
+ const CEREBRAS_API_URL = 'https://api.cerebras.ai/v1/chat/completions';
4
+ const RATE_LIMIT_MS = 200;
5
+ const DEFAULT_MODEL = 'qwen-3-235b-a22b-instruct-2507'; // 默认模型
6
+
7
+ const CORS_HEADERS = {
8
+ 'Access-Control-Allow-Origin': '*',
9
+ 'Access-Control-Allow-Methods': 'POST, OPTIONS',
10
+ 'Access-Control-Allow-Headers': 'Content-Type, Authorization',
11
+ };
12
+
13
+ const requestQueue: { body: any; resolve: (response: Response) => void }[] = [];
14
+
15
+ let apiKeys: string[] = [];
16
+ let currentKeyIndex = 0;
17
+ let authPassword: string | null = null;
18
+
19
+ function initializeKeys() {
20
+ const keysString = Deno.env.get("CEREBRAS_API_KEYS");
21
+ if (keysString) {
22
+ apiKeys = keysString.split(',').map(key => key.trim()).filter(key => key);
23
+ console.log(`Initialized with ${apiKeys.length} API keys.`);
24
+ } else {
25
+ console.error("CEREBRAS_API_KEYS environment variable not set!");
26
+ }
27
+
28
+ // 初始化鉴权密码
29
+ authPassword = Deno.env.get("AUTH_PASSWORD");
30
+ if (authPassword) {
31
+ console.log("Authentication enabled.");
32
+ } else {
33
+ console.log("Authentication disabled (no AUTH_PASSWORD set).");
34
+ }
35
+ }
36
+
37
+ function authenticateRequest(request: Request): boolean {
38
+ // 如果没有设置鉴权密码,则跳过验证
39
+ if (!authPassword) {
40
+ return true;
41
+ }
42
+
43
+ const authHeader = request.headers.get("Authorization");
44
+ if (!authHeader || !authHeader.startsWith("Bearer ")) {
45
+ return false;
46
+ }
47
+
48
+ const providedPassword = authHeader.substring(7); // 去掉 "Bearer " 前缀
49
+ return providedPassword === authPassword;
50
+ }
51
+
52
+ async function processQueue() {
53
+ if (requestQueue.length === 0 || apiKeys.length === 0) {
54
+ return;
55
+ }
56
+
57
+ const { body, resolve } = requestQueue.shift()!;
58
+
59
+ const apiKey = apiKeys[currentKeyIndex];
60
+ currentKeyIndex = (currentKeyIndex + 1) % apiKeys.length;
61
+
62
+ console.log(`Processing request with key index: ${currentKeyIndex}`);
63
+
64
+ // 模型默认映射:无论用户传入什么模型名称,都映射到默认模型
65
+ const originalModel = body.model;
66
+ body.model = DEFAULT_MODEL;
67
+ console.log(`Model mapping: "${originalModel}" -> "${DEFAULT_MODEL}"`);
68
+
69
+ try {
70
+ const apiResponse = await fetch(CEREBRAS_API_URL, {
71
+ method: 'POST',
72
+ headers: {
73
+ 'Content-Type': 'application/json',
74
+ 'Authorization': `Bearer ${apiKey}`,
75
+ },
76
+ body: JSON.stringify(body),
77
+ });
78
+
79
+ const responseHeaders = new Headers(apiResponse.headers);
80
+ Object.entries(CORS_HEADERS).forEach(([key, value]) => {
81
+ responseHeaders.set(key, value);
82
+ });
83
+
84
+ resolve(new Response(apiResponse.body, {
85
+ status: apiResponse.status,
86
+ statusText: apiResponse.statusText,
87
+ headers: responseHeaders,
88
+ }));
89
+
90
+ } catch (error) {
91
+ console.error("Error forwarding request to Cerebras:", error);
92
+ resolve(new Response(`Proxy error: ${error.message}`, { status: 502, headers: CORS_HEADERS }));
93
+ }
94
+ }
95
+
96
+ async function handler(req: Request): Promise<Response> {
97
+ if (req.method === 'OPTIONS') {
98
+ return new Response(null, { status: 204, headers: CORS_HEADERS });
99
+ }
100
+
101
+ if (req.method !== 'POST') {
102
+ return new Response("Method Not Allowed", { status: 405, headers: CORS_HEADERS });
103
+ }
104
+
105
+ // 鉴权检查
106
+ if (!authenticateRequest(req)) {
107
+ return new Response("Unauthorized", { status: 401, headers: CORS_HEADERS });
108
+ }
109
+
110
+ if (apiKeys.length === 0) {
111
+ return new Response("Server configuration error: No API keys configured.", { status: 500, headers: CORS_HEADERS });
112
+ }
113
+
114
+ try {
115
+ const requestBody = await req.json();
116
+
117
+ return new Promise((resolve) => {
118
+ requestQueue.push({ body: requestBody, resolve });
119
+ });
120
+
121
+ } catch (error) {
122
+ return new Response(`Invalid JSON body: ${error.message}`, { status: 400, headers: CORS_HEADERS });
123
+ }
124
+ }
125
+
126
+ initializeKeys();
127
+ serve(handler,{port:7860});
128
+ setInterval(processQueue, RATE_LIMIT_MS);
129
+
130
+ console.log(`Cerebras smart proxy with auth & auto model rotation started.`);
131
+ console.log(`- Default model: ${DEFAULT_MODEL}`);
132
+ console.log(`- Authentication: ${authPassword ? 'Enabled' : 'Disabled'}`);
133
+ console.log(`- Request processing interval: ${RATE_LIMIT_MS}ms`);
134
+ console.log(`- Max requests per second (approx): ${1000 / RATE_LIMIT_MS}`);