support openai format
This commit is contained in:
@@ -17,9 +17,3 @@ If you find this project useful, please consider [buying me a cup of coffee](htt
|
|||||||
您的电脑上必须安装有 Google Chrome 浏览器才能够使用当前分支。旧版已不再维护。
|
您的电脑上必须安装有 Google Chrome 浏览器才能够使用当前分支。旧版已不再维护。
|
||||||
|
|
||||||
Google Chrome must be installed on your system in order to use this proxy. Previous versions are no longer maintained.
|
Google Chrome must be installed on your system in order to use this proxy. Previous versions are no longer maintained.
|
||||||
|
|
||||||
## Limitations 限制
|
|
||||||
|
|
||||||
Only Anthropic API format is supported. Change the model name to use different models (default claude_3_opus)
|
|
||||||
|
|
||||||
只支持A社的API格式,默认模型为 claude_3_opus。
|
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ const modelMappping = {
|
|||||||
"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-4o": "gpt_4o",
|
||||||
|
"gpt-4-turbo": "gpt_4_turbo",
|
||||||
};
|
};
|
||||||
|
|
||||||
// import config.mjs
|
// import config.mjs
|
||||||
@@ -50,7 +53,7 @@ app.options("/v1/messages", (req, res) => {
|
|||||||
res.status(200).end();
|
res.status(200).end();
|
||||||
});
|
});
|
||||||
// openai format model request
|
// openai format model request
|
||||||
app.get("/v1/models", apiKeyAuth, (req, res) => {
|
app.get("/v1/models", OpenAIApiKeyAuth, (req, res) => {
|
||||||
res.setHeader("Content-Type", "application/json");
|
res.setHeader("Content-Type", "application/json");
|
||||||
res.setHeader("Access-Control-Allow-Origin", "*");
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||||
let models = availableModels.map((model, index) => {
|
let models = availableModels.map((model, index) => {
|
||||||
@@ -64,7 +67,8 @@ app.get("/v1/models", apiKeyAuth, (req, res) => {
|
|||||||
});
|
});
|
||||||
res.json({ object: "list", data: models });
|
res.json({ object: "list", data: models });
|
||||||
});
|
});
|
||||||
app.post("/v1/messages", apiKeyAuth, (req, res) => {
|
// handle openai format model request
|
||||||
|
app.post("/v1/chat/completions", OpenAIApiKeyAuth, (req, res) => {
|
||||||
req.rawBody = "";
|
req.rawBody = "";
|
||||||
req.setEncoding("utf8");
|
req.setEncoding("utf8");
|
||||||
|
|
||||||
@@ -73,6 +77,188 @@ app.post("/v1/messages", apiKeyAuth, (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
req.on("end", async () => {
|
req.on("end", async () => {
|
||||||
|
console.log("Handling request of OpenAI format");
|
||||||
|
res.setHeader("Content-Type", "text/event-stream;charset=utf-8");
|
||||||
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
let jsonBody = JSON.parse(req.rawBody);
|
||||||
|
|
||||||
|
console.log("message length:" + jsonBody.messages.length);
|
||||||
|
// decide which session to use randomly
|
||||||
|
var randomSession = Object.keys(provider.sessions)[Math.floor(Math.random() * Object.keys(provider.sessions).length)];
|
||||||
|
console.log("Using session " + randomSession);
|
||||||
|
// call provider to get completion
|
||||||
|
|
||||||
|
// try to map model
|
||||||
|
if (jsonBody.model && modelMappping[jsonBody.model]) {
|
||||||
|
jsonBody.model = modelMappping[jsonBody.model];
|
||||||
|
}
|
||||||
|
if (jsonBody.model && !availableModels.includes(jsonBody.model)) {
|
||||||
|
res.json({ error: { code: 404, message: "Invalid Model" } });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("Using model " + jsonBody.model);
|
||||||
|
|
||||||
|
// call provider to get completion
|
||||||
|
await provider
|
||||||
|
.getCompletion(randomSession, jsonBody.messages, jsonBody.stream ? true : false, jsonBody.model, process.env.USE_CUSTOM_MODE == "true" ? true : false)
|
||||||
|
.then(({ completion, cancel }) => {
|
||||||
|
completion.on("start", (id) => {
|
||||||
|
if (jsonBody.stream) {
|
||||||
|
// send message start
|
||||||
|
res.write(createEvent(":", "queue heartbeat 114514"));
|
||||||
|
res.write(
|
||||||
|
createEvent("data", {
|
||||||
|
id: msgid,
|
||||||
|
object: "chat.completion.chunk",
|
||||||
|
created: Math.floor(new Date().getTime() / 1000),
|
||||||
|
model: jsonBody.model,
|
||||||
|
system_fingerprint: "114514",
|
||||||
|
choices: [{ index: 0, delta: { role: "assistant", content: "" }, logprobs: null, finish_reason: null }],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
completion.on("completion", (id, text) => {
|
||||||
|
if (jsonBody.stream) {
|
||||||
|
// send message delta
|
||||||
|
if (jsonBody.stream) {
|
||||||
|
res.write(
|
||||||
|
createEvent("data", {
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
content_filter_results: {
|
||||||
|
hate: { filtered: false, severity: "safe" },
|
||||||
|
self_harm: { filtered: false, severity: "safe" },
|
||||||
|
sexual: { filtered: false, severity: "safe" },
|
||||||
|
violence: { filtered: false, severity: "safe" },
|
||||||
|
},
|
||||||
|
delta: { content: text },
|
||||||
|
finish_reason: null,
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
created: Math.floor(new Date().getTime() / 1000),
|
||||||
|
id: id,
|
||||||
|
model: jsonBody.model,
|
||||||
|
object: "chat.completion.chunk",
|
||||||
|
system_fingerprint: "114514",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 只会发一次,发送final response
|
||||||
|
res.write(
|
||||||
|
JSON.stringify({
|
||||||
|
id: id,
|
||||||
|
object: "chat.completion",
|
||||||
|
created: Math.floor(new Date().getTime() / 1000),
|
||||||
|
model: jsonBody.model,
|
||||||
|
system_fingerprint: "114514",
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
index: 0,
|
||||||
|
message: {
|
||||||
|
role: "assistant",
|
||||||
|
content: text,
|
||||||
|
},
|
||||||
|
logprobs: null,
|
||||||
|
finish_reason: "stop",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
usage: {
|
||||||
|
prompt_tokens: 1,
|
||||||
|
completion_tokens: 1,
|
||||||
|
total_tokens: 1,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
res.end();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
completion.on("end", () => {
|
||||||
|
if (jsonBody.stream) {
|
||||||
|
res.write(createEvent("data", "[DONE]"));
|
||||||
|
res.end();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
res.on("close", () => {
|
||||||
|
console.log(" > [Client closed]");
|
||||||
|
completion.removeAllListeners();
|
||||||
|
cancel();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
if (jsonBody.stream) {
|
||||||
|
res.write(
|
||||||
|
createEvent("data", {
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
content_filter_results: {
|
||||||
|
hate: { filtered: false, severity: "safe" },
|
||||||
|
self_harm: { filtered: false, severity: "safe" },
|
||||||
|
sexual: { filtered: false, severity: "safe" },
|
||||||
|
violence: { filtered: false, severity: "safe" },
|
||||||
|
},
|
||||||
|
delta: { content: "Error occurred, please check the log.\n\n出现错误,请检查日志:<pre>" + error.stack || error + "</pre>" },
|
||||||
|
finish_reason: null,
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
created: Math.floor(new Date().getTime() / 1000),
|
||||||
|
id: uuidv4(),
|
||||||
|
model: jsonBody.model,
|
||||||
|
object: "chat.completion.chunk",
|
||||||
|
system_fingerprint: "114514",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
res.end();
|
||||||
|
} else {
|
||||||
|
res.write(
|
||||||
|
JSON.stringify({
|
||||||
|
id: uuidv4(),
|
||||||
|
object: "chat.completion",
|
||||||
|
created: Math.floor(new Date().getTime() / 1000),
|
||||||
|
model: jsonBody.model,
|
||||||
|
system_fingerprint: "114514",
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
index: 0,
|
||||||
|
message: {
|
||||||
|
role: "assistant",
|
||||||
|
content: "Error occurred, please check the log.\n\n出现错误,请检查日志:<pre>" + error.stack || error + "</pre>",
|
||||||
|
},
|
||||||
|
logprobs: null,
|
||||||
|
finish_reason: "stop",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
usage: {
|
||||||
|
prompt_tokens: 1,
|
||||||
|
completion_tokens: 1,
|
||||||
|
total_tokens: 1,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
res.end();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// handle anthropic format model request
|
||||||
|
app.post("/v1/messages", AnthropicApiKeyAuth, (req, res) => {
|
||||||
|
req.rawBody = "";
|
||||||
|
req.setEncoding("utf8");
|
||||||
|
|
||||||
|
req.on("data", function (chunk) {
|
||||||
|
req.rawBody += chunk;
|
||||||
|
});
|
||||||
|
|
||||||
|
req.on("end", async () => {
|
||||||
|
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);
|
||||||
@@ -191,17 +377,20 @@ app.post("/v1/messages", apiKeyAuth, (req, res) => {
|
|||||||
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: "出现错误,请检查日志:<pre>" + error + "</pre>"},
|
delta: {
|
||||||
|
type: "text_delta",
|
||||||
|
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: id,
|
id: uuidv4(),
|
||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
text: "出现错误,请检查日志:<pre>" + error + "</pre>"
|
text: "Error occurred, please check the log.\n\n出现错误,请检查日志:<pre>" + error.stack || error + "</pre>",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "string",
|
id: "string",
|
||||||
@@ -235,10 +424,10 @@ app.listen(port, () => {
|
|||||||
if (!validApiKey) {
|
if (!validApiKey) {
|
||||||
console.log(`Proxy is currently running with no authentication`);
|
console.log(`Proxy is currently running with no authentication`);
|
||||||
}
|
}
|
||||||
console.log(`API Format: Anthropic; Custom mode: ${process.env.USE_CUSTOM_MODE == "true" ? "enabled" : "disabled"}`);
|
console.log(`Custom mode: ${process.env.USE_CUSTOM_MODE == "true" ? "enabled" : "disabled"}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
function apiKeyAuth(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) {
|
||||||
@@ -250,3 +439,16 @@ function apiKeyAuth(req, res, next) {
|
|||||||
|
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function OpenAIApiKeyAuth(req, res, next) {
|
||||||
|
const reqApiKey = req.header("Authorization");
|
||||||
|
|
||||||
|
if (validApiKey && reqApiKey !== "Bearer " + validApiKey) {
|
||||||
|
// 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;
|
||||||
|
console.log(`Receviced Request from IP ${clientIpAddress} but got invalid password.`);
|
||||||
|
return res.status(401).json({ error: { code: 403, message: "Invalid Password" } });
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
|
|
||||||
# 使用方法
|
# 使用方法
|
||||||
|
|
||||||
0. 安装 Node.JS
|
0. 安装 Node.JS 和 Git
|
||||||
|
|
||||||
1. 获得一个 YOU.COM 账户并且订阅,登录。
|
1. 获得一个 YOU.COM 账户并且订阅,登录。
|
||||||
|
|
||||||
2. 打开 F12(DevTools),找到 “Network(网络)”、刷新一下页面,找到“you.com”这个项目(或者“instrumentation”这个项目)
|
2. 打开 F12(DevTools),找到 Console
|
||||||
|
|
||||||
3. 点进去,往下滑找到 "Cookie",完整的复制后面的内容。
|
3. 在 > 后面粘贴以下代码并回车。然后复制所有内容(Cookie)。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
prompt("请Ctrl+C复制以下所有内容(Cookie)",document.cookie)
|
||||||
|
```
|
||||||
|
|
||||||
4. 下载或Clone本项目代码,解压
|
4. 下载或Clone本项目代码,解压
|
||||||
|
|
||||||
@@ -30,29 +35,31 @@ export const config = {
|
|||||||
|
|
||||||
7. (可选)如果需要,您可以仿照第6步在`start.bat`中设定一个名为 "PASSWORD" 的环境变量,并将其用作密码。如果没有定义该环境变量,程序将接受所有传入的请求,而不进行任何身份验证
|
7. (可选)如果需要,您可以仿照第6步在`start.bat`中设定一个名为 "PASSWORD" 的环境变量,并将其用作密码。如果没有定义该环境变量,程序将接受所有传入的请求,而不进行任何身份验证
|
||||||
|
|
||||||
(可选)如果需要,可以设置代理。
|
(可选)如果需要,可以设置代理,请参考下文。
|
||||||
|
|
||||||
(可选)如果需要,可以修改使用的模型。但是仍然建议使用opus,因为其他未经测试。
|
|
||||||
|
|
||||||
(可选)如果需要,可以启用自定义会话模式(`USE_CUSTOM_MODE`设置为`true`)。可以缩短原系统消息长度、禁用联网、减缓等待时间,可能有助于破限。但有可能导致更容易出现 unusual query volume。
|
(可选)如果需要,可以启用自定义会话模式(`USE_CUSTOM_MODE`设置为`true`)。可以缩短原系统消息长度、禁用联网、减缓等待时间,可能有助于破限。但有可能导致更容易出现 unusual query volume。
|
||||||
|
|
||||||
8. 启动 start.bat
|
8. 启动 start.bat
|
||||||
|
|
||||||
9. 酒馆中选择 Claude,反向代理地址填 http://127.0.0.1:8080/v1 **反代密码必须填, 同时打开流式传输**,随便什么都可以(除非你在第7步设置了PASSWORD)。
|
9. 酒馆中选择 **Custom (OpenAI-compatible)**,反向代理地址填 http://127.0.0.1:8080/v1 **反代密码必须填**,随便什么都可以(除非你在第7步设置了PASSWORD)。
|
||||||
|
|
||||||
10. 开始使用。如果失败了/没有结果/403/Warning 就多重试几次。
|
10. 开始使用。如果失败了/没有结果/403/Warning 就多重试几次。
|
||||||
|
|
||||||
# 使用代理
|
# 使用代理
|
||||||
|
|
||||||
可以使用本地的socks5或http(s)代理。只需在 start.bat 中设置 `https_proxy` 环境变量。
|
如果用户在中国大陆,可能会遇到访问不稳定的情况。从npm安装依赖和从 git 拉取代码也需要稳定的网络连接。这些操作遇到问题的时候应该首先考虑挂全局代理。
|
||||||
|
|
||||||
|
对于项目本身,可以使用本地的socks5或http(s)代理。只需在 start.bat 中设置 `https_proxy` 环境变量。
|
||||||
|
|
||||||
比如,如要使用 Clash 的默认本地代理,则应设置为 `set https_proxy=http://127.0.0.1:7890`
|
比如,如要使用 Clash 的默认本地代理,则应设置为 `set https_proxy=http://127.0.0.1:7890`
|
||||||
|
|
||||||
欲知详细代理格式,请查阅 https://www.npmjs.com/package/proxy-from-env
|
欲知详细代理格式,请查阅 https://www.npmjs.com/package/proxy-from-env
|
||||||
|
|
||||||
# VPS 部署
|
# 操作系统部署
|
||||||
|
|
||||||
请使用项目中的 Dockerfile,不建议使用其他方式部署。
|
对于Linux,请使用项目中的 Dockerfile,但总的来说还不是很稳定。如果你会自己配置 X11、桌面环境,那就最好,否则建议还是用本地Windows部署。
|
||||||
|
|
||||||
|
对于 Android 下的Termux环境,暂时没有适配Android Chrome WebDriver的计划所以不支持。当用户询问手机使用相关问题时,请告诉他们用puppeteer的新版本不支持,如果是旧版本,可以尽力为他们提供帮助但是需要说明旧版本已经不再更新。
|
||||||
|
|
||||||
# 修改模型
|
# 修改模型
|
||||||
|
|
||||||
@@ -76,9 +83,33 @@ command_r_plus
|
|||||||
zephyr
|
zephyr
|
||||||
```
|
```
|
||||||
|
|
||||||
## 注意事项
|
# 注意事项
|
||||||
|
|
||||||
如果浏览器弹出人机验证窗口,请在30秒内完成。
|
## 不同分支的问题
|
||||||
|
项目目前有三个分支,可以用git checkout <分支> 的指令相互切换:
|
||||||
|
- bypass-cf 分支,最新版本(维护中),API格式为任意格式(两种格式都支持)。使用puppeteer模拟浏览器访问。
|
||||||
|
- anthropic 分支,旧版本(不再维护),API格式为Anthropic格式。直接请求API,容易被CloudFlare识别为机器人而拦截。
|
||||||
|
- openai 分支,旧版本(不再维护),API格式为OpenAI格式。直接请求API,容易被CloudFlare识别为机器人而拦截。
|
||||||
|
|
||||||
|
在诊断用户问题的时候,注意观察或者询问用户用的是哪个分支,不同API格式不能通用。酒馆提示 Not Found,可能就是因为选错了对应的API格式。
|
||||||
|
|
||||||
|
## 关于403问题的原理(基本只存在于旧版本)
|
||||||
|
|
||||||
|
cloudflare有一个风控分数。这个和你的TLS指纹、浏览器指纹、IP地址声誉等等有关系
|
||||||
|
我们这个项目一直用的TLS指纹和浏览器指纹就非常可疑(都是自动化库和Node内置TLS),分数直接拉满
|
||||||
|
相当于已经预先有了30+30分数,剩下就看IP地址声誉(40分)你拿了几分
|
||||||
|
(具体分数不详,只是举个例子)
|
||||||
|
那如果你IP确实白,拿了0分,那你总共分数就是60。
|
||||||
|
假设you那边设置了分数高于80的要跳验证码,那现在就没事
|
||||||
|
如果你IP黑,拿了超过20分,那你就是>80分,你就要跳验证码,结果就是403
|
||||||
|
然后最近you觉得被薅狠了,或者别的啥原因,把这个分数设置成60以上的就要跳验证码
|
||||||
|
结果就我IP有点黑,不管怎么搞都过不去了。
|
||||||
|
但是同样的IP,你用正常的Google Chrome访问,就没问题,因为它的指纹非常干净,所以前面的指纹分数就很低
|
||||||
|
就算加上IP声誉分他也没到那条线
|
||||||
|
总之以上是一个简化的版本,CF抗bot还有很多指标、很多策略
|
||||||
|
这个问题基本只存在于旧版本,新版本由于使用了浏览器模拟访问,已经不容易被拦截。
|
||||||
|
|
||||||
|
新版本如果弹出人机验证提示,用户只需要在30秒内点击完成CloudFlare的人机验证,并且等待程序继续处理即可。
|
||||||
|
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
@@ -115,13 +146,11 @@ export const config = {
|
|||||||
|
|
||||||
(Optional) You can set the proxy in start.bat. See below.
|
(Optional) You can set the proxy in start.bat. See below.
|
||||||
|
|
||||||
(Optional) You may change the model to use, but only claude_3_opus is tested.
|
|
||||||
|
|
||||||
(Optional) You may turn on the custom chat mode by setting `USE_CUSTOM_MODE` env to `true`
|
(Optional) You may turn on the custom chat mode by setting `USE_CUSTOM_MODE` env to `true`
|
||||||
|
|
||||||
8. Start start.bat
|
8. Start start.bat
|
||||||
|
|
||||||
9. Select Claude in the Tavern and put http://127.0.0.1:8080/v1 as the address of the reverse proxy. **Use any random string for password, also turn on Streaming** (unless you set PASSWORD in step 7).
|
9. Select **Custom (OpenAI-compatible)** in the SillyTavern and ues http://127.0.0.1:8080/v1 as the endpoint of the reverse proxy. **Use any random string for password** (unless you set PASSWORD in step 7).
|
||||||
|
|
||||||
10. Enjoy it. If it fails/no result/403/Warning, try again.
|
10. Enjoy it. If it fails/no result/403/Warning, try again.
|
||||||
|
|
||||||
@@ -133,30 +162,6 @@ Use the `https_proxy` env to set custom proxy. Refer to https://www.npmjs.com/pa
|
|||||||
|
|
||||||
Docker is highly recommended, please use the Dockerfile.
|
Docker is highly recommended, please use the Dockerfile.
|
||||||
|
|
||||||
# Change model
|
|
||||||
|
|
||||||
Change `AI_MODEL` env to switch between models.
|
|
||||||
|
|
||||||
Supported model names (refer to you.com website for latest models):
|
|
||||||
|
|
||||||
```
|
|
||||||
gpt_4o
|
|
||||||
gpt_4_turbo
|
|
||||||
gpt_4
|
|
||||||
claude_3_5_sonnet
|
|
||||||
claude_3_opus
|
|
||||||
claude_3_sonnet
|
|
||||||
claude_3_haiku
|
|
||||||
claude_2
|
|
||||||
llama3
|
|
||||||
gemini_pro
|
|
||||||
gemini_1_5_pro
|
|
||||||
databricks_dbrx_instruct
|
|
||||||
command_r
|
|
||||||
command_r_plus
|
|
||||||
zephyr
|
|
||||||
```
|
|
||||||
|
|
||||||
## Caution
|
## Caution
|
||||||
|
|
||||||
If you get a CloudFlare Challenge, solve it in 30 seconds.
|
If you get a CloudFlare Challenge, solve it in 30 seconds.
|
||||||
|
|||||||
Reference in New Issue
Block a user