File size: 3,714 Bytes
bc0be9c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
import { generateVqdHash } from "./vm.ts";
import { userAgent } from "./utils.ts";
import { CONFIG, getHash, setHash } from "./utils.ts";
import { ChatMessage } from "./types.ts";
import { errorResponse } from "./response.ts";
export class DDGService {
private hash: string | null = null;
async getVqdHash(): Promise<string | Response> {
// 优先使用环境变量中的hash
const envHash = getHash();
if (envHash) {
return envHash;
}
try {
const response = await fetch(CONFIG.DDG_STATUS_URL, {
method: "GET",
headers: {
"User-Agent": userAgent,
"x-vqd-accept": "1",
},
});
if (!response.ok) {
return errorResponse(`hash初始化请求失败: ${response.status}`, 502);
}
const hash = response.headers.get("x-vqd-hash-1");
if (!hash) {
return errorResponse(`未找到hash头部,状态码: ${response.status}`, 502);
}
let decryptedHash: string;
try {
decryptedHash = generateVqdHash(hash);
} catch (decryptError) {
return errorResponse(`hash解密失败: ${decryptError.message}`, 502);
}
if (!decryptedHash || decryptedHash.trim() === "") {
return errorResponse(`hash解密结果为空`, 502);
}
setHash(decryptedHash);
return decryptedHash;
} catch (error) {
return errorResponse(`获取hash失败: ${error.message}`, 502);
}
}
// 内部发送消息方法,返回具体的错误信息
private async sendMessage(
model: string,
messages: ChatMessage[]
): Promise<{
success: boolean;
response?: Response;
error?: string;
status?: number;
}> {
const hash = await this.getVqdHash();
if (hash instanceof Response) {
return { success: false, error: "获取hash失败", status: hash.status };
}
const payload = {
model,
messages,
canUseTools: false,
canUseApproxLocation: false,
};
try {
const response = await fetch(CONFIG.DDG_CHAT_URL, {
method: "POST",
headers: {
"User-Agent": userAgent,
"x-vqd-hash-1": hash,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
if (!response.ok) {
const errorText = await response.text();
return {
success: false,
error: `上游错误: ${response.status} - ${errorText}`,
status: response.status,
};
}
return { success: true, response };
} catch (error) {
return {
success: false,
error: `请求失败: ${error.message}`,
status: 502,
};
}
}
// 带重试机制的发送消息方法 - 只对418错误重试
async sendMessageWithRetry(
model: string,
messages: ChatMessage[],
maxRetries = 1
): Promise<Response> {
let lastResult: {
success: boolean;
response?: Response;
error?: string;
status?: number;
} | null = null;
for (let attempt = 0; attempt <= maxRetries; attempt++) {
if (attempt > 0) {
setHash(""); // 重置hash,强制重新获取
}
const result = await this.sendMessage(model, messages);
if (result.success && result.response) {
return result.response;
}
lastResult = result;
// 只有418错误才重试
if (result.status === 418 || 429) {
continue;
} else {
// 其他错误直接返回,不重试
break;
}
}
// 返回最后一次的错误
return errorResponse(
lastResult?.error || "发送消息失败",
lastResult?.status || 502
);
}
}
|