@gringow/gringow 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +279 -43
- package/dist/config.d.mts +7 -8
- package/dist/config.mjs +32 -20
- package/dist/config.test.mjs +39 -25
- package/dist/constants/default-config.mjs +4 -3
- package/dist/data/check-cache.mjs +33 -63
- package/dist/data/clear-cache.mjs +32 -20
- package/dist/data/create-cache-dir.mjs +32 -20
- package/dist/data/delete-cache-item.mjs +32 -20
- package/dist/data/get-cache.mjs +32 -20
- package/dist/data/get-or-create-cache.mjs +32 -20
- package/dist/data/save-cache.mjs +32 -20
- package/dist/data/write-cache-to-disk.mjs +32 -20
- package/dist/gringow.mjs +84 -491
- package/dist/index.mjs +84 -491
- package/dist/io/ask-llm.d.mts +3 -1
- package/dist/io/ask-llm.mjs +77 -449
- package/dist/schemas/config.shcema.d.mts +40 -47
- package/dist/schemas/config.shcema.mjs +26 -15
- package/dist/types/index.d.mts +3 -25
- package/gringow.config.js.example +2 -4
- package/gringow.config.json.example +4 -2
- package/package.json +2 -5
- package/dist/io/anthropic/ask.d.mts +0 -11
- package/dist/io/anthropic/ask.mjs +0 -190
- package/dist/io/anthropic/commit-response.d.mts +0 -21
- package/dist/io/anthropic/commit-response.mjs +0 -10
- package/dist/io/anthropic/index.d.mts +0 -14
- package/dist/io/anthropic/index.mjs +0 -208
- package/dist/io/anthropic/parse.d.mts +0 -20
- package/dist/io/anthropic/parse.mjs +0 -10
- package/dist/io/gemini/ask.d.mts +0 -11
- package/dist/io/gemini/ask.mjs +0 -232
- package/dist/io/gemini/commit-response.d.mts +0 -11
- package/dist/io/gemini/commit-response.mjs +0 -7
- package/dist/io/gemini/index.d.mts +0 -14
- package/dist/io/gemini/index.mjs +0 -248
- package/dist/io/gemini/parse.d.mts +0 -20
- package/dist/io/gemini/parse.mjs +0 -11
- package/dist/io/huggingface/ask.d.mts +0 -13
- package/dist/io/huggingface/ask.mjs +0 -405
- package/dist/io/huggingface/commit-response.d.mts +0 -39
- package/dist/io/huggingface/commit-response.mjs +0 -14
- package/dist/io/huggingface/index.d.mts +0 -13
- package/dist/io/huggingface/index.mjs +0 -426
- package/dist/io/huggingface/languages-map.d.mts +0 -191
- package/dist/io/huggingface/languages-map.mjs +0 -187
- package/dist/io/huggingface/parse.d.mts +0 -20
- package/dist/io/huggingface/parse.mjs +0 -9
package/dist/io/ask-llm.mjs
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
+
import { igniteEngine, Message } from 'multi-llm-ts';
|
|
1
2
|
import { cosmiconfig } from 'cosmiconfig';
|
|
2
3
|
import merge from 'lodash.merge';
|
|
3
4
|
import { z } from 'zod';
|
|
4
|
-
import Anthropic from '@anthropic-ai/sdk';
|
|
5
|
-
import { GoogleGenerativeAI } from '@google/generative-ai';
|
|
6
|
-
import { env, pipeline } from '@huggingface/transformers';
|
|
7
|
-
import 'fs';
|
|
8
5
|
|
|
9
|
-
// src/
|
|
6
|
+
// src/io/ask-llm.ts
|
|
10
7
|
|
|
11
8
|
// src/constants/default-config.ts
|
|
12
9
|
var defaultConfig = {
|
|
@@ -20,19 +17,34 @@ var defaultConfig = {
|
|
|
20
17
|
prefix: "grw",
|
|
21
18
|
write: true
|
|
22
19
|
},
|
|
23
|
-
keys: {},
|
|
24
20
|
sourceLanguage: "en-US",
|
|
21
|
+
defaultLanguage: "pt-BR",
|
|
25
22
|
languages: ["pt-BR", "fr-CA"],
|
|
26
23
|
llm: {
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
provider: "openai",
|
|
25
|
+
apiKey: void 0,
|
|
26
|
+
model: "gpt-4o-mini",
|
|
29
27
|
temperature: 1,
|
|
30
28
|
sleep: 0
|
|
31
29
|
},
|
|
32
30
|
globby: "./src/**/*.{js,jsx,ts,tsx}"
|
|
33
31
|
};
|
|
34
32
|
var languageSchema = z.string().regex(/^[a-z]{2,3}(-[A-Z]{2})?$/);
|
|
35
|
-
var
|
|
33
|
+
var llmProviderSchema = z.enum([
|
|
34
|
+
"anthropic",
|
|
35
|
+
"gemini",
|
|
36
|
+
"openai",
|
|
37
|
+
"groq",
|
|
38
|
+
"mistral",
|
|
39
|
+
"ollama",
|
|
40
|
+
"xai",
|
|
41
|
+
"deepseek",
|
|
42
|
+
"openrouter",
|
|
43
|
+
"cerebras",
|
|
44
|
+
"lmstudio",
|
|
45
|
+
"azure",
|
|
46
|
+
"meta"
|
|
47
|
+
]);
|
|
36
48
|
var configSchema = z.object({
|
|
37
49
|
debug: z.boolean().optional(),
|
|
38
50
|
log: z.object({
|
|
@@ -44,14 +56,13 @@ var configSchema = z.object({
|
|
|
44
56
|
prefix: z.string(),
|
|
45
57
|
write: z.boolean().optional()
|
|
46
58
|
}),
|
|
47
|
-
keys: z.object({
|
|
48
|
-
anthropicApiKey: z.string().optional(),
|
|
49
|
-
geminiApiKey: z.string().optional()
|
|
50
|
-
}),
|
|
51
59
|
sourceLanguage: languageSchema,
|
|
60
|
+
defaultLanguage: languageSchema,
|
|
52
61
|
languages: z.array(languageSchema),
|
|
53
62
|
llm: z.object({
|
|
54
|
-
|
|
63
|
+
provider: llmProviderSchema,
|
|
64
|
+
apiKey: z.string().optional(),
|
|
65
|
+
baseURL: z.string().optional(),
|
|
55
66
|
model: z.string().nullable(),
|
|
56
67
|
temperature: z.number().optional(),
|
|
57
68
|
sleep: z.number().optional(),
|
|
@@ -65,17 +76,15 @@ var configSchema = z.object({
|
|
|
65
76
|
globby: z.string().regex(/^\.\/.*/).optional()
|
|
66
77
|
}).refine(
|
|
67
78
|
(data) => {
|
|
68
|
-
|
|
69
|
-
|
|
79
|
+
const noApiKeyRequired = ["ollama", "lmstudio"];
|
|
80
|
+
if (noApiKeyRequired.includes(data.llm.provider)) {
|
|
81
|
+
return true;
|
|
70
82
|
}
|
|
71
|
-
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
return true;
|
|
83
|
+
return !!data.llm.apiKey;
|
|
75
84
|
},
|
|
76
85
|
{
|
|
77
|
-
message: "The API key
|
|
78
|
-
path: ["
|
|
86
|
+
message: "The API key must be present in llm.apiKey for the chosen provider.",
|
|
87
|
+
path: ["llm", "apiKey"]
|
|
79
88
|
}
|
|
80
89
|
);
|
|
81
90
|
|
|
@@ -111,7 +120,7 @@ Your task is to translate a given text and output **only one valid JSON object**
|
|
|
111
120
|
|
|
112
121
|
Follow these rules strictly:
|
|
113
122
|
|
|
114
|
-
1. The original text is written in English.
|
|
123
|
+
1. The original text is written in English or Spanish.
|
|
115
124
|
2. You will receive additional user parameters under the variable 'extraInstructions'. These may specify tone, persona, style, context, or any relevant translation guideline.
|
|
116
125
|
- Examples: \u201Ctranslate as if you were a Shakespearean narrator\u201D or \u201Cuse a formal business tone suitable for a corporate presentation.\u201D
|
|
117
126
|
- Apply these creatively but **without altering the meaning or punctuation** of the original text.
|
|
@@ -144,10 +153,10 @@ Translate the following text faithfully:
|
|
|
144
153
|
function defaultPostPrompt(_config) {
|
|
145
154
|
return "";
|
|
146
155
|
}
|
|
147
|
-
function prePrompt(config,
|
|
156
|
+
function prePrompt(config, prepend, replace) {
|
|
148
157
|
return [
|
|
149
158
|
// ...(append ? ['[SPECIFIC_INPUTS]', String(append), '[/SPECIFIC_INPUTS]'] : []),
|
|
150
|
-
replace ? String(replace) : defaultPrePrompt(config,
|
|
159
|
+
replace ? String(replace) : defaultPrePrompt(config, prepend)
|
|
151
160
|
].join(" ").trim();
|
|
152
161
|
}
|
|
153
162
|
function postPrompt(config, prepend, replace) {
|
|
@@ -156,445 +165,64 @@ function postPrompt(config, prepend, replace) {
|
|
|
156
165
|
replace ? String(replace) : defaultPostPrompt()
|
|
157
166
|
].join(" ").trim();
|
|
158
167
|
}
|
|
159
|
-
async function askAnthropic(prompt, prePrompt2, postPrompt2) {
|
|
160
|
-
const config = await awaitedConfig;
|
|
161
|
-
if (Number(config.llm.sleep)) {
|
|
162
|
-
await new Promise((resolve) => setTimeout(resolve, config.llm.sleep ?? 1));
|
|
163
|
-
}
|
|
164
|
-
if (!config.keys.anthropicApiKey) {
|
|
165
|
-
throw new Error("Anthropic API key is not set in the config");
|
|
166
|
-
}
|
|
167
|
-
const anthropic = new Anthropic({
|
|
168
|
-
apiKey: config.keys.anthropicApiKey,
|
|
169
|
-
dangerouslyAllowBrowser: true
|
|
170
|
-
});
|
|
171
|
-
const fullPrompt = String(`${prePrompt2}
|
|
172
168
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
function commitResponseAnthropic(response) {
|
|
193
|
-
const result2 = response.content.reduce((acc, item) => {
|
|
194
|
-
const nextAcc = acc + (item.type === "text" ? item.text : "");
|
|
195
|
-
return nextAcc;
|
|
196
|
-
}, "");
|
|
197
|
-
return result2;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// src/io/anthropic/parse.ts
|
|
201
|
-
function parseAnthropic(unparsed) {
|
|
202
|
-
if (typeof unparsed !== "string") {
|
|
203
|
-
throw new Error("CommitResponse should be a string here.");
|
|
204
|
-
}
|
|
205
|
-
const parsed = JSON.parse(unparsed);
|
|
169
|
+
// src/io/ask-llm.ts
|
|
170
|
+
var providerEngineMap = {
|
|
171
|
+
anthropic: "anthropic",
|
|
172
|
+
gemini: "google",
|
|
173
|
+
openai: "openai",
|
|
174
|
+
groq: "groq",
|
|
175
|
+
mistral: "mistralai",
|
|
176
|
+
ollama: "ollama",
|
|
177
|
+
xai: "xai",
|
|
178
|
+
deepseek: "deepseek",
|
|
179
|
+
openrouter: "openrouter",
|
|
180
|
+
cerebras: "cerebras",
|
|
181
|
+
lmstudio: "lmstudio",
|
|
182
|
+
azure: "azure",
|
|
183
|
+
meta: "meta"
|
|
184
|
+
};
|
|
185
|
+
function parseResponse(responseText) {
|
|
186
|
+
const cleaned = responseText.replace(/```json/g, "").replace(/```/g, "").trim();
|
|
187
|
+
const parsed = JSON.parse(cleaned);
|
|
206
188
|
return parsed;
|
|
207
189
|
}
|
|
208
|
-
async function
|
|
209
|
-
try {
|
|
210
|
-
if (!config.keys.geminiApiKey) {
|
|
211
|
-
throw new Error("Gemini API key is not set in the config");
|
|
212
|
-
}
|
|
213
|
-
const generativeAIClient = new GoogleGenerativeAI(config.keys.geminiApiKey);
|
|
214
|
-
const model = generativeAIClient.getGenerativeModel({
|
|
215
|
-
model: config.llm.model,
|
|
216
|
-
generationConfig: {
|
|
217
|
-
temperature: config.llm.temperature ?? 0.8
|
|
218
|
-
}
|
|
219
|
-
});
|
|
220
|
-
if (config.debug) {
|
|
221
|
-
console.log("Gemini model prompt:", JSON.stringify({ prompt }));
|
|
222
|
-
}
|
|
223
|
-
const response = await model.generateContent([prompt]);
|
|
224
|
-
return response;
|
|
225
|
-
} catch (err) {
|
|
226
|
-
const error = err;
|
|
227
|
-
console.log("Error details from Gemini model", JSON.stringify({ error }, null, 2));
|
|
228
|
-
const retryDelay = error?.errorDetails?.find(
|
|
229
|
-
(detail) => detail?.["@type"] === "type.googleapis.com/google.rpc.RetryInfo"
|
|
230
|
-
)?.retryDelay ?? void 0;
|
|
231
|
-
if (error.status === 429 && retryDelay !== void 0) {
|
|
232
|
-
const sleepTime = config.llm.sleep ?? 3;
|
|
233
|
-
console.warn(
|
|
234
|
-
`Rate limit exceeded when generating response from Gemini model, retrying in... ${retryDelay} + ${sleepTime / 1e3}s`
|
|
235
|
-
);
|
|
236
|
-
await new Promise((resolve) => setTimeout(resolve, (parseInt(retryDelay, 10) + sleepTime / 1e3) * 1e3));
|
|
237
|
-
return generateResponse(prompt, config);
|
|
238
|
-
}
|
|
239
|
-
console.error("Error generating response from Gemini model", { error });
|
|
240
|
-
throw error;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
async function askGemini(prompt, prePrompt2, postPrompt2) {
|
|
190
|
+
async function askLLM(prompt, prePrompt2, postPrompt2) {
|
|
244
191
|
const config = await awaitedConfig;
|
|
245
|
-
|
|
246
|
-
|
|
192
|
+
const provider = config.llm.provider;
|
|
193
|
+
const engineName = providerEngineMap[provider];
|
|
194
|
+
if (!engineName) {
|
|
195
|
+
throw new Error(`Unknown LLM provider: ${provider}`);
|
|
247
196
|
}
|
|
248
|
-
if (!config.
|
|
249
|
-
throw new Error(
|
|
197
|
+
if (!config.llm.apiKey) {
|
|
198
|
+
throw new Error(`API key for ${provider} is not configured in llm.apiKey`);
|
|
250
199
|
}
|
|
251
|
-
if (config.
|
|
252
|
-
|
|
200
|
+
if (config.llm.sleep && config.llm.sleep > 0) {
|
|
201
|
+
await new Promise((resolve) => setTimeout(resolve, config.llm.sleep));
|
|
253
202
|
}
|
|
254
|
-
const
|
|
203
|
+
const engine = igniteEngine(engineName, {
|
|
204
|
+
apiKey: config.llm.apiKey,
|
|
205
|
+
...config.llm.baseURL ? { baseURL: config.llm.baseURL } : {}
|
|
206
|
+
});
|
|
207
|
+
const fullPrompt = `${prePrompt2}
|
|
255
208
|
|
|
256
209
|
|
|
257
210
|
${prompt}
|
|
258
211
|
|
|
259
212
|
|
|
260
|
-
${postPrompt2}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
if (responseString.startsWith("{") && responseString.endsWith("}")) {
|
|
266
|
-
response = maybeResponse;
|
|
267
|
-
break;
|
|
268
|
-
}
|
|
269
|
-
if (config.debug) {
|
|
270
|
-
console.log("Gemini model response is not valid, contains no JSON:", JSON.stringify({ maybeResponse }));
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
if (config.debug) {
|
|
274
|
-
console.log("Gemini model response:", JSON.stringify({ response }));
|
|
275
|
-
}
|
|
276
|
-
if (!response) {
|
|
277
|
-
throw new Error("Gemini model response is not valid");
|
|
278
|
-
}
|
|
279
|
-
return response;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// src/io/gemini/commit-response.ts
|
|
283
|
-
function commitResponseGemini(response) {
|
|
284
|
-
const result2 = response.response.text();
|
|
285
|
-
return result2;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// src/io/gemini/parse.ts
|
|
289
|
-
function parseGemini(unparsed) {
|
|
290
|
-
if (typeof unparsed !== "string") {
|
|
291
|
-
throw new Error("CommitResponse should be a string here.");
|
|
292
|
-
}
|
|
293
|
-
const cleaned = unparsed.replace(/```json/g, "").replace(/```/g, "");
|
|
294
|
-
const parsed = JSON.parse(cleaned);
|
|
295
|
-
return parsed;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// src/io/huggingface/languages-map.ts
|
|
299
|
-
var languagesMap = {
|
|
300
|
-
"en-US": "eng_Latn",
|
|
301
|
-
"en-GB": "eng_Latn",
|
|
302
|
-
"pt-BR": "por_Latn",
|
|
303
|
-
"pt-PT": "por_Latn",
|
|
304
|
-
"es-ES": "spa_Latn",
|
|
305
|
-
"es-MX": "spa_Latn",
|
|
306
|
-
"fr-FR": "fra_Latn",
|
|
307
|
-
"fr-CA": "fra_Latn",
|
|
308
|
-
"de-DE": "deu_Latn",
|
|
309
|
-
"it-IT": "ita_Latn",
|
|
310
|
-
"nl-NL": "nld_Latn",
|
|
311
|
-
"pl-PL": "pol_Latn",
|
|
312
|
-
"ru-RU": "rus_Cyrl",
|
|
313
|
-
"uk-UA": "ukr_Cyrl",
|
|
314
|
-
"bg-BG": "bul_Cyrl",
|
|
315
|
-
"hr-HR": "hrv_Latn",
|
|
316
|
-
"cs-CZ": "ces_Latn",
|
|
317
|
-
"sk-SK": "slk_Latn",
|
|
318
|
-
"hu-HU": "hun_Latn",
|
|
319
|
-
"ro-RO": "ron_Latn",
|
|
320
|
-
"fi-FI": "fin_Latn",
|
|
321
|
-
"sv-SE": "swe_Latn",
|
|
322
|
-
"da-DK": "dan_Latn",
|
|
323
|
-
"no-NO": "nob_Latn",
|
|
324
|
-
"is-IS": "isl_Latn",
|
|
325
|
-
"et-EE": "est_Latn",
|
|
326
|
-
"lv-LV": "lav_Latn",
|
|
327
|
-
"lt-LT": "lit_Latn",
|
|
328
|
-
"mt-MT": "mlt_Latn",
|
|
329
|
-
"ga-IE": "gle_Latn",
|
|
330
|
-
"cy-GB": "cym_Latn",
|
|
331
|
-
"eu-ES": "eus_Latn",
|
|
332
|
-
"ca-ES": "cat_Latn",
|
|
333
|
-
"gl-ES": "glg_Latn",
|
|
334
|
-
"oc-FR": "oci_Latn",
|
|
335
|
-
"br-FR": "bre_Latn",
|
|
336
|
-
"gd-GB": "gla_Latn",
|
|
337
|
-
"kw-GB": "cor_Latn",
|
|
338
|
-
"fur-IT": "fur_Latn",
|
|
339
|
-
"rm-CH": "roh_Latn",
|
|
340
|
-
"lb-LU": "ltz_Latn",
|
|
341
|
-
"fy-NL": "fry_Latn",
|
|
342
|
-
"af-ZA": "afr_Latn",
|
|
343
|
-
"zh-CN": "zho_Hans",
|
|
344
|
-
"zh-TW": "zho_Hant",
|
|
345
|
-
"zh-HK": "zho_Hant",
|
|
346
|
-
"ja-JP": "jpn_Jpan",
|
|
347
|
-
"ko-KR": "kor_Hang",
|
|
348
|
-
"th-TH": "tha_Thai",
|
|
349
|
-
"vi-VN": "vie_Latn",
|
|
350
|
-
"id-ID": "ind_Latn",
|
|
351
|
-
"ms-MY": "zsm_Latn",
|
|
352
|
-
"tl-PH": "tgl_Latn",
|
|
353
|
-
"my-MM": "mya_Mymr",
|
|
354
|
-
"km-KH": "khm_Khmr",
|
|
355
|
-
"lo-LA": "lao_Laoo",
|
|
356
|
-
"bn-BD": "ben_Beng",
|
|
357
|
-
"bn-IN": "ben_Beng",
|
|
358
|
-
"hi-IN": "hin_Deva",
|
|
359
|
-
"ur-PK": "urd_Arab",
|
|
360
|
-
"ur-IN": "urd_Arab",
|
|
361
|
-
"pa-IN": "pan_Guru",
|
|
362
|
-
"gu-IN": "guj_Gujr",
|
|
363
|
-
"or-IN": "ory_Orya",
|
|
364
|
-
"as-IN": "asm_Beng",
|
|
365
|
-
"ml-IN": "mal_Mlym",
|
|
366
|
-
"ta-IN": "tam_Tamil",
|
|
367
|
-
"te-IN": "tel_Telu",
|
|
368
|
-
"kn-IN": "kan_Knda",
|
|
369
|
-
"si-LK": "sin_Sinh",
|
|
370
|
-
"ne-NP": "nep_Deva",
|
|
371
|
-
"dz-BT": "dzo_Tibt",
|
|
372
|
-
"bo-CN": "bod_Tibt",
|
|
373
|
-
"mn-MN": "khk_Cyrl",
|
|
374
|
-
"ka-GE": "kat_Geor",
|
|
375
|
-
"hy-AM": "hye_Armn",
|
|
376
|
-
"az-AZ": "azj_Latn",
|
|
377
|
-
"tr-TR": "tur_Latn",
|
|
378
|
-
"fa-IR": "pes_Arab",
|
|
379
|
-
"fa-AF": "pes_Arab",
|
|
380
|
-
"ps-AF": "pbt_Arab",
|
|
381
|
-
"ku-TR": "kmr_Latn",
|
|
382
|
-
"he-IL": "heb_Hebr",
|
|
383
|
-
"ar-SA": "arb_Arab",
|
|
384
|
-
"ar-EG": "arb_Arab",
|
|
385
|
-
"ar-MA": "arb_Arab",
|
|
386
|
-
"ar-DZ": "arb_Arab",
|
|
387
|
-
"ar-TN": "arb_Arab",
|
|
388
|
-
"ar-LY": "arb_Arab",
|
|
389
|
-
"ar-SD": "arb_Arab",
|
|
390
|
-
"ar-IQ": "arb_Arab",
|
|
391
|
-
"ar-SY": "arb_Arab",
|
|
392
|
-
"ar-JO": "arb_Arab",
|
|
393
|
-
"ar-LB": "arb_Arab",
|
|
394
|
-
"ar-KW": "arb_Arab",
|
|
395
|
-
"ar-AE": "arb_Arab",
|
|
396
|
-
"ar-QA": "arb_Arab",
|
|
397
|
-
"ar-BH": "arb_Arab",
|
|
398
|
-
"ar-OM": "arb_Arab",
|
|
399
|
-
"ar-YE": "arb_Arab",
|
|
400
|
-
"ar-SO": "arb_Arab",
|
|
401
|
-
"ar-DJ": "arb_Arab",
|
|
402
|
-
"ar-KM": "arb_Arab",
|
|
403
|
-
"ar-TD": "arb_Arab",
|
|
404
|
-
"ar-ER": "arb_Arab",
|
|
405
|
-
"ar-IL": "arb_Arab",
|
|
406
|
-
"ar-PS": "arb_Arab",
|
|
407
|
-
"ar-001": "arb_Arab",
|
|
408
|
-
"sw-KE": "swh_Latn",
|
|
409
|
-
"sw-TZ": "swh_Latn",
|
|
410
|
-
"am-ET": "amh_Ethi",
|
|
411
|
-
"om-ET": "gaz_Latn",
|
|
412
|
-
"so-SO": "som_Latn",
|
|
413
|
-
"ha-NG": "hau_Latn",
|
|
414
|
-
"yo-NG": "yor_Latn",
|
|
415
|
-
"ig-NG": "ibo_Latn",
|
|
416
|
-
"zu-ZA": "zul_Latn",
|
|
417
|
-
"xh-ZA": "xho_Latn",
|
|
418
|
-
"rw-RW": "kin_Latn",
|
|
419
|
-
"lg-UG": "lug_Latn",
|
|
420
|
-
"ak-GH": "aka_Latn",
|
|
421
|
-
"tw-GH": "twi_Latn",
|
|
422
|
-
"ee-GH": "ewe_Latn",
|
|
423
|
-
"ff-SN": "fuv_Latn",
|
|
424
|
-
"wo-SN": "wol_Latn",
|
|
425
|
-
"sn-ZW": "sna_Latn",
|
|
426
|
-
"nd-ZW": "nde_Latn",
|
|
427
|
-
"ny-MW": "nya_Latn",
|
|
428
|
-
"st-ZA": "sot_Latn",
|
|
429
|
-
"tn-BW": "tsn_Latn",
|
|
430
|
-
"ts-ZA": "tso_Latn",
|
|
431
|
-
"ve-ZA": "ven_Latn",
|
|
432
|
-
"ss-ZA": "ssw_Latn",
|
|
433
|
-
"nr-ZA": "nbl_Latn",
|
|
434
|
-
"qu-PE": "quy_Latn",
|
|
435
|
-
"qu-BO": "quy_Latn",
|
|
436
|
-
"qu-EC": "quy_Latn",
|
|
437
|
-
"ay-BO": "aym_Latn",
|
|
438
|
-
"gn-PY": "grn_Latn",
|
|
439
|
-
"ht-HT": "hat_Latn",
|
|
440
|
-
"jv-ID": "jav_Latn",
|
|
441
|
-
"su-ID": "sun_Latn",
|
|
442
|
-
"ceb-PH": "ceb_Latn",
|
|
443
|
-
"ilo-PH": "ilo_Latn",
|
|
444
|
-
"war-PH": "war_Latn",
|
|
445
|
-
"bjn-ID": "bjn_Latn",
|
|
446
|
-
"ban-ID": "ban_Latn",
|
|
447
|
-
"mad-ID": "mad_Latn",
|
|
448
|
-
"min-ID": "min_Latn",
|
|
449
|
-
"ace-ID": "ace_Latn",
|
|
450
|
-
"bug-ID": "bug_Latn",
|
|
451
|
-
"gor-ID": "gor_Latn",
|
|
452
|
-
"mak-ID": "mak_Latn",
|
|
453
|
-
"mdr-ID": "mdr_Latn",
|
|
454
|
-
"sas-ID": "sas_Latn",
|
|
455
|
-
"shn-MM": "shn_Mymr",
|
|
456
|
-
"kac-MM": "kac_Latn",
|
|
457
|
-
"lzh-CN": "lzh_Hant",
|
|
458
|
-
"wuu-CN": "wuu_Hans",
|
|
459
|
-
"yue-CN": "yue_Hant",
|
|
460
|
-
"nan-TW": "nan_Hant",
|
|
461
|
-
"hak-TW": "hak_Hant",
|
|
462
|
-
"cjy-CN": "cjy_Hans",
|
|
463
|
-
"cmn-CN": "cmn_Hans",
|
|
464
|
-
"cmn-TW": "cmn_Hant",
|
|
465
|
-
"cmn-SG": "cmn_Hans",
|
|
466
|
-
"cmn-HK": "cmn_Hant",
|
|
467
|
-
"cmn-MO": "cmn_Hant",
|
|
468
|
-
"cmn-001": "cmn_Hans",
|
|
469
|
-
"haw-US": "haw_Latn",
|
|
470
|
-
"mi-NZ": "mri_Latn",
|
|
471
|
-
"sm-WS": "smo_Latn",
|
|
472
|
-
"to-TO": "ton_Latn",
|
|
473
|
-
"fj-FJ": "fij_Latn",
|
|
474
|
-
"ty-PF": "tah_Latn",
|
|
475
|
-
"co-FR": "cos_Latn",
|
|
476
|
-
"eu-FR": "eus_Latn",
|
|
477
|
-
"kk-KZ": "kaz_Cyrl",
|
|
478
|
-
"ky-KG": "kir_Cyrl",
|
|
479
|
-
"uz-UZ": "uzn_Latn",
|
|
480
|
-
"tg-TJ": "tgk_Cyrl",
|
|
481
|
-
"tk-TM": "tuk_Latn"
|
|
482
|
-
};
|
|
483
|
-
|
|
484
|
-
// src/io/huggingface/ask.ts
|
|
485
|
-
function getLanguageCode(language) {
|
|
486
|
-
return languagesMap[language];
|
|
487
|
-
}
|
|
488
|
-
function progressCallback(progress) {
|
|
489
|
-
process.stdout.clearLine(0);
|
|
490
|
-
process.stdout.cursorTo(0);
|
|
491
|
-
if (progress.status === "download") {
|
|
492
|
-
process.stdout.write("Downloading...");
|
|
493
|
-
} else if (progress.status === "initiate") {
|
|
494
|
-
process.stdout.write("Initializing...");
|
|
495
|
-
} else if (progress.status === "done") {
|
|
496
|
-
process.stdout.write("Done!");
|
|
497
|
-
} else if (progress.status === "progress" && "progress" in progress && "loaded" in progress && "total" in progress) {
|
|
498
|
-
process.stdout.write(
|
|
499
|
-
`Downloading: ${Number(progress.progress).toFixed(2)}%, loaded: ${progress.loaded}/${progress.total}`
|
|
500
|
-
);
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
async function pipeLanguage(pipe, original, srcLanguage, targetLanguage) {
|
|
504
|
-
const response = await pipe(original, {
|
|
505
|
-
src_lang: srcLanguage,
|
|
506
|
-
tgt_lang: targetLanguage,
|
|
507
|
-
temperature: 1
|
|
213
|
+
${postPrompt2}`.trim();
|
|
214
|
+
const messages = [new Message("user", fullPrompt)];
|
|
215
|
+
const model = config.llm.model ?? "gpt-4o-mini";
|
|
216
|
+
const response = await engine.complete(engine.buildModel(model), messages, {
|
|
217
|
+
temperature: config.llm.temperature
|
|
508
218
|
});
|
|
509
|
-
|
|
510
|
-
}
|
|
511
|
-
async function askHuggingface(original) {
|
|
512
|
-
const config = await awaitedConfig;
|
|
513
|
-
const cacheDir = `${config.cache.dir}/.cache`;
|
|
514
|
-
env.cacheDir = cacheDir;
|
|
515
|
-
const pipe = await pipeline("translation", config.llm.model, {
|
|
516
|
-
progress_callback: progressCallback,
|
|
517
|
-
cache_dir: cacheDir
|
|
518
|
-
});
|
|
519
|
-
const { languages } = config;
|
|
520
|
-
let responses = [];
|
|
521
|
-
for await (const language of languages) {
|
|
522
|
-
const response = await pipeLanguage(
|
|
523
|
-
pipe,
|
|
524
|
-
original,
|
|
525
|
-
getLanguageCode(config.sourceLanguage),
|
|
526
|
-
getLanguageCode(language)
|
|
527
|
-
);
|
|
528
|
-
if (Array.isArray(response)) {
|
|
529
|
-
responses = responses.concat(
|
|
530
|
-
response.map((r) => ({
|
|
531
|
-
...r,
|
|
532
|
-
targetLanguage: language
|
|
533
|
-
}))
|
|
534
|
-
);
|
|
535
|
-
} else {
|
|
536
|
-
responses.push({
|
|
537
|
-
...response,
|
|
538
|
-
targetLanguage: language
|
|
539
|
-
});
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
return { responses, original };
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
// src/io/huggingface/commit-response.ts
|
|
546
|
-
function commitResponseHuggingface(response) {
|
|
547
|
-
const { responses, original } = response;
|
|
548
|
-
const translation = responses.reduce((acc, curr) => {
|
|
549
|
-
acc[curr.targetLanguage] = curr.translation_text;
|
|
550
|
-
return acc;
|
|
551
|
-
}, {});
|
|
552
|
-
return {
|
|
553
|
-
translation,
|
|
554
|
-
original
|
|
555
|
-
};
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
// src/io/huggingface/parse.ts
|
|
559
|
-
function parseHuggingface(unparsed) {
|
|
560
|
-
if (typeof unparsed === "string") {
|
|
561
|
-
throw new Error("CommitResponse should not be a string here.");
|
|
562
|
-
}
|
|
563
|
-
return unparsed;
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
// src/io/ask-llm.ts
|
|
567
|
-
var llmChoices = {
|
|
568
|
-
anthropic: {
|
|
569
|
-
ask: askAnthropic,
|
|
570
|
-
commitResponse: commitResponseAnthropic,
|
|
571
|
-
parse: parseAnthropic
|
|
572
|
-
},
|
|
573
|
-
gemini: {
|
|
574
|
-
ask: askGemini,
|
|
575
|
-
commitResponse: commitResponseGemini,
|
|
576
|
-
parse: parseGemini
|
|
577
|
-
},
|
|
578
|
-
huggingface: {
|
|
579
|
-
ask: askHuggingface,
|
|
580
|
-
commitResponse: commitResponseHuggingface,
|
|
581
|
-
parse: parseHuggingface
|
|
219
|
+
if (config.debug) {
|
|
220
|
+
console.log("LLM response:", JSON.stringify({ provider, model: config.llm.model, response: response.content }));
|
|
582
221
|
}
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
const response = await llmChoice.ask(prompt, prePrompt2, postPrompt2);
|
|
586
|
-
const unparsed = llmChoice.commitResponse(response);
|
|
587
|
-
const parsed = llmChoice.parse(unparsed);
|
|
588
|
-
return parsed;
|
|
589
|
-
}
|
|
590
|
-
async function askLLM(prompt, prePrompt2, postPrompt2) {
|
|
591
|
-
const config = await awaitedConfig;
|
|
592
|
-
const llmChoiceName = config.llm.choice;
|
|
593
|
-
const llmChoice = llmChoices[llmChoiceName];
|
|
594
|
-
if (!llmChoice) {
|
|
595
|
-
throw new Error("LLMChoice not found");
|
|
222
|
+
if (!response.content) {
|
|
223
|
+
throw new Error("LLM response content is empty");
|
|
596
224
|
}
|
|
597
|
-
return
|
|
225
|
+
return parseResponse(response.content);
|
|
598
226
|
}
|
|
599
227
|
|
|
600
228
|
export { askLLM };
|