update available models
This commit is contained in:
@@ -1,40 +1,42 @@
|
|||||||
import express from "express";
|
import express from "express";
|
||||||
import { createEvent, getGitRevision } from "./utils.mjs";
|
import {createEvent, getGitRevision} from "./utils.mjs";
|
||||||
import YouProvider from "./provider.mjs";
|
import YouProvider from "./provider.mjs";
|
||||||
import localtunnel from "localtunnel";
|
import localtunnel from "localtunnel";
|
||||||
import ngrok from 'ngrok';
|
import ngrok from 'ngrok';
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import {v4 as uuidv4} from "uuid";
|
||||||
import './proxyAgent.mjs';
|
import './proxyAgent.mjs';
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
const port = process.env.PORT || 8080;
|
const port = process.env.PORT || 8080;
|
||||||
const validApiKey = process.env.PASSWORD;
|
const validApiKey = process.env.PASSWORD;
|
||||||
const availableModels = [
|
const availableModels = [
|
||||||
"gpt_4o",
|
"gpt_4o",
|
||||||
"gpt_4_turbo",
|
"gpt_4_turbo",
|
||||||
"gpt_4",
|
"gpt_4",
|
||||||
"claude_3_5_sonnet",
|
"claude_3_5_sonnet",
|
||||||
"claude_3_opus",
|
"claude_3_opus",
|
||||||
"claude_3_sonnet",
|
"claude_3_sonnet",
|
||||||
"claude_3_haiku",
|
"claude_3_haiku",
|
||||||
"claude_2",
|
"claude_2",
|
||||||
"llama3",
|
"llama3",
|
||||||
"gemini_pro",
|
"gemini_pro",
|
||||||
"gemini_1_5_pro",
|
"gemini_1_5_pro",
|
||||||
"databricks_dbrx_instruct",
|
"gemini_1_5_flash",
|
||||||
"command_r",
|
"databricks_dbrx_instruct",
|
||||||
"command_r_plus",
|
"command_r",
|
||||||
"zephyr",
|
"command_r_plus",
|
||||||
|
"zephyr",
|
||||||
];
|
];
|
||||||
const modelMappping = {
|
const modelMappping = {
|
||||||
"claude-3-5-sonnet-20240620": "claude_3_5_sonnet",
|
"claude-3-5-sonnet-20240620": "claude_3_5_sonnet",
|
||||||
"claude-3-20240229": "claude_3_opus",
|
"claude-3-20240229": "claude_3_opus",
|
||||||
"claude-3-sonnet-20240229": "claude_3_sonnet",
|
"claude-3-sonnet-20240229": "claude_3_sonnet",
|
||||||
"claude-3-haiku-20240307": "claude_3_haiku",
|
"claude-3-haiku-20240307": "claude_3_haiku",
|
||||||
"claude-2.1": "claude_2",
|
"claude-2.1": "claude_2",
|
||||||
"claude-2.0": "claude_2",
|
"claude-2.0": "claude_2",
|
||||||
"gpt-4": "gpt_4",
|
"gpt-4": "gpt_4",
|
||||||
"gpt-4o": "gpt_4o",
|
"gpt-4o": "gpt_4o",
|
||||||
"gpt-4-turbo": "gpt_4_turbo",
|
"gpt-4-turbo": "gpt_4_turbo",
|
||||||
};
|
};
|
||||||
|
|
||||||
// import config.mjs
|
// import config.mjs
|
||||||
@@ -77,375 +79,384 @@ app.get("/v1/models", OpenAIApiKeyAuth, (req, res) => {
|
|||||||
name: model,
|
name: model,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
res.json({ object: "list", data: models });
|
res.json({object: "list", data: models});
|
||||||
});
|
});
|
||||||
// handle openai format model request
|
// handle openai format model request
|
||||||
app.post("/v1/chat/completions", OpenAIApiKeyAuth, (req, res) => {
|
app.post("/v1/chat/completions", OpenAIApiKeyAuth, (req, res) => {
|
||||||
req.rawBody = "";
|
req.rawBody = "";
|
||||||
req.setEncoding("utf8");
|
req.setEncoding("utf8");
|
||||||
|
|
||||||
req.on("data", function (chunk) {
|
req.on("data", function (chunk) {
|
||||||
req.rawBody += chunk;
|
req.rawBody += chunk;
|
||||||
});
|
});
|
||||||
|
|
||||||
req.on("end", async () => {
|
req.on("end", async () => {
|
||||||
console.log("Handling request of OpenAI format");
|
console.log("Handling request of OpenAI format");
|
||||||
res.setHeader("Content-Type", "text/event-stream;charset=utf-8");
|
res.setHeader("Content-Type", "text/event-stream;charset=utf-8");
|
||||||
res.setHeader("Access-Control-Allow-Origin", "*");
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||||
let jsonBody = JSON.parse(req.rawBody);
|
let jsonBody = JSON.parse(req.rawBody);
|
||||||
|
|
||||||
console.log("message length:" + jsonBody.messages.length);
|
console.log("message length:" + jsonBody.messages.length);
|
||||||
// decide which session to use randomly
|
// decide which session to use randomly
|
||||||
let randomSession = Object.keys(provider.sessions)[Math.floor(Math.random() * Object.keys(provider.sessions).length)];
|
let randomSession = Object.keys(provider.sessions)[Math.floor(Math.random() * Object.keys(provider.sessions).length)];
|
||||||
console.log("Using session " + randomSession);
|
console.log("Using session " + randomSession);
|
||||||
// call provider to get completion
|
// call provider to get completion
|
||||||
|
|
||||||
// try to map model
|
// try to map model
|
||||||
if (jsonBody.model && modelMappping[jsonBody.model]) {
|
if (jsonBody.model && modelMappping[jsonBody.model]) {
|
||||||
jsonBody.model = modelMappping[jsonBody.model];
|
jsonBody.model = modelMappping[jsonBody.model];
|
||||||
}
|
}
|
||||||
if (jsonBody.model && !availableModels.includes(jsonBody.model)) {
|
if (jsonBody.model && !availableModels.includes(jsonBody.model)) {
|
||||||
res.json({ error: { code: 404, message: "Invalid Model" } });
|
res.json({error: {code: 404, message: "Invalid Model"}});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("Using model " + jsonBody.model);
|
console.log("Using model " + jsonBody.model);
|
||||||
|
|
||||||
// call provider to get completion
|
// call provider to get completion
|
||||||
await provider
|
await provider
|
||||||
.getCompletion(
|
.getCompletion(
|
||||||
{
|
{
|
||||||
username: randomSession,
|
username: randomSession,
|
||||||
messages: jsonBody.messages,
|
messages: jsonBody.messages,
|
||||||
stream: !!jsonBody.stream,
|
stream: !!jsonBody.stream,
|
||||||
proxyModel: jsonBody.model,
|
proxyModel: jsonBody.model,
|
||||||
useCustomMode: process.env.USE_CUSTOM_MODE === "true"
|
useCustomMode: process.env.USE_CUSTOM_MODE === "true"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.then(({ completion, cancel }) => {
|
.then(({completion, cancel}) => {
|
||||||
completion.on("start", (id) => {
|
completion.on("start", (id) => {
|
||||||
if (jsonBody.stream) {
|
if (jsonBody.stream) {
|
||||||
// send message start
|
// send message start
|
||||||
res.write(createEvent(":", "queue heartbeat 114514"));
|
res.write(createEvent(":", "queue heartbeat 114514"));
|
||||||
res.write(
|
res.write(
|
||||||
createEvent("data", {
|
createEvent("data", {
|
||||||
id: msgid,
|
id: msgid,
|
||||||
object: "chat.completion.chunk",
|
object: "chat.completion.chunk",
|
||||||
created: Math.floor(new Date().getTime() / 1000),
|
created: Math.floor(new Date().getTime() / 1000),
|
||||||
model: jsonBody.model,
|
model: jsonBody.model,
|
||||||
system_fingerprint: "114514",
|
system_fingerprint: "114514",
|
||||||
choices: [{ index: 0, delta: { role: "assistant", content: "" }, logprobs: null, finish_reason: null }],
|
choices: [{
|
||||||
})
|
index: 0,
|
||||||
);
|
delta: {role: "assistant", content: ""},
|
||||||
}
|
logprobs: null,
|
||||||
});
|
finish_reason: null
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
completion.on("completion", (id, text) => {
|
completion.on("completion", (id, text) => {
|
||||||
if (jsonBody.stream) {
|
if (jsonBody.stream) {
|
||||||
// send message delta
|
// send message delta
|
||||||
res.write(
|
res.write(
|
||||||
createEvent("data", {
|
createEvent("data", {
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
content_filter_results: {
|
content_filter_results: {
|
||||||
hate: { filtered: false, severity: "safe" },
|
hate: {filtered: false, severity: "safe"},
|
||||||
self_harm: { filtered: false, severity: "safe" },
|
self_harm: {filtered: false, severity: "safe"},
|
||||||
sexual: { filtered: false, severity: "safe" },
|
sexual: {filtered: false, severity: "safe"},
|
||||||
violence: { filtered: false, severity: "safe" },
|
violence: {filtered: false, severity: "safe"},
|
||||||
},
|
},
|
||||||
delta: { content: text },
|
delta: {content: text},
|
||||||
finish_reason: null,
|
finish_reason: null,
|
||||||
index: 0,
|
index: 0,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
created: Math.floor(new Date().getTime() / 1000),
|
created: Math.floor(new Date().getTime() / 1000),
|
||||||
id: id,
|
id: id,
|
||||||
model: jsonBody.model,
|
model: jsonBody.model,
|
||||||
object: "chat.completion.chunk",
|
object: "chat.completion.chunk",
|
||||||
system_fingerprint: "114514",
|
system_fingerprint: "114514",
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// 只会发一次,发送final response
|
// 只会发一次,发送final response
|
||||||
res.write(
|
res.write(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
id: id,
|
id: id,
|
||||||
object: "chat.completion",
|
object: "chat.completion",
|
||||||
created: Math.floor(new Date().getTime() / 1000),
|
created: Math.floor(new Date().getTime() / 1000),
|
||||||
model: jsonBody.model,
|
model: jsonBody.model,
|
||||||
system_fingerprint: "114514",
|
system_fingerprint: "114514",
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
index: 0,
|
index: 0,
|
||||||
message: {
|
message: {
|
||||||
role: "assistant",
|
role: "assistant",
|
||||||
content: text,
|
content: text,
|
||||||
},
|
},
|
||||||
logprobs: null,
|
logprobs: null,
|
||||||
finish_reason: "stop",
|
finish_reason: "stop",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
usage: {
|
usage: {
|
||||||
prompt_tokens: 1,
|
prompt_tokens: 1,
|
||||||
completion_tokens: 1,
|
completion_tokens: 1,
|
||||||
total_tokens: 1,
|
total_tokens: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
res.end();
|
res.end();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
completion.on("end", () => {
|
completion.on("end", () => {
|
||||||
if (jsonBody.stream) {
|
if (jsonBody.stream) {
|
||||||
res.write(createEvent("data", "[DONE]"));
|
res.write(createEvent("data", "[DONE]"));
|
||||||
res.end();
|
res.end();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
res.on("close", () => {
|
res.on("close", () => {
|
||||||
console.log(" > [Client closed]");
|
console.log(" > [Client closed]");
|
||||||
completion.removeAllListeners();
|
completion.removeAllListeners();
|
||||||
cancel();
|
cancel();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
if (jsonBody.stream) {
|
if (jsonBody.stream) {
|
||||||
res.write(
|
res.write(
|
||||||
createEvent("data", {
|
createEvent("data", {
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
content_filter_results: {
|
content_filter_results: {
|
||||||
hate: { filtered: false, severity: "safe" },
|
hate: {filtered: false, severity: "safe"},
|
||||||
self_harm: { filtered: false, severity: "safe" },
|
self_harm: {filtered: false, severity: "safe"},
|
||||||
sexual: { filtered: false, severity: "safe" },
|
sexual: {filtered: false, severity: "safe"},
|
||||||
violence: { filtered: false, severity: "safe" },
|
violence: {filtered: false, severity: "safe"},
|
||||||
},
|
},
|
||||||
delta: {
|
delta: {
|
||||||
content: "Error occurred, please check the log.\n\n出现错误,请检查日志:<pre>" + error.stack || error + "</pre>",
|
content: "Error occurred, please check the log.\n\n出现错误,请检查日志:<pre>" + error.stack || error + "</pre>",
|
||||||
},
|
},
|
||||||
finish_reason: null,
|
finish_reason: null,
|
||||||
index: 0,
|
index: 0,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
created: Math.floor(new Date().getTime() / 1000),
|
created: Math.floor(new Date().getTime() / 1000),
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
model: jsonBody.model,
|
model: jsonBody.model,
|
||||||
object: "chat.completion.chunk",
|
object: "chat.completion.chunk",
|
||||||
system_fingerprint: "114514",
|
system_fingerprint: "114514",
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
res.end();
|
res.end();
|
||||||
} else {
|
} else {
|
||||||
res.write(
|
res.write(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
object: "chat.completion",
|
object: "chat.completion",
|
||||||
created: Math.floor(new Date().getTime() / 1000),
|
created: Math.floor(new Date().getTime() / 1000),
|
||||||
model: jsonBody.model,
|
model: jsonBody.model,
|
||||||
system_fingerprint: "114514",
|
system_fingerprint: "114514",
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
index: 0,
|
index: 0,
|
||||||
message: {
|
message: {
|
||||||
role: "assistant",
|
role: "assistant",
|
||||||
content: "Error occurred, please check the log.\n\n出现错误,请检查日志:<pre>" + error.stack || error + "</pre>",
|
content: "Error occurred, please check the log.\n\n出现错误,请检查日志:<pre>" + error.stack || error + "</pre>",
|
||||||
},
|
},
|
||||||
logprobs: null,
|
logprobs: null,
|
||||||
finish_reason: "stop",
|
finish_reason: "stop",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
usage: {
|
usage: {
|
||||||
prompt_tokens: 1,
|
prompt_tokens: 1,
|
||||||
completion_tokens: 1,
|
completion_tokens: 1,
|
||||||
total_tokens: 1,
|
total_tokens: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
res.end();
|
res.end();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// handle anthropic format model request
|
// handle anthropic format model request
|
||||||
app.post("/v1/messages", AnthropicApiKeyAuth, (req, res) => {
|
app.post("/v1/messages", AnthropicApiKeyAuth, (req, res) => {
|
||||||
req.rawBody = "";
|
req.rawBody = "";
|
||||||
req.setEncoding("utf8");
|
req.setEncoding("utf8");
|
||||||
|
|
||||||
req.on("data", function (chunk) {
|
req.on("data", function (chunk) {
|
||||||
req.rawBody += chunk;
|
req.rawBody += chunk;
|
||||||
});
|
});
|
||||||
|
|
||||||
req.on("end", async () => {
|
req.on("end", async () => {
|
||||||
console.log("Handling request of Anthropic format");
|
console.log("Handling request of Anthropic format");
|
||||||
res.setHeader("Content-Type", "text/event-stream;charset=utf-8");
|
res.setHeader("Content-Type", "text/event-stream;charset=utf-8");
|
||||||
res.setHeader("Access-Control-Allow-Origin", "*");
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||||
let jsonBody = JSON.parse(req.rawBody);
|
let jsonBody = JSON.parse(req.rawBody);
|
||||||
if (jsonBody.system) {
|
if (jsonBody.system) {
|
||||||
// 把系统消息加入messages的首条
|
// 把系统消息加入messages的首条
|
||||||
jsonBody.messages.unshift({ role: "system", content: jsonBody.system });
|
jsonBody.messages.unshift({role: "system", content: jsonBody.system});
|
||||||
}
|
}
|
||||||
console.log("message length:" + jsonBody.messages.length);
|
console.log("message length:" + jsonBody.messages.length);
|
||||||
|
|
||||||
// decide which session to use randomly
|
// decide which session to use randomly
|
||||||
let randomSession = Object.keys(provider.sessions)[Math.floor(Math.random() * Object.keys(provider.sessions).length)];
|
let randomSession = Object.keys(provider.sessions)[Math.floor(Math.random() * Object.keys(provider.sessions).length)];
|
||||||
console.log("Using session " + randomSession);
|
console.log("Using session " + randomSession);
|
||||||
|
|
||||||
// decide which model to use
|
// decide which model to use
|
||||||
let proxyModel;
|
let proxyModel;
|
||||||
if (process.env.AI_MODEL) {
|
if (process.env.AI_MODEL) {
|
||||||
proxyModel = process.env.AI_MODEL;
|
proxyModel = process.env.AI_MODEL;
|
||||||
} else if (jsonBody.model && modelMappping[jsonBody.model]) {
|
} else if (jsonBody.model && modelMappping[jsonBody.model]) {
|
||||||
proxyModel = modelMappping[jsonBody.model];
|
proxyModel = modelMappping[jsonBody.model];
|
||||||
} else {
|
} else {
|
||||||
proxyModel = "claude_3_opus";
|
proxyModel = "claude_3_opus";
|
||||||
}
|
}
|
||||||
console.log(`Using model ${proxyModel}`);
|
console.log(`Using model ${proxyModel}`);
|
||||||
|
|
||||||
// call provider to get completion
|
// call provider to get completion
|
||||||
await provider
|
await provider
|
||||||
.getCompletion({
|
.getCompletion({
|
||||||
username: randomSession,
|
username: randomSession,
|
||||||
messages: jsonBody.messages,
|
messages: jsonBody.messages,
|
||||||
stream: !!jsonBody.stream,
|
stream: !!jsonBody.stream,
|
||||||
proxyModel: proxyModel,
|
proxyModel: proxyModel,
|
||||||
useCustomMode: process.env.USE_CUSTOM_MODE === "true"
|
useCustomMode: process.env.USE_CUSTOM_MODE === "true"
|
||||||
})
|
})
|
||||||
.then(({ completion, cancel }) => {
|
.then(({completion, cancel}) => {
|
||||||
completion.on("start", (id) => {
|
completion.on("start", (id) => {
|
||||||
if (jsonBody.stream) {
|
if (jsonBody.stream) {
|
||||||
// send message start
|
// send message start
|
||||||
res.write(
|
res.write(
|
||||||
createEvent("message_start", {
|
createEvent("message_start", {
|
||||||
type: "message_start",
|
type: "message_start",
|
||||||
message: {
|
message: {
|
||||||
id: `${id}`,
|
id: `${id}`,
|
||||||
type: "message",
|
type: "message",
|
||||||
role: "assistant",
|
role: "assistant",
|
||||||
content: [],
|
content: [],
|
||||||
model: proxyModel,
|
model: proxyModel,
|
||||||
stop_reason: null,
|
stop_reason: null,
|
||||||
stop_sequence: null,
|
stop_sequence: null,
|
||||||
usage: { input_tokens: 8, output_tokens: 1 },
|
usage: {input_tokens: 8, output_tokens: 1},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
res.write(createEvent("content_block_start", { type: "content_block_start", index: 0, content_block: { type: "text", text: "" } }));
|
res.write(createEvent("content_block_start", {
|
||||||
res.write(createEvent("ping", { type: "ping" }));
|
type: "content_block_start",
|
||||||
}
|
index: 0,
|
||||||
});
|
content_block: {type: "text", text: ""}
|
||||||
|
}));
|
||||||
|
res.write(createEvent("ping", {type: "ping"}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
completion.on("completion", (id, text) => {
|
completion.on("completion", (id, text) => {
|
||||||
if (jsonBody.stream) {
|
if (jsonBody.stream) {
|
||||||
// send message delta
|
// send message delta
|
||||||
res.write(
|
res.write(
|
||||||
createEvent("content_block_delta", {
|
createEvent("content_block_delta", {
|
||||||
type: "content_block_delta",
|
type: "content_block_delta",
|
||||||
index: 0,
|
index: 0,
|
||||||
delta: { type: "text_delta", text: text },
|
delta: {type: "text_delta", text: text},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// 只会发一次,发送final response
|
// 只会发一次,发送final response
|
||||||
res.write(
|
res.write(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
id: id,
|
id: id,
|
||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
text: text,
|
text: text,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "string",
|
id: "string",
|
||||||
name: "string",
|
name: "string",
|
||||||
input: {},
|
input: {},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
model: "string",
|
model: "string",
|
||||||
stop_reason: "end_turn",
|
stop_reason: "end_turn",
|
||||||
stop_sequence: "string",
|
stop_sequence: "string",
|
||||||
usage: {
|
usage: {
|
||||||
input_tokens: 0,
|
input_tokens: 0,
|
||||||
output_tokens: 0,
|
output_tokens: 0,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
res.end();
|
res.end();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
completion.on("end", () => {
|
completion.on("end", () => {
|
||||||
if (jsonBody.stream) {
|
if (jsonBody.stream) {
|
||||||
res.write(createEvent("content_block_stop", { type: "content_block_stop", index: 0 }));
|
res.write(createEvent("content_block_stop", {type: "content_block_stop", index: 0}));
|
||||||
res.write(
|
res.write(
|
||||||
createEvent("message_delta", {
|
createEvent("message_delta", {
|
||||||
type: "message_delta",
|
type: "message_delta",
|
||||||
delta: { stop_reason: "end_turn", stop_sequence: null },
|
delta: {stop_reason: "end_turn", stop_sequence: null},
|
||||||
usage: { output_tokens: 12 },
|
usage: {output_tokens: 12},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
res.write(createEvent("message_stop", { type: "message_stop" }));
|
res.write(createEvent("message_stop", {type: "message_stop"}));
|
||||||
res.end();
|
res.end();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
res.on("close", () => {
|
res.on("close", () => {
|
||||||
console.log(" > [Client closed]");
|
console.log(" > [Client closed]");
|
||||||
completion.removeAllListeners();
|
completion.removeAllListeners();
|
||||||
cancel();
|
cancel();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
if (jsonBody.stream) {
|
if (jsonBody.stream) {
|
||||||
res.write(
|
res.write(
|
||||||
createEvent("content_block_delta", {
|
createEvent("content_block_delta", {
|
||||||
type: "content_block_delta",
|
type: "content_block_delta",
|
||||||
index: 0,
|
index: 0,
|
||||||
delta: {
|
delta: {
|
||||||
type: "text_delta",
|
type: "text_delta",
|
||||||
text: "Error occurred, please check the log.\n\n出现错误,请检查日志:<pre>" + error.stack || error + "</pre>",
|
text: "Error occurred, please check the log.\n\n出现错误,请检查日志:<pre>" + error.stack || error + "</pre>",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
res.end();
|
res.end();
|
||||||
} else {
|
} else {
|
||||||
res.write(
|
res.write(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
text: "Error occurred, please check the log.\n\n出现错误,请检查日志:<pre>" + error.stack || error + "</pre>",
|
text: "Error occurred, please check the log.\n\n出现错误,请检查日志:<pre>" + error.stack || error + "</pre>",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "string",
|
id: "string",
|
||||||
name: "string",
|
name: "string",
|
||||||
input: {},
|
input: {},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
model: "string",
|
model: "string",
|
||||||
stop_reason: "end_turn",
|
stop_reason: "end_turn",
|
||||||
stop_sequence: "string",
|
stop_sequence: "string",
|
||||||
usage: {
|
usage: {
|
||||||
input_tokens: 0,
|
input_tokens: 0,
|
||||||
output_tokens: 0,
|
output_tokens: 0,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
res.end();
|
res.end();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// handle other
|
// handle other
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
const { revision, branch } = getGitRevision();
|
const {revision, branch} = getGitRevision();
|
||||||
res.status(404).send("Not Found (YouChat_Proxy " + revision + "@" + branch + ")");
|
res.status(404).send("Not Found (YouChat_Proxy " + revision + "@" + branch + ")");
|
||||||
console.log("收到了错误路径的请求,请检查您使用的API端点是否正确。")
|
console.log("收到了错误路径的请求,请检查您使用的API端点是否正确。")
|
||||||
});
|
});
|
||||||
|
|
||||||
const createLocaltunnel = async (port, subdomain) => {
|
const createLocaltunnel = async (port, subdomain) => {
|
||||||
const tunnelOptions = { port };
|
const tunnelOptions = {port};
|
||||||
if (subdomain) {
|
if (subdomain) {
|
||||||
tunnelOptions.subdomain = subdomain;
|
tunnelOptions.subdomain = subdomain;
|
||||||
}
|
}
|
||||||
@@ -461,7 +472,7 @@ const createLocaltunnel = async (port, subdomain) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const createNgrok = async (port, authToken, customDomain, subdomain) => {
|
const createNgrok = async (port, authToken, customDomain, subdomain) => {
|
||||||
const ngrokOptions = { addr: port, authtoken: authToken };
|
const ngrokOptions = {addr: port, authtoken: authToken};
|
||||||
|
|
||||||
if (customDomain) {
|
if (customDomain) {
|
||||||
ngrokOptions.hostname = customDomain;
|
ngrokOptions.hostname = customDomain;
|
||||||
@@ -514,27 +525,27 @@ app.listen(port, async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function AnthropicApiKeyAuth(req, res, next) {
|
function AnthropicApiKeyAuth(req, res, next) {
|
||||||
const reqApiKey = req.header("x-api-key");
|
const reqApiKey = req.header("x-api-key");
|
||||||
|
|
||||||
if (validApiKey && reqApiKey !== validApiKey) {
|
if (validApiKey && reqApiKey !== validApiKey) {
|
||||||
// If Environment variable PASSWORD is set AND x-api-key header is not equal to it, return 401
|
// If Environment variable PASSWORD is set AND x-api-key header is not equal to it, return 401
|
||||||
const clientIpAddress = req.headers["x-forwarded-for"] || req.ip;
|
const clientIpAddress = req.headers["x-forwarded-for"] || req.ip;
|
||||||
console.log(`Receviced Request from IP ${clientIpAddress} but got invalid password.`);
|
console.log(`Receviced Request from IP ${clientIpAddress} but got invalid password.`);
|
||||||
return res.status(401).json({ error: "Invalid Password" });
|
return res.status(401).json({error: "Invalid Password"});
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
function OpenAIApiKeyAuth(req, res, next) {
|
function OpenAIApiKeyAuth(req, res, next) {
|
||||||
const reqApiKey = req.header("Authorization");
|
const reqApiKey = req.header("Authorization");
|
||||||
|
|
||||||
if (validApiKey && reqApiKey !== "Bearer " + validApiKey) {
|
if (validApiKey && reqApiKey !== "Bearer " + validApiKey) {
|
||||||
// If Environment variable PASSWORD is set AND Authorization header is not equal to it, return 401
|
// If Environment variable PASSWORD is set AND Authorization header is not equal to it, return 401
|
||||||
const clientIpAddress = req.headers["x-forwarded-for"] || req.ip;
|
const clientIpAddress = req.headers["x-forwarded-for"] || req.ip;
|
||||||
console.log(`Receviced Request from IP ${clientIpAddress} but got invalid password.`);
|
console.log(`Receviced Request from IP ${clientIpAddress} but got invalid password.`);
|
||||||
return res.status(401).json({ error: { code: 403, message: "Invalid Password" } });
|
return res.status(401).json({error: {code: 403, message: "Invalid Password"}});
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user