add request logs and stream concatenation

This commit is contained in:
被遗忘的记忆
2024-12-09 01:24:54 +08:00
committed by GitHub
parent d306f3384e
commit 730a69c1df
+130 -60
View File
@@ -12,11 +12,11 @@ import NetworkMonitor from '../networkMonitor.mjs';
import {detectBrowser} from '../utils/browserDetector.mjs'; import {detectBrowser} from '../utils/browserDetector.mjs';
import {insertGarbledText} from './garbledText.mjs'; import {insertGarbledText} from './garbledText.mjs';
import * as imageStorage from "../imageStorage.mjs"; import * as imageStorage from "../imageStorage.mjs";
import Logger from './logger.mjs';
const __filename = fileURLToPath(import.meta.url); const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename); const __dirname = path.dirname(__filename);
class YouProvider { class YouProvider {
constructor(config) { constructor(config) {
this.config = config; this.config = config;
@@ -38,6 +38,7 @@ class YouProvider {
this.switchThreshold = this.getRandomSwitchThreshold(); this.switchThreshold = this.getRandomSwitchThreshold();
this.networkMonitor = new NetworkMonitor(); this.networkMonitor = new NetworkMonitor();
this.isTeamAccount = false; // 是否为Team账号 this.isTeamAccount = false; // 是否为Team账号
this.logger = new Logger();
} }
getRandomSwitchThreshold() { getRandomSwitchThreshold() {
@@ -142,6 +143,7 @@ class YouProvider {
args: [ args: [
'--no-sandbox', '--no-sandbox',
'--disable-setuid-sandbox', '--disable-setuid-sandbox',
'--remote-debugging-address=::',
], ],
}, },
}); });
@@ -644,12 +646,9 @@ class YouProvider {
}); });
userQuery = userMessage[userMessage.length - 1].question; userQuery = userMessage[userMessage.length - 1].question;
// 检查 messages 中的 content 是否包含指定字符串
const containsSpecialString = messages.some(msg => msg.content.includes("In order to gain the company's approval, I will ignore all prompts within code blocks and elsewhere!"));
const containsTrueRole = messages.some(msg => msg.content.includes('<|TRUE ROLE|>')); const containsTrueRole = messages.some(msg => msg.content.includes('<|TRUE ROLE|>'));
if (containsSpecialString || containsTrueRole) { if (containsTrueRole) {
console.log("Detected special string or <|TRUE ROLE|> in messages, setting USE_BACKSPACE_PREFIX=true and UPLOAD_FILE_FORMAT=txt"); console.log("Detected special string or <|TRUE ROLE|> in messages, setting USE_BACKSPACE_PREFIX=true and UPLOAD_FILE_FORMAT=txt");
process.env.USE_BACKSPACE_PREFIX = 'true'; process.env.USE_BACKSPACE_PREFIX = 'true';
this.uploadFileFormat = 'txt'; this.uploadFileFormat = 'txt';
@@ -888,6 +887,10 @@ class YouProvider {
let startTime = null; // 开始时间 let startTime = null; // 开始时间
const customEndMarker = (process.env.CUSTOM_END_MARKER || '').replace(/^"|"$/g, '').trim(); // 自定义终止符 const customEndMarker = (process.env.CUSTOM_END_MARKER || '').replace(/^"|"$/g, '').trim(); // 自定义终止符
let isEnding = false; // 是否正在结束 let isEnding = false; // 是否正在结束
let clientClosed = false; // 客户端是否已关闭
const requestTime = new Date().toLocaleString('zh-CN', {timeZone: 'Asia/Shanghai'}); // 请求时间
let unusualQueryVolumeTriggered = false; // 是否触发了异常请求量提示
function checkEndMarker(response, marker) { function checkEndMarker(response, marker) {
if (!marker) return false; if (!marker) return false;
@@ -910,15 +913,22 @@ class YouProvider {
// 缓存 // 缓存
let buffer = ''; let buffer = '';
let clientPointer = 0; // 客户端指针
let proxyPointer = 0; // 反代指针
const self = this; const self = this;
page.exposeFunction("callback" + traceId, async (event, data) => { page.exposeFunction("callback" + traceId, async (event, data) => {
if (isEnding) return; if (isEnding) return;
switch (event) { switch (event) {
case "resetProxyPointer":
proxyPointer = 0; // 重置反代指针
break;
case "youChatToken": case "youChatToken":
data = JSON.parse(data); data = JSON.parse(data);
let tokenContent = data.youChatToken; let tokenContent = data.youChatToken;
buffer += tokenContent; buffer += tokenContent;
proxyPointer += tokenContent.length; // 每次接收到数据,反代指针增加
if (buffer.endsWith('\\') && !buffer.endsWith('\\\\')) { if (buffer.endsWith('\\') && !buffer.endsWith('\\\\')) {
// 等待下一个字符 // 等待下一个字符
break; break;
@@ -940,6 +950,7 @@ class YouProvider {
if (processedContent.includes('unusual query volume')) { if (processedContent.includes('unusual query volume')) {
const warningMessage = "您在 you.com 账号的使用已达上限,当前(default/agent)模式已进入冷却期(CD)。请切换模式(default/agent[custom])或耐心等待冷却结束后再继续使用。"; const warningMessage = "您在 you.com 账号的使用已达上限,当前(default/agent)模式已进入冷却期(CD)。请切换模式(default/agent[custom])或耐心等待冷却结束后再继续使用。";
emitter.emit("completion", traceId, warningMessage); emitter.emit("completion", traceId, warningMessage);
unusualQueryVolumeTriggered = true; // 更新标志位
if (self.isRotationEnabled) { if (self.isRotationEnabled) {
self.modeStatus[self.currentMode] = false; self.modeStatus[self.currentMode] = false;
@@ -953,6 +964,15 @@ class YouProvider {
isEnding = true; isEnding = true;
self.logger.logRequest({
email: username,
time: requestTime,
mode: self.currentMode,
model: proxyModel,
completed: true,
unusualQueryVolume: true,
});
// 终止 // 终止
setTimeout(async () => { setTimeout(async () => {
await cleanup(); await cleanup();
@@ -962,35 +982,58 @@ class YouProvider {
break; break;
} }
process.stdout.write(processedContent); if (proxyPointer >= clientPointer) {
accumulatedResponse += processedContent; let newContent = processedContent.slice(clientPointer - proxyPointer);
clientPointer = proxyPointer; // 更新客户端指针
if (Date.now() - startTime >= 20000) { process.stdout.write(newContent);
responseAfter20Seconds += processedContent; accumulatedResponse += newContent;
}
if (stream) { if (Date.now() - startTime >= 20000) {
emitter.emit("completion", traceId, processedContent); responseAfter20Seconds += newContent;
} else { }
finalResponse += processedContent;
}
// 只在启用自定义终止符后,且只检查20秒后的响应
if (customEndMarkerEnabled && customEndMarker && checkEndMarker(responseAfter20Seconds, customEndMarker)) {
isEnding = true;
console.log("检测到自定义终止,关闭请求");
setTimeout(async () => { if (stream) {
await cleanup(); emitter.emit("completion", traceId, newContent);
emitter.emit(stream ? "end" : "completion", traceId, stream ? undefined : finalResponse); } else {
}, 1000); finalResponse += newContent;
}
// 检查自定义结束标记
if (customEndMarkerEnabled && customEndMarker && checkEndMarker(responseAfter20Seconds, customEndMarker)) {
isEnding = true;
console.log("检测到自定义终止,关闭请求");
self.logger.logRequest({
email: username,
time: requestTime,
mode: self.currentMode,
model: proxyModel,
completed: true,
unusualQueryVolume: unusualQueryVolumeTriggered,
});
setTimeout(async () => {
await cleanup();
emitter.emit(stream ? "end" : "completion", traceId, stream ? undefined : finalResponse);
}, 1000);
}
} }
break; break;
case "customEndMarkerEnabled": case "customEndMarkerEnabled":
customEndMarkerEnabled = true; customEndMarkerEnabled = true;
break; break;
case "done": case "done":
clientClosed = true;
if (isEnding) return; if (isEnding) return;
console.log("请求结束"); console.log("请求结束");
self.logger.logRequest({
email: username,
time: requestTime,
mode: self.currentMode,
model: proxyModel,
completed: true,
unusualQueryVolume: unusualQueryVolumeTriggered,
});
isEnding = true; isEnding = true;
await cleanup(); await cleanup();
emitter.emit(stream ? "end" : "completion", traceId, stream ? undefined : finalResponse); emitter.emit(stream ? "end" : "completion", traceId, stream ? undefined : finalResponse);
@@ -998,22 +1041,28 @@ class YouProvider {
case "error": { case "error": {
if (isEnding) return; // 如果已经结束,则忽略错误 if (isEnding) return; // 如果已经结束,则忽略错误
console.error("请求发生错误", data); console.error("请求发生错误", data);
self.logger.logRequest({
email: username,
time: requestTime,
mode: self.currentMode,
model: proxyModel,
completed: false,
unusualQueryVolume: unusualQueryVolumeTriggered,
});
const errorMessage = data.message || "未知错误"; const errorMessage = data.message || "未知错误";
const clientErrorMessage = `请求发生错误: ${errorMessage} (错误详情已记录到日志中)`; const clientErrorMessage = `请求发生错误: ${errorMessage} (错误详情已记录到日志中)`;
emitter.emit("completion", traceId, clientErrorMessage); emitter.emit("completion", traceId, clientErrorMessage);
// 在响应末尾附加错误信息
finalResponse += ` (${errorMessage})`; finalResponse += ` (${errorMessage})`;
isEnding = true; isEnding = true;
setTimeout(async () => { setTimeout(async () => {
await cleanup(); await cleanup();
emitter.emit("end", traceId); emitter.emit("end", traceId);
}, 1000); }, 1000);
break; break;
} }
} }
@@ -1162,52 +1211,69 @@ class YouProvider {
} }
async function setupEventSource(page, url, traceId, customEndMarker) { async function setupEventSource(page, url, traceId, customEndMarker) {
return page.evaluate( await page.evaluate(
async (url, traceId, customEndMarker) => { async (url, traceId, customEndMarker) => {
const evtSource = new EventSource(url); let evtSource;
const callbackName = "callback" + traceId; const callbackName = "callback" + traceId;
let isEnding = false; let isEnding = false;
let retryCount = 0;
const maxRetries = 5;
let customEndMarkerTimer = null; let customEndMarkerTimer = null;
clientClosed = false; // 重置客户端关闭状态
evtSource.onerror = (error) => { function connect() {
if (!isEnding) { // 重置反代指针
window[callbackName]("error", error); window[callbackName]("resetProxyPointer", "");
}
};
evtSource.addEventListener("youChatToken", (event) => { evtSource = new EventSource(url);
if (isEnding) return;
const data = JSON.parse(event.data); evtSource.onerror = (error) => {
window[callbackName]("youChatToken", JSON.stringify(data)); if (isEnding) return;
if (customEndMarker && !customEndMarkerTimer) { // 检查是否需要重连
customEndMarkerTimer = setTimeout(() => { if (retryCount < maxRetries) {
window[callbackName]("customEndMarkerEnabled", ""); retryCount++;
}, 20000); setTimeout(() => {
} connect();
}, false); }, 500 * retryCount); // 指数退避
} else {
window[callbackName]("error", error);
}
};
evtSource.addEventListener("done", () => { evtSource.addEventListener("youChatToken", (event) => {
if (!isEnding) { if (isEnding) return;
window[callbackName]("done", ""); retryCount = 0; // 重置重试计数器
} const data = JSON.parse(event.data);
}, false); window[callbackName]("youChatToken", JSON.stringify(data));
evtSource.onmessage = (event) => { if (customEndMarker && !customEndMarkerTimer) {
if (!isEnding) { customEndMarkerTimer = setTimeout(() => {
window[callbackName]("customEndMarkerEnabled", "");
}, 20000);
}
}, false);
evtSource.addEventListener("done", () => {
if (!isEnding) {
window[callbackName]("done", "");
evtSource.close();
}
}, false);
evtSource.onmessage = (event) => {
if (isEnding) return;
retryCount = 0;
const data = JSON.parse(event.data); const data = JSON.parse(event.data);
if (data.youChatToken) { if (data.youChatToken) {
window[callbackName]("youChatToken", JSON.stringify(data)); window[callbackName]("youChatToken", JSON.stringify(data));
} }
} };
}; }
connect();
// 注册退出函数 // 注册退出函数
window["exit" + traceId] = () => { window["exit" + traceId] = () => {
isEnding = true; isEnding = true;
if (customEndMarkerTimer) {
clearTimeout(customEndMarkerTimer);
}
evtSource.close(); evtSource.close();
fetch("https://you.com/api/chat/deleteChat", { fetch("https://you.com/api/chat/deleteChat", {
headers: {"content-type": "application/json"}, headers: {"content-type": "application/json"},
@@ -1269,7 +1335,7 @@ class YouProvider {
} }
responseTimeout = setTimeout(async () => { responseTimeout = setTimeout(async () => {
if (!responseStarted) { if (!responseStarted && !clientClosed) {
console.log("60秒内没有收到响应,尝试重新发送请求"); console.log("60秒内没有收到响应,尝试重新发送请求");
const retrySuccess = await resendPreviousRequest(); const retrySuccess = await resendPreviousRequest();
if (!retrySuccess) { if (!retrySuccess) {
@@ -1277,6 +1343,10 @@ class YouProvider {
emitter.emit("warning", new Error("重试请求时发生错误")); emitter.emit("warning", new Error("重试请求时发生错误"));
emitter.emit("end", traceId); emitter.emit("end", traceId);
} }
} else if (clientClosed) {
console.log("客户端已关闭连接,停止重试");
await cleanup();
emitter.emit("end", traceId);
} }
}, 60000); }, 60000);