anylang
Version:
A translator's kit that uses the free APIs of Google Translate, Yandex, Bing, ChatGPT, and other LLMs
137 lines (135 loc) • 15.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.DuckDuckGoLLMFetcher = void 0;
var _zod = require("zod");
var __awaiter = void 0 && (void 0).__awaiter || function (thisArg, _arguments, P, generator) {
function adopt(value) {
return value instanceof P ? value : new P(function (resolve) {
resolve(value);
});
}
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
}
}
function step(result) {
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
}
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
function processRawText(rawText) {
const texts = [];
for (const line of rawText.split('\n\n')) {
const prefix = 'data: ';
if (!line.startsWith(prefix)) continue;
const text = line.slice(prefix.length);
if (text === '[DONE]') break;
const json = _zod.z.object({
action: _zod.z.string().optional(),
type: _zod.z.string().optional(),
status: _zod.z.string().optional(),
message: _zod.z.string().optional()
}).parse(JSON.parse(text), {
error: () => 'Unexpected data'
});
// In case of an error, DuckDuckGo may return a response containing an error object
if (json.action === 'error') {
const error = `The received text contains error object; action: ${json.action}: status: ${json.status}, type: ${json.type}`;
console.warn(error);
throw new Error(error);
}
if (json.message === undefined) continue;
const validText = _zod.z.object({
message: _zod.z.string(),
created: _zod.z.number()
}).parse(json);
texts.push(validText);
}
return texts.sort((a, b) => a.created - b.created).map(i => i.message).join('');
}
class DuckDuckGoLLMFetcher {
constructor(options) {
var _a, _b;
this.getLengthLimit = () => 2300;
this.getRequestsTimeout = () => 2000;
this.key = null;
this.options = {
model: (_a = options === null || options === void 0 ? void 0 : options.model) !== null && _a !== void 0 ? _a : 'o3-mini',
headers: Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.headers), {
'User-Agent': ((_b = options === null || options === void 0 ? void 0 : options.headers) === null || _b === void 0 ? void 0 : _b['User-Agent']) || 'Mozilla/5.0 (X11; Linux i686; rv:124.0) Gecko/20100101 Firefox/124.0'
})
};
}
getKey() {
return __awaiter(this, void 0, void 0, function* () {
if (!this.key) {
const response = yield fetch('https://duckduckgo.com/duckchat/v1/status', {
headers: Object.assign(Object.assign({}, this.options.headers), {
Accept: '*/*',
'x-vqd-accept': '1',
Priority: 'u=4',
Pragma: 'no-cache'
})
});
if (!response.ok) {
throw new Error(`Request failed with status ${response.status}: ${response.statusText}`);
}
// extract key
const key = response.headers.get('x-vqd-4');
const validKey = _zod.z.string().min(1, {
message: "Header 'x-vqd-4' is missing or empty"
}).parse(key);
this.key = validKey;
}
return this.key;
});
}
fetch(prompt) {
return __awaiter(this, void 0, void 0, function* () {
const key = yield this.getKey();
const response = yield fetch('https://duckduckgo.com/duckchat/v1/chat', {
method: 'POST',
headers: Object.assign(Object.assign({}, this.options.headers), {
Accept: 'text/event-stream',
'Content-Type': 'application/json',
'X-Vqd-4': key,
Priority: 'u=4'
}),
body: JSON.stringify({
model: this.options.model,
messages: [{
role: 'user',
content: prompt
}]
})
});
if (!response.ok) {
// when the key is not valid or deprecated server send 400 status
// This is not a specific status, but we can try reloading the key
// In the next method call, a new key is will be required
if (response.status === 400) {
this.key = null;
}
throw new Error(`Request failed with status ${response.status}: ${response.statusText}`);
}
const responseText = yield response.text();
return processRawText(responseText);
});
}
}
exports.DuckDuckGoLLMFetcher = DuckDuckGoLLMFetcher;
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRvcnMvdW5zdGFibGUvRHVja0R1Y2tHb0xMTVRyYW5zbGF0b3IvRHVja0R1Y2tHb0xMTUZldGNoZXIuanMiLCJuYW1lcyI6WyJfem9kIiwicmVxdWlyZSIsInByb2Nlc3NSYXdUZXh0IiwicmF3VGV4dCIsInRleHRzIiwibGluZSIsInNwbGl0IiwicHJlZml4Iiwic3RhcnRzV2l0aCIsInRleHQiLCJzbGljZSIsImxlbmd0aCIsImpzb24iLCJ6Iiwib2JqZWN0IiwiYWN0aW9uIiwic3RyaW5nIiwib3B0aW9uYWwiLCJ0eXBlIiwic3RhdHVzIiwibWVzc2FnZSIsInBhcnNlIiwiSlNPTiIsImVycm9yIiwiY29uc29sZSIsIndhcm4iLCJFcnJvciIsInVuZGVmaW5lZCIsInZhbGlkVGV4dCIsImNyZWF0ZWQiLCJudW1iZXIiLCJwdXNoIiwic29ydCIsImEiLCJiIiwibWFwIiwiaSIsImpvaW4iLCJEdWNrRHVja0dvTExNRmV0Y2hlciIsImNvbnN0cnVjdG9yIiwib3B0aW9ucyIsImdldExlbmd0aExpbWl0IiwiZ2V0UmVxdWVzdHNUaW1lb3V0Iiwia2V5IiwibW9kZWwiLCJfYSIsImhlYWRlcnMiLCJPYmplY3QiLCJhc3NpZ24iLCJfYiIsImdldEtleSIsInJlc3BvbnNlIiwiZmV0Y2giLCJBY2NlcHQiLCJQcmlvcml0eSIsIlByYWdtYSIsIm9rIiwic3RhdHVzVGV4dCIsImdldCIsInZhbGlkS2V5IiwibWluIiwicHJvbXB0IiwibWV0aG9kIiwiYm9keSIsInN0cmluZ2lmeSIsIm1lc3NhZ2VzIiwicm9sZSIsImNvbnRlbnQiLCJyZXNwb25zZVRleHQiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsidHJhbnNsYXRvcnMvdW5zdGFibGUvRHVja0R1Y2tHb0xMTVRyYW5zbGF0b3IvRHVja0R1Y2tHb0xMTUZldGNoZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgeiB9IGZyb20gJ3pvZCc7XG5cbmltcG9ydCB7IExMTUZldGNoZXIgfSBmcm9tICcuLi8uLi9MTE1UcmFuc2xhdG9ycyc7XG5cbmZ1bmN0aW9uIHByb2Nlc3NSYXdUZXh0KHJhd1RleHQ6IHN0cmluZykge1xuXHRjb25zdCB0ZXh0czoge1xuXHRcdG1lc3NhZ2U6IHN0cmluZztcblx0XHRjcmVhdGVkOiBudW1iZXI7XG5cdH1bXSA9IFtdO1xuXG5cdGZvciAoY29uc3QgbGluZSBvZiByYXdUZXh0LnNwbGl0KCdcXG5cXG4nKSkge1xuXHRcdGNvbnN0IHByZWZpeCA9ICdkYXRhOiAnO1xuXHRcdGlmICghbGluZS5zdGFydHNXaXRoKHByZWZpeCkpIGNvbnRpbnVlO1xuXG5cdFx0Y29uc3QgdGV4dCA9IGxpbmUuc2xpY2UocHJlZml4Lmxlbmd0aCk7XG5cdFx0aWYgKHRleHQgPT09ICdbRE9ORV0nKSBicmVhaztcblxuXHRcdGNvbnN0IGpzb24gPSB6XG5cdFx0XHQub2JqZWN0KHtcblx0XHRcdFx0YWN0aW9uOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG5cdFx0XHRcdHR5cGU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcblx0XHRcdFx0c3RhdHVzOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG5cdFx0XHRcdG1lc3NhZ2U6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcblx0XHRcdH0pXG5cdFx0XHQucGFyc2UoSlNPTi5wYXJzZSh0ZXh0KSwgeyBlcnJvcjogKCkgPT4gJ1VuZXhwZWN0ZWQgZGF0YScgfSk7XG5cblx0XHQvLyBJbiBjYXNlIG9mIGFuIGVycm9yLCBEdWNrRHVja0dvIG1heSByZXR1cm4gYSByZXNwb25zZSBjb250YWluaW5nIGFuIGVycm9yIG9iamVjdFxuXHRcdGlmIChqc29uLmFjdGlvbiA9PT0gJ2Vycm9yJykge1xuXHRcdFx0Y29uc3QgZXJyb3IgPSBgVGhlIHJlY2VpdmVkIHRleHQgY29udGFpbnMgZXJyb3Igb2JqZWN0OyBhY3Rpb246ICR7anNvbi5hY3Rpb259OiBzdGF0dXM6ICR7anNvbi5zdGF0dXN9LCB0eXBlOiAke2pzb24udHlwZX1gO1xuXHRcdFx0Y29uc29sZS53YXJuKGVycm9yKTtcblx0XHRcdHRocm93IG5ldyBFcnJvcihlcnJvcik7XG5cdFx0fVxuXG5cdFx0aWYgKGpzb24ubWVzc2FnZSA9PT0gdW5kZWZpbmVkKSBjb250aW51ZTtcblxuXHRcdGNvbnN0IHZhbGlkVGV4dCA9IHpcblx0XHRcdC5vYmplY3QoeyBtZXNzYWdlOiB6LnN0cmluZygpLCBjcmVhdGVkOiB6Lm51bWJlcigpIH0pXG5cdFx0XHQucGFyc2UoanNvbik7XG5cblx0XHR0ZXh0cy5wdXNoKHZhbGlkVGV4dCk7XG5cdH1cblxuXHRyZXR1cm4gdGV4dHNcblx0XHQuc29ydCgoYSwgYikgPT4gYS5jcmVhdGVkIC0gYi5jcmVhdGVkKVxuXHRcdC5tYXAoKGkpID0+IGkubWVzc2FnZSlcblx0XHQuam9pbignJyk7XG59XG5cbmV4cG9ydCBjbGFzcyBEdWNrRHVja0dvTExNRmV0Y2hlciBpbXBsZW1lbnRzIExMTUZldGNoZXIge1xuXHRwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM7XG5cblx0Y29uc3RydWN0b3Iob3B0aW9ucz86IHsgbW9kZWw/OiBzdHJpbmc7IGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IH0pIHtcblx0XHR0aGlzLm9wdGlvbnMgPSB7XG5cdFx0XHRtb2RlbDogb3B0aW9ucz8ubW9kZWwgPz8gJ28zLW1pbmknLFxuXHRcdFx0aGVhZGVyczoge1xuXHRcdFx0XHQuLi5vcHRpb25zPy5oZWFkZXJzLFxuXHRcdFx0XHQnVXNlci1BZ2VudCc6XG5cdFx0XHRcdFx0b3B0aW9ucz8uaGVhZGVycz8uWydVc2VyLUFnZW50J10gfHxcblx0XHRcdFx0XHQnTW96aWxsYS81LjAgKFgxMTsgTGludXggaTY4NjsgcnY6MTI0LjApIEdlY2tvLzIwMTAwMTAxIEZpcmVmb3gvMTI0LjAnLFxuXHRcdFx0fSxcblx0XHR9O1xuXHR9XG5cblx0cHVibGljIGdldExlbmd0aExpbWl0ID0gKCkgPT4gMjMwMDtcblx0cHVibGljIGdldFJlcXVlc3RzVGltZW91dCA9ICgpID0+IDIwMDA7XG5cblx0cHJpdmF0ZSBrZXk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXHRwdWJsaWMgYXN5bmMgZ2V0S2V5KCkge1xuXHRcdGlmICghdGhpcy5rZXkpIHtcblx0XHRcdGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJ2h0dHBzOi8vZHVja2R1Y2tnby5jb20vZHVja2NoYXQvdjEvc3RhdHVzJywge1xuXHRcdFx0XHRoZWFkZXJzOiB7XG5cdFx0XHRcdFx0Li4udGhpcy5vcHRpb25zLmhlYWRlcnMsXG5cdFx0XHRcdFx0QWNjZXB0OiAnKi8qJyxcblx0XHRcdFx0XHQneC12cWQtYWNjZXB0JzogJzEnLFxuXHRcdFx0XHRcdFByaW9yaXR5OiAndT00Jyxcblx0XHRcdFx0XHRQcmFnbWE6ICduby1jYWNoZScsXG5cdFx0XHRcdH0sXG5cdFx0XHR9KTtcblx0XHRcdGlmICghcmVzcG9uc2Uub2spIHtcblx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKFxuXHRcdFx0XHRcdGBSZXF1ZXN0IGZhaWxlZCB3aXRoIHN0YXR1cyAke3Jlc3BvbnNlLnN0YXR1c306ICR7cmVzcG9uc2Uuc3RhdHVzVGV4dH1gLFxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBleHRyYWN0IGtleVxuXHRcdFx0Y29uc3Qga2V5ID0gcmVzcG9uc2UuaGVhZGVycy5nZXQoJ3gtdnFkLTQnKTtcblx0XHRcdGNvbnN0IHZhbGlkS2V5ID0gelxuXHRcdFx0XHQuc3RyaW5nKClcblx0XHRcdFx0Lm1pbigxLCB7IG1lc3NhZ2U6IFwiSGVhZGVyICd4LXZxZC00JyBpcyBtaXNzaW5nIG9yIGVtcHR5XCIgfSlcblx0XHRcdFx0LnBhcnNlKGtleSk7XG5cblx0XHRcdHRoaXMua2V5ID0gdmFsaWRLZXk7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmtleTtcblx0fVxuXG5cdHB1YmxpYyBhc3luYyBmZXRjaChwcm9tcHQ6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG5cdFx0Y29uc3Qga2V5ID0gYXdhaXQgdGhpcy5nZXRLZXkoKTtcblx0XHRjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCdodHRwczovL2R1Y2tkdWNrZ28uY29tL2R1Y2tjaGF0L3YxL2NoYXQnLCB7XG5cdFx0XHRtZXRob2Q6ICdQT1NUJyxcblx0XHRcdGhlYWRlcnM6IHtcblx0XHRcdFx0Li4udGhpcy5vcHRpb25zLmhlYWRlcnMsXG5cdFx0XHRcdEFjY2VwdDogJ3RleHQvZXZlbnQtc3RyZWFtJyxcblx0XHRcdFx0J0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcblx0XHRcdFx0J1gtVnFkLTQnOiBrZXksXG5cdFx0XHRcdFByaW9yaXR5OiAndT00Jyxcblx0XHRcdH0sXG5cdFx0XHRib2R5OiBKU09OLnN0cmluZ2lmeSh7XG5cdFx0XHRcdG1vZGVsOiB0aGlzLm9wdGlvbnMubW9kZWwsXG5cdFx0XHRcdG1lc3NhZ2VzOiBbXG5cdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0cm9sZTogJ3VzZXInLFxuXHRcdFx0XHRcdFx0Y29udGVudDogcHJvbXB0LFxuXHRcdFx0XHRcdH0sXG5cdFx0XHRcdF0sXG5cdFx0XHR9KSxcblx0XHR9KTtcblxuXHRcdGlmICghcmVzcG9uc2Uub2spIHtcblx0XHRcdC8vIHdoZW4gdGhlIGtleSBpcyBub3QgdmFsaWQgb3IgZGVwcmVjYXRlZCBzZXJ2ZXIgc2VuZCA0MDAgc3RhdHVzXG5cdFx0XHQvLyBUaGlzIGlzIG5vdCBhIHNwZWNpZmljIHN0YXR1cywgYnV0IHdlIGNhbiB0cnkgcmVsb2FkaW5nIHRoZSBrZXlcblx0XHRcdC8vIEluIHRoZSBuZXh0IG1ldGhvZCBjYWxsLCBhIG5ldyBrZXkgaXMgd2lsbCBiZSByZXF1aXJlZFxuXHRcdFx0aWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gNDAwKSB7XG5cdFx0XHRcdHRoaXMua2V5ID0gbnVsbDtcblx0XHRcdH1cblx0XHRcdHRocm93IG5ldyBFcnJvcihcblx0XHRcdFx0YFJlcXVlc3QgZmFpbGVkIHdpdGggc3RhdHVzICR7cmVzcG9uc2Uuc3RhdHVzfTogJHtyZXNwb25zZS5zdGF0dXNUZXh0fWAsXG5cdFx0XHQpO1xuXHRcdH1cblxuXHRcdGNvbnN0IHJlc3BvbnNlVGV4dCA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKTtcblx0XHRyZXR1cm4gcHJvY2Vzc1Jhd1RleHQocmVzcG9uc2VUZXh0KTtcblx0fVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFBQSxJQUFBLEdBQUFDLE9BQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFJQSxTQUFTQyxjQUFjQSxDQUFDQyxPQUFlO0VBQ3RDLE1BQU1DLEtBQUssR0FHTCxFQUFFO0VBRVIsS0FBSyxNQUFNQyxJQUFJLElBQUlGLE9BQU8sQ0FBQ0csS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFO0lBQ3pDLE1BQU1DLE1BQU0sR0FBRyxRQUFRO0lBQ3ZCLElBQUksQ0FBQ0YsSUFBSSxDQUFDRyxVQUFVLENBQUNELE1BQU0sQ0FBQyxFQUFFO0lBRTlCLE1BQU1FLElBQUksR0FBR0osSUFBSSxDQUFDSyxLQUFLLENBQUNILE1BQU0sQ0FBQ0ksTUFBTSxDQUFDO0lBQ3RDLElBQUlGLElBQUksS0FBSyxRQUFRLEVBQUU7SUFFdkIsTUFBTUcsSUFBSSxHQUFHQyxNQUFDLENBQ1pDLE1BQU0sQ0FBQztNQUNQQyxNQUFNLEVBQUVGLE1BQUMsQ0FBQ0csTUFBTSxFQUFFLENBQUNDLFFBQVEsRUFBRTtNQUM3QkMsSUFBSSxFQUFFTCxNQUFDLENBQUNHLE1BQU0sRUFBRSxDQUFDQyxRQUFRLEVBQUU7TUFDM0JFLE1BQU0sRUFBRU4sTUFBQyxDQUFDRyxNQUFNLEVBQUUsQ0FBQ0MsUUFBUSxFQUFFO01BQzdCRyxPQUFPLEVBQUVQLE1BQUMsQ0FBQ0csTUFBTSxFQUFFLENBQUNDLFFBQVE7S0FDNUIsQ0FBQyxDQUNESSxLQUFLLENBQUNDLElBQUksQ0FBQ0QsS0FBSyxDQUFDWixJQUFJLENBQUMsRUFBRTtNQUFFYyxLQUFLLEVBQUVBLENBQUEsS0FBTTtJQUFpQixDQUFFLENBQUM7SUFFN0Q7SUFDQSxJQUFJWCxJ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