vue2server7 7.0.96 → 7.0.98

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/11 +160 -1
  2. package/package.json +1 -1
package/11 CHANGED
@@ -1 +1,160 @@
1
- 111
1
+ import express from "express";
2
+ import axios from "axios";
3
+ import cors from "cors";
4
+
5
+ const app = express();
6
+
7
+ app.use(cors());
8
+ app.use(express.json({ limit: "10mb" }));
9
+
10
+ // ===== 你的内网模型网关配置 =====
11
+ const TARGET_URL = "http://maasapp.aip.bj.bob.test8080/apis/ais-v2/chat/completions";
12
+ const TARGET_API_KEY = "你的真实内网API_KEY";
13
+ const TARGET_APP_TAG = "proxyai";
14
+ const DEFAULT_MODEL = "qwen15-32b";
15
+
16
+ // ===== 健康检查 =====
17
+ app.get("/health", (req, res) => {
18
+ res.json({ ok: true });
19
+ });
20
+
21
+ // ===== 可选:给 Continue 用的模型列表接口 =====
22
+ app.get("/v1/models", (req, res) => {
23
+ res.json({
24
+ object: "list",
25
+ data: [
26
+ {
27
+ id: DEFAULT_MODEL,
28
+ object: "model",
29
+ created: Math.floor(Date.now() / 1000),
30
+ owned_by: "local-proxy"
31
+ }
32
+ ]
33
+ });
34
+ });
35
+
36
+ // ===== OpenAI Chat Completions 兼容接口 =====
37
+ app.post("/v1/chat/completions", async (req, res) => {
38
+ try {
39
+ const {
40
+ model,
41
+ messages,
42
+ temperature,
43
+ max_tokens,
44
+ stream
45
+ } = req.body;
46
+
47
+ const finalModel = model || DEFAULT_MODEL;
48
+ const finalStream = !!stream;
49
+
50
+ const requestBody = {
51
+ model: finalModel,
52
+ messages: Array.isArray(messages) ? messages : [],
53
+ temperature: typeof temperature === "number" ? temperature : 0.1,
54
+ max_tokens: typeof max_tokens === "number" ? max_tokens : 20000,
55
+ stream: finalStream
56
+ };
57
+
58
+ // ===== 非流式 =====
59
+ if (!finalStream) {
60
+ const response = await axios.post(TARGET_URL, requestBody, {
61
+ headers: {
62
+ Authorization: `Bearer ${TARGET_API_KEY}`,
63
+ "X-LLM-Application-Tag": TARGET_APP_TAG,
64
+ "Content-Type": "application/json"
65
+ },
66
+ timeout: 120000
67
+ });
68
+
69
+ // 如果你的内网返回已经接近 OpenAI 格式,可直接透传
70
+ // 这里做一层兼容处理,更稳
71
+ const data = response.data;
72
+
73
+ // 兼容:如果对方已经是 OpenAI 格式
74
+ if (data?.choices) {
75
+ return res.json(data);
76
+ }
77
+
78
+ // 兼容:如果对方返回的是别的结构,尝试提取文本
79
+ const text =
80
+ data?.choices?.[0]?.message?.content ??
81
+ data?.data?.content ??
82
+ data?.data?.text ??
83
+ data?.text ??
84
+ data?.reply ??
85
+ "";
86
+
87
+ return res.json({
88
+ id: `chatcmpl-${Date.now()}`,
89
+ object: "chat.completion",
90
+ created: Math.floor(Date.now() / 1000),
91
+ model: finalModel,
92
+ choices: [
93
+ {
94
+ index: 0,
95
+ message: {
96
+ role: "assistant",
97
+ content: text
98
+ },
99
+ finish_reason: "stop"
100
+ }
101
+ ],
102
+ usage: data?.usage || {
103
+ prompt_tokens: 0,
104
+ completion_tokens: 0,
105
+ total_tokens: 0
106
+ }
107
+ });
108
+ }
109
+
110
+ // ===== 流式 =====
111
+ const response = await axios.post(TARGET_URL, requestBody, {
112
+ headers: {
113
+ Authorization: `Bearer ${TARGET_API_KEY}`,
114
+ "X-LLM-Application-Tag": TARGET_APP_TAG,
115
+ "Content-Type": "application/json"
116
+ },
117
+ responseType: "stream",
118
+ timeout: 120000
119
+ });
120
+
121
+ res.setHeader("Content-Type", "text/event-stream; charset=utf-8");
122
+ res.setHeader("Cache-Control", "no-cache, no-transform");
123
+ res.setHeader("Connection", "keep-alive");
124
+
125
+ response.data.on("data", (chunk) => {
126
+ const text = chunk.toString("utf8");
127
+
128
+ // 情况1:你的内网本来就是标准 SSE,直接透传
129
+ // 如果不是标准 SSE,可以在这里做转换
130
+ res.write(text);
131
+ });
132
+
133
+ response.data.on("end", () => {
134
+ res.end();
135
+ });
136
+
137
+ response.data.on("error", (err) => {
138
+ console.error("stream error:", err.message);
139
+ res.end();
140
+ });
141
+ } catch (error) {
142
+ const status = error.response?.status || 500;
143
+ const detail = error.response?.data || error.message;
144
+
145
+ console.error("proxy error:", detail);
146
+
147
+ res.status(status).json({
148
+ error: {
149
+ message: typeof detail === "string" ? detail : JSON.stringify(detail),
150
+ type: "proxy_error",
151
+ code: status
152
+ }
153
+ });
154
+ }
155
+ });
156
+
157
+ const PORT = 3000;
158
+ app.listen(PORT, () => {
159
+ console.log(`Proxy server running at http://127.0.0.1:${PORT}`);
160
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue2server7",
3
- "version": "7.0.96",
3
+ "version": "7.0.98",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "dev": "nodemon --watch src --ext ts --exec \"ts-node src/app.ts\"",