anylang
Version:
A translator's kit that uses the free APIs of Google Translate, Yandex, Bing, ChatGPT, and other LLMs
110 lines (108 loc) • 14.9 kB
JavaScript
var __awaiter = (this && this.__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());
});
};
import { z } from 'zod';
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 = z
.object({
action: z.string().optional(),
type: z.string().optional(),
status: z.string().optional(),
message: 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 = z
.object({ message: z.string(), created: z.number() })
.parse(json);
texts.push(validText);
}
return texts
.sort((a, b) => a.created - b.created)
.map((i) => i.message)
.join('');
}
export 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 = 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);
});
}
}
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRyYW5zbGF0b3JzL3Vuc3RhYmxlL0R1Y2tEdWNrR29MTE1UcmFuc2xhdG9yL0R1Y2tEdWNrR29MTE1GZXRjaGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBLE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFJeEIsU0FBUyxjQUFjLENBQUMsT0FBZTtJQUN0QyxNQUFNLEtBQUssR0FHTCxFQUFFLENBQUM7SUFFVCxLQUFLLE1BQU0sSUFBSSxJQUFJLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUMxQyxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUM7UUFDeEIsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDO1lBQUUsU0FBUztRQUV2QyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN2QyxJQUFJLElBQUksS0FBSyxRQUFRO1lBQUUsTUFBTTtRQUU3QixNQUFNLElBQUksR0FBRyxDQUFDO2FBQ1osTUFBTSxDQUFDO1lBQ1AsTUFBTSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7WUFDN0IsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7WUFDM0IsTUFBTSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7WUFDN0IsT0FBTyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7U0FDOUIsQ0FBQzthQUNELEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQztRQUU5RCxtRkFBbUY7UUFDbkYsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLE9BQU8sRUFBRSxDQUFDO1lBQzdC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QU0sRUFBRSxDQUFDO1lBQ2hDLE1BQU0sUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLHlDQUF5QyxFQUFFO2dCQUN2RSxNQUFNLEVBQUUsTUFBTTtnQkFDZCxPQUFPLGtDQUNILElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxLQUN2QixNQUFNLEVBQUUsbUJBQW1CLEVBQzNCLGNBQWMsRUFBRSxrQkFBa0IsRUFDbEMsU0FBUyxFQUFFLEdBQUcsRUFDZCxRQUFRLEVBQUUsS0FBSyxHQUNmO2dCQUNELElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDO29CQUNwQixLQUFLLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLO29CQUN6QixRQUFRLEVBQUU7d0JBQ1Q7NEJBQ0MsSUFBSSxFQUFFLE1BQU07NEJBQ1osT0FBTyxFQUFFLE1BQU07eUJBQ2Y7cUJBQ0Q7aUJBQ0QsQ0FBQzthQUNGLENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ2xCLGlFQUFpRTtnQkFDakUsa0VBQWtFO2dCQUNsRSx5REFBeUQ7Z0JBQ3pELElBQUksUUFBUSxDQUFDLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQztvQkFDN0IsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUM7Z0JBQ2pCLENBQUM7Z0JBQ0QsTUFBTSxJQUFJLEtBQUssQ0FDZCw4QkFBOEIsUUFBUSxDQUFDLE1BQU0sS0FBSyxRQUFRLENBQUMsVUFBVSxFQUFFLENBQ3ZFLENBQUM7WUFDSCxDQUFDO1lBRUQsTUFBTSxZQUFZLEdBQUcsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDM0MsT0FBTyxjQUFjLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDckMsQ0FBQztLQUFBO0NBQ0QiLCJmaWxlIjoidHJhbnNsYXRvcnMvdW5zdGFibGUvRHVja0R1Y2tHb0xMTVRyYW5zbGF0b3IvRHVja0R1Y2tHb0xMTUZldGNoZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB6IH0gZnJvbSAnem9kJztcblxuaW1wb3J0IHsgTExNRmV0Y2hlciB9IGZyb20gJy4uLy4uL0xMTVRyYW5zbGF0b3JzJztcblxuZnVuY3Rpb24gcHJvY2Vzc1Jhd1RleHQocmF3VGV4dDogc3RyaW5nKSB7XG5cdGNvbnN0IHRleHRzOiB7XG5cdFx0bWVzc2FnZTogc3RyaW5nO1xuXHRcdGNyZWF0ZWQ6IG51bWJlcjtcblx0fVtdID0gW107XG5cblx0Zm9yIChjb25zdCBsaW5lIG9mIHJhd1RleHQuc3BsaXQoJ1xcblxcbicpKSB7XG5cdFx0Y29uc3QgcHJlZml4ID0gJ2RhdGE6ICc7XG5cdFx0aWYgKCFsaW5lLnN0YXJ0c1dpdGgocHJlZml4KSkgY29udGludWU7XG5cblx0XHRjb25zdCB0ZXh0ID0gbGluZS5zbGljZShwcmVmaXgubGVuZ3RoKTtcblx0XHRpZiAodGV4dCA9PT0gJ1tET05FXScpIGJyZWFrO1xuXG5cdFx0Y29uc3QganNvbiA9IHpcblx0XHRcdC5vYmplY3Qoe1xuXHRcdFx0XHRhY3Rpb246IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcblx0XHRcdFx0dHlwZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuXHRcdFx0XHRzdGF0dXM6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcblx0XHRcdFx0bWVzc2FnZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuXHRcdFx0fSlcblx0XHRcdC5wYXJzZShKU09OLnBhcnNlKHRleHQpLCB7IGVycm9yOiAoKSA9PiAnVW5leHBlY3RlZCBkYXRhJyB9KTtcblxuXHRcdC8vIEluIGNhc2Ugb2YgYW4gZXJyb3IsIER1Y2tEdWNrR28gbWF5IHJldHVybiBhIHJlc3BvbnNlIGNvbnRhaW5pbmcgYW4gZXJyb3Igb2JqZWN0XG5cdFx0aWYgKGpzb24uYWN0aW9uID09PSAnZXJyb3InKSB7XG5cdFx0XHRjb25zdCBlcnJvciA9IGBUaGUgcmVjZWl2ZWQgdGV4dCBjb250YWlucyBlcnJvciBvYmplY3Q7IGFjdGlvbjogJHtqc29uLmFjdGlvbn06IHN0YXR1czogJHtqc29uLnN0YXR1c30sIHR5cGU6ICR7anNvbi50eXBlfWA7XG5cdFx0XHRjb25zb2xlLndhcm4oZXJyb3IpO1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKGVycm9yKTtcblx0XHR9XG5cblx0XHRpZiAoanNvbi5tZXNzYWdlID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuXG5cdFx0Y29uc3QgdmFsaWRUZXh0ID0gelxuXHRcdFx0Lm9iamVjdCh7IG1lc3NhZ2U6IHouc3RyaW5nKCksIGNyZWF0ZWQ6IHoubnVtYmVyKCkgfSlcblx0XHRcdC5wYXJzZShqc29uKTtcblxuXHRcdHRleHRzLnB1c2godmFsaWRUZXh0KTtcblx0fVxuXG5cdHJldHVybiB0ZXh0c1xuXHRcdC5zb3J0KChhLCBiKSA9PiBhLmNyZWF0ZWQgLSBiLmNyZWF0ZWQpXG5cdFx0Lm1hcCgoaSkgPT4gaS5tZXNzYWdlKVxuXHRcdC5qb2luKCcnKTtcbn1cblxuZXhwb3J0IGNsYXNzIER1Y2tEdWNrR29MTE1GZXRjaGVyIGltcGxlbWVudHMgTExNRmV0Y2hlciB7XG5cdHByaXZhdGUgcmVhZG9ubHkgb3B0aW9ucztcblxuXHRjb25zdHJ1Y3RvcihvcHRpb25zPzogeyBtb2RlbD86IHN0cmluZzsgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfSkge1xuXHRcdHRoaXMub3B0aW9ucyA9IHtcblx0XHRcdG1vZGVsOiBvcHRpb25zPy5tb2RlbCA/PyAnbzMtbWluaScsXG5cdFx0XHRoZWFkZXJzOiB7XG5cdFx0XHRcdC4uLm9wdGlvbnM/LmhlYWRlcnMsXG5cdFx0XHRcdCdVc2VyLUFnZW50Jzpcblx0XHRcdFx0XHRvcHRpb25zPy5oZWFkZXJzPy5bJ1VzZXItQWdlbnQnXSB8fFxuXHRcdFx0XHRcdCdNb3ppbGxhLzUuMCAoWDExOyBMaW51eCBpNjg2OyBydjoxMjQuMCkgR2Vja28vMjAxMDAxMDEgRmlyZWZveC8xMjQuMCcsXG5cdFx0XHR9LFxuXHRcdH07XG5cdH1cblxuXHRwdWJsaWMgZ2V0TGVuZ3RoTGltaXQgPSAoKSA9PiAyMzAwO1xuXHRwdWJsaWMgZ2V0UmVxdWVzdHNUaW1lb3V0ID0gKCkgPT4gMjAwMDtcblxuXHRwcml2YXRlIGtleTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cdHB1YmxpYyBhc3luYyBnZXRLZXkoKSB7XG5cdFx0aWYgKCF0aGlzLmtleSkge1xuXHRcdFx0Y29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgnaHR0cHM6Ly9kdWNrZHVja2dvLmNvbS9kdWNrY2hhdC92MS9zdGF0dXMnLCB7XG5cdFx0XHRcdGhlYWRlcnM6IHtcblx0XHRcdFx0XHQuLi50aGlzLm9wdGlvbnMuaGVhZGVycyxcblx0XHRcdFx0XHRBY2NlcHQ6ICcqLyonLFxuXHRcdFx0XHRcdCd4LXZxZC1hY2NlcHQnOiAnMScsXG5cdFx0XHRcdFx0UHJpb3JpdHk6ICd1PTQnLFxuXHRcdFx0XHRcdFByYWdtYTogJ25vLWNhY2hlJyxcblx0XHRcdFx0fSxcblx0XHRcdH0pO1xuXHRcdFx0aWYgKCFyZXNwb25zZS5vaykge1xuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoXG5cdFx0XHRcdFx0YFJlcXVlc3QgZmFpbGVkIHdpdGggc3RhdHVzICR7cmVzcG9uc2Uuc3RhdHVzfTogJHtyZXNwb25zZS5zdGF0dXNUZXh0fWAsXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGV4dHJhY3Qga2V5XG5cdFx0XHRjb25zdCBrZXkgPSByZXNwb25zZS5oZWFkZXJzLmdldCgneC12cWQtNCcpO1xuXHRcdFx0Y29uc3QgdmFsaWRLZXkgPSB6XG5cdFx0XHRcdC5zdHJpbmcoKVxuXHRcdFx0XHQubWluKDEsIHsgbWVzc2FnZTogXCJIZWFkZXIgJ3gtdnFkLTQnIGlzIG1pc3Npbmcgb3IgZW1wdHlcIiB9KVxuXHRcdFx0XHQucGFyc2Uoa2V5KTtcblxuXHRcdFx0dGhpcy5rZXkgPSB2YWxpZEtleTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMua2V5O1xuXHR9XG5cblx0cHVibGljIGFzeW5jIGZldGNoKHByb21wdDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcblx0XHRjb25zdCBrZXkgPSBhd2FpdCB0aGlzLmdldEtleSgpO1xuXHRcdGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJ2h0dHBzOi8vZHVja2R1Y2tnby5jb20vZHVja2NoYXQvdjEvY2hhdCcsIHtcblx0XHRcdG1ldGhvZDogJ1BPU1QnLFxuXHRcdFx0aGVhZGVyczoge1xuXHRcdFx0XHQuLi50aGlzLm9wdGlvbnMuaGVhZGVycyxcblx0XHRcdFx0QWNjZXB0OiAndGV4dC9ldmVudC1zdHJlYW0nLFxuXHRcdFx0XHQnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuXHRcdFx0XHQnWC1WcWQtNCc6IGtleSxcblx0XHRcdFx0UHJpb3JpdHk6ICd1PTQnLFxuXHRcdFx0fSxcblx0XHRcdGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcblx0XHRcdFx0bW9kZWw6IHRoaXMub3B0aW9ucy5tb2RlbCxcblx0XHRcdFx0bWVzc2FnZXM6IFtcblx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHRyb2xlOiAndXNlcicsXG5cdFx0XHRcdFx0XHRjb250ZW50OiBwcm9tcHQsXG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XSxcblx0XHRcdH0pLFxuXHRcdH0pO1xuXG5cdFx0aWYgKCFyZXNwb25zZS5vaykge1xuXHRcdFx0Ly8gd2hlbiB0aGUga2V5IGlzIG5vdCB2YWxpZCBvciBkZXByZWNhdGVkIHNlcnZlciBzZW5kIDQwMCBzdGF0dXNcblx0XHRcdC8vIFRoaXMgaXMgbm90IGEgc3BlY2lmaWMgc3RhdHVzLCBidXQgd2UgY2FuIHRyeSByZWxvYWRpbmcgdGhlIGtleVxuXHRcdFx0Ly8gSW4gdGhlIG5leHQgbWV0aG9kIGNhbGwsIGEgbmV3IGtleSBpcyB3aWxsIGJlIHJlcXVpcmVkXG5cdFx0XHRpZiAocmVzcG9uc2Uuc3RhdHVzID09PSA0MDApIHtcblx0XHRcdFx0dGhpcy5rZXkgPSBudWxsO1xuXHRcdFx0fVxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFxuXHRcdFx0XHRgUmVxdWVzdCBmYWlsZWQgd2l0aCBzdGF0dXMgJHtyZXNwb25zZS5zdGF0dXN9OiAke3Jlc3BvbnNlLnN0YXR1c1RleHR9YCxcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0Y29uc3QgcmVzcG9uc2VUZXh0ID0gYXdhaXQgcmVzcG9uc2UudGV4dCgpO1xuXHRcdHJldHVybiBwcm9jZXNzUmF3VGV4dChyZXNwb25zZVRleHQpO1xuXHR9XG59XG4iXX0=