@lingo.dev/_compiler 0.1.13 → 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/build/index.cjs +259 -138
- package/build/index.mjs +259 -138
- package/package.json +2 -1
package/build/index.cjs
CHANGED
|
@@ -4,7 +4,7 @@ var _unplugin = require('unplugin');
|
|
|
4
4
|
// package.json
|
|
5
5
|
var package_default = {
|
|
6
6
|
name: "@lingo.dev/_compiler",
|
|
7
|
-
version: "0.
|
|
7
|
+
version: "0.2.0",
|
|
8
8
|
description: "Lingo.dev Compiler",
|
|
9
9
|
private: false,
|
|
10
10
|
publishConfig: {
|
|
@@ -40,6 +40,7 @@ var package_default = {
|
|
|
40
40
|
typescript: "^5.4.5"
|
|
41
41
|
},
|
|
42
42
|
dependencies: {
|
|
43
|
+
"@ai-sdk/google": "^1.2.19",
|
|
43
44
|
"@ai-sdk/groq": "^1.2.3",
|
|
44
45
|
"@babel/generator": "^7.26.5",
|
|
45
46
|
"@babel/parser": "^7.26.7",
|
|
@@ -919,6 +920,7 @@ var LCPCache = class {
|
|
|
919
920
|
|
|
920
921
|
// src/lib/lcp/api/index.ts
|
|
921
922
|
var _groq = require('@ai-sdk/groq');
|
|
923
|
+
var _google = require('@ai-sdk/google');
|
|
922
924
|
var _ai = require('ai');
|
|
923
925
|
|
|
924
926
|
|
|
@@ -1150,21 +1152,36 @@ function getRc() {
|
|
|
1150
1152
|
return data;
|
|
1151
1153
|
}
|
|
1152
1154
|
|
|
1153
|
-
// src/utils/
|
|
1155
|
+
// src/utils/llm-api-key.ts
|
|
1154
1156
|
|
|
1155
1157
|
var _dotenv = require('dotenv'); var dotenv = _interopRequireWildcard(_dotenv);
|
|
1158
|
+
function getKeyFromEnv(envVarName) {
|
|
1159
|
+
const ephemeralEnv = {};
|
|
1160
|
+
dotenv.config({ processEnv: ephemeralEnv });
|
|
1161
|
+
return ephemeralEnv[envVarName];
|
|
1162
|
+
}
|
|
1163
|
+
function getKeyFromRc(rcPath) {
|
|
1164
|
+
const rc = getRc();
|
|
1165
|
+
const result = _lodash2.default.get(rc, rcPath);
|
|
1166
|
+
return typeof result === "string" ? result : void 0;
|
|
1167
|
+
}
|
|
1156
1168
|
function getGroqKey() {
|
|
1157
1169
|
return getGroqKeyFromEnv() || getGroqKeyFromRc();
|
|
1158
1170
|
}
|
|
1159
1171
|
function getGroqKeyFromRc() {
|
|
1160
|
-
|
|
1161
|
-
const result = _lodash2.default.get(rc, "llm.groqApiKey");
|
|
1162
|
-
return result;
|
|
1172
|
+
return getKeyFromRc("llm.groqApiKey");
|
|
1163
1173
|
}
|
|
1164
1174
|
function getGroqKeyFromEnv() {
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1175
|
+
return getKeyFromEnv("GROQ_API_KEY");
|
|
1176
|
+
}
|
|
1177
|
+
function getGoogleKey() {
|
|
1178
|
+
return getGoogleKeyFromEnv() || getGoogleKeyFromRc();
|
|
1179
|
+
}
|
|
1180
|
+
function getGoogleKeyFromRc() {
|
|
1181
|
+
return getKeyFromRc("llm.googleApiKey");
|
|
1182
|
+
}
|
|
1183
|
+
function getGoogleKeyFromEnv() {
|
|
1184
|
+
return getKeyFromEnv("GOOGLE_API_KEY");
|
|
1168
1185
|
}
|
|
1169
1186
|
|
|
1170
1187
|
// src/lib/lcp/api/index.ts
|
|
@@ -1176,6 +1193,24 @@ function isRunningInCIOrDocker() {
|
|
|
1176
1193
|
return Boolean(process.env.CI) || fs.default.existsSync("/.dockerenv");
|
|
1177
1194
|
}
|
|
1178
1195
|
|
|
1196
|
+
// src/lib/lcp/api/provider-details.ts
|
|
1197
|
+
var providerDetails = {
|
|
1198
|
+
groq: {
|
|
1199
|
+
name: "Groq",
|
|
1200
|
+
apiKeyEnvVar: "GROQ_API_KEY",
|
|
1201
|
+
apiKeyConfigKey: "llm.groqApiKey",
|
|
1202
|
+
getKeyLink: "https://groq.com",
|
|
1203
|
+
docsLink: "https://console.groq.com/docs/errors"
|
|
1204
|
+
},
|
|
1205
|
+
google: {
|
|
1206
|
+
name: "Google",
|
|
1207
|
+
apiKeyEnvVar: "GOOGLE_API_KEY",
|
|
1208
|
+
apiKeyConfigKey: "llm.googleApiKey",
|
|
1209
|
+
getKeyLink: "https://ai.google.dev/",
|
|
1210
|
+
docsLink: "https://ai.google.dev/gemini-api/docs/troubleshooting"
|
|
1211
|
+
}
|
|
1212
|
+
};
|
|
1213
|
+
|
|
1179
1214
|
// src/lib/lcp/api/index.ts
|
|
1180
1215
|
var LCPAPI = class {
|
|
1181
1216
|
static async translate(models, sourceDictionary, sourceLocale, targetLocale) {
|
|
@@ -1260,148 +1295,199 @@ var LCPAPI = class {
|
|
|
1260
1295
|
return dictionary;
|
|
1261
1296
|
}
|
|
1262
1297
|
static async _translateChunk(models, sourceDictionary, sourceLocale, targetLocale) {
|
|
1263
|
-
try {
|
|
1264
|
-
return await this._translateChunkGroq(
|
|
1265
|
-
models,
|
|
1266
|
-
sourceDictionary,
|
|
1267
|
-
sourceLocale,
|
|
1268
|
-
targetLocale
|
|
1269
|
-
);
|
|
1270
|
-
} catch (error) {
|
|
1271
|
-
this._failGroqFailureLocal(
|
|
1272
|
-
targetLocale,
|
|
1273
|
-
error instanceof Error ? error.message : "Unknown error"
|
|
1274
|
-
);
|
|
1275
|
-
}
|
|
1276
|
-
if (isRunningInCIOrDocker()) {
|
|
1277
|
-
const groqFromEnv = getGroqKeyFromEnv();
|
|
1278
|
-
if (!groqFromEnv) {
|
|
1279
|
-
this._failMissingGroqKeyCi();
|
|
1280
|
-
}
|
|
1281
|
-
}
|
|
1282
|
-
throw new Error(
|
|
1283
|
-
"\u26A0\uFE0F No API key found. Please set GROQ_API_KEY environment variable. If you dont have one go to https://groq.com/"
|
|
1284
|
-
);
|
|
1285
|
-
}
|
|
1286
|
-
static async _translateChunkGroq(models, sourceDictionary, sourceLocale, targetLocale) {
|
|
1287
|
-
const groq = _groq.createGroq.call(void 0, { apiKey: getGroqKey() });
|
|
1288
|
-
console.log(`Created Groq client for ${targetLocale}`);
|
|
1289
1298
|
const { provider, model } = getLocaleModel(
|
|
1290
1299
|
models,
|
|
1291
1300
|
sourceLocale,
|
|
1292
1301
|
targetLocale
|
|
1293
1302
|
);
|
|
1294
|
-
if (!model) {
|
|
1303
|
+
if (!provider || !model) {
|
|
1295
1304
|
throw new Error(
|
|
1296
|
-
`\u26A0\uFE0F Locale ${targetLocale} is not configured. Add model for this locale to your config.`
|
|
1305
|
+
`\u26A0\uFE0F Locale "${targetLocale}" is not configured. Add provider and model for this locale to your config, e.g., "groq:llama3-8b-8192".`
|
|
1297
1306
|
);
|
|
1298
1307
|
}
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1308
|
+
try {
|
|
1309
|
+
const aiModel = this._createAiModel(provider, model, targetLocale);
|
|
1310
|
+
console.log(
|
|
1311
|
+
`\u2728 Using model "${model}" from "${provider}" to translate from "${sourceLocale}" to "${targetLocale}"`
|
|
1302
1312
|
);
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
);
|
|
1307
|
-
const groqModel = groq(model);
|
|
1308
|
-
console.log(`Created model ${model}`);
|
|
1309
|
-
const response = await _ai.generateText.call(void 0, {
|
|
1310
|
-
model: groqModel,
|
|
1311
|
-
messages: [
|
|
1312
|
-
{
|
|
1313
|
-
role: "system",
|
|
1314
|
-
content: prompt_default({ sourceLocale, targetLocale })
|
|
1315
|
-
},
|
|
1316
|
-
...shots_default.flatMap((shotsTuple) => [
|
|
1313
|
+
const response = await _ai.generateText.call(void 0, {
|
|
1314
|
+
model: aiModel,
|
|
1315
|
+
messages: [
|
|
1317
1316
|
{
|
|
1318
|
-
role: "
|
|
1319
|
-
content:
|
|
1317
|
+
role: "system",
|
|
1318
|
+
content: prompt_default({ sourceLocale, targetLocale })
|
|
1320
1319
|
},
|
|
1320
|
+
...shots_default.flatMap((shotsTuple) => [
|
|
1321
|
+
{
|
|
1322
|
+
role: "user",
|
|
1323
|
+
content: obj2xml(shotsTuple[0])
|
|
1324
|
+
},
|
|
1325
|
+
{
|
|
1326
|
+
role: "assistant",
|
|
1327
|
+
content: obj2xml(shotsTuple[1])
|
|
1328
|
+
}
|
|
1329
|
+
]),
|
|
1321
1330
|
{
|
|
1322
|
-
role: "
|
|
1323
|
-
content: obj2xml(
|
|
1331
|
+
role: "user",
|
|
1332
|
+
content: obj2xml(sourceDictionary)
|
|
1333
|
+
}
|
|
1334
|
+
]
|
|
1335
|
+
});
|
|
1336
|
+
console.log("Response text received for", targetLocale);
|
|
1337
|
+
let responseText = response.text;
|
|
1338
|
+
responseText = responseText.substring(
|
|
1339
|
+
responseText.indexOf("<"),
|
|
1340
|
+
responseText.lastIndexOf(">") + 1
|
|
1341
|
+
);
|
|
1342
|
+
return xml2obj(responseText);
|
|
1343
|
+
} catch (error) {
|
|
1344
|
+
this._failLLMFailureLocal(
|
|
1345
|
+
provider,
|
|
1346
|
+
targetLocale,
|
|
1347
|
+
error instanceof Error ? error.message : "Unknown error"
|
|
1348
|
+
);
|
|
1349
|
+
throw error;
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
/**
|
|
1353
|
+
* Instantiates an AI model based on provider and model ID.
|
|
1354
|
+
* Includes CI/CD API key checks.
|
|
1355
|
+
* @param providerId The ID of the AI provider (e.g., "groq", "google").
|
|
1356
|
+
* @param modelId The ID of the specific model (e.g., "llama3-8b-8192", "gemini-2.0-flash").
|
|
1357
|
+
* @param targetLocale The target locale being translated to (for logging/error messages).
|
|
1358
|
+
* @returns An instantiated AI LanguageModel.
|
|
1359
|
+
* @throws Error if the provider is not supported or API key is missing in CI/CD.
|
|
1360
|
+
*/
|
|
1361
|
+
static _createAiModel(providerId, modelId, targetLocale) {
|
|
1362
|
+
switch (providerId) {
|
|
1363
|
+
case "groq":
|
|
1364
|
+
if (isRunningInCIOrDocker()) {
|
|
1365
|
+
const groqFromEnv = getGroqKeyFromEnv();
|
|
1366
|
+
if (!groqFromEnv) {
|
|
1367
|
+
this._failMissingLLMKeyCi(providerId);
|
|
1324
1368
|
}
|
|
1325
|
-
]),
|
|
1326
|
-
{
|
|
1327
|
-
role: "user",
|
|
1328
|
-
content: obj2xml(sourceDictionary)
|
|
1329
1369
|
}
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1370
|
+
const groqKey = getGroqKey();
|
|
1371
|
+
if (!groqKey) {
|
|
1372
|
+
throw new Error(
|
|
1373
|
+
"\u26A0\uFE0F GROQ API key not found. Please set GROQ_API_KEY environment variable or configure it user-wide."
|
|
1374
|
+
);
|
|
1375
|
+
}
|
|
1376
|
+
console.log(
|
|
1377
|
+
`Creating Groq client for ${targetLocale} using model ${modelId}`
|
|
1378
|
+
);
|
|
1379
|
+
return _groq.createGroq.call(void 0, { apiKey: groqKey })(modelId);
|
|
1380
|
+
case "google":
|
|
1381
|
+
if (isRunningInCIOrDocker()) {
|
|
1382
|
+
const googleFromEnv = getGoogleKeyFromEnv();
|
|
1383
|
+
if (!googleFromEnv) {
|
|
1384
|
+
this._failMissingLLMKeyCi(providerId);
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
const googleKey = getGoogleKey();
|
|
1388
|
+
if (!googleKey) {
|
|
1389
|
+
throw new Error(
|
|
1390
|
+
"\u26A0\uFE0F Google API key not found. Please set GOOGLE_API_KEY environment variable or configure it user-wide."
|
|
1391
|
+
);
|
|
1392
|
+
}
|
|
1393
|
+
console.log(
|
|
1394
|
+
`Creating Google Generative AI client for ${targetLocale} using model ${modelId}`
|
|
1395
|
+
);
|
|
1396
|
+
return _google.createGoogleGenerativeAI.call(void 0, { apiKey: googleKey })(modelId);
|
|
1397
|
+
default:
|
|
1398
|
+
throw new Error(
|
|
1399
|
+
`\u26A0\uFE0F Provider "${providerId}" for locale "${targetLocale}" is not supported. Only "groq" and "google" providers are supported at the moment.`
|
|
1400
|
+
);
|
|
1401
|
+
}
|
|
1339
1402
|
}
|
|
1340
1403
|
/**
|
|
1341
1404
|
* Show an actionable error message and exit the process when the compiler
|
|
1342
|
-
* is running in CI/CD without a
|
|
1405
|
+
* is running in CI/CD without a required LLM API key.
|
|
1343
1406
|
* The message explains why this situation is unusual and how to fix it.
|
|
1407
|
+
* @param providerId The ID of the LLM provider whose key is missing.
|
|
1344
1408
|
*/
|
|
1345
|
-
static
|
|
1409
|
+
static _failMissingLLMKeyCi(providerId) {
|
|
1410
|
+
let details = providerDetails[providerId];
|
|
1411
|
+
if (!details) {
|
|
1412
|
+
console.error(
|
|
1413
|
+
`Internal Error: Missing details for provider "${providerId}" when reporting missing key in CI/CD. You might be using an unsupported provider.`
|
|
1414
|
+
);
|
|
1415
|
+
process.exit(1);
|
|
1416
|
+
}
|
|
1346
1417
|
console.log(
|
|
1347
1418
|
_dedent2.default`
|
|
1348
1419
|
\n
|
|
1349
1420
|
💡 You're using Lingo.dev Localization Compiler, and it detected unlocalized components in your app.
|
|
1350
1421
|
|
|
1351
|
-
The compiler needs a
|
|
1422
|
+
The compiler needs a ${details.name} API key to translate missing strings, but ${details.apiKeyEnvVar} is not set in the environment.
|
|
1352
1423
|
|
|
1353
1424
|
This is unexpected: typically you run a full build locally, commit the generated translation files, and push them to CI/CD.
|
|
1354
1425
|
|
|
1355
1426
|
However, If you want CI/CD to translate the new strings, provide the key with:
|
|
1356
|
-
• Session-wide: export
|
|
1357
|
-
• Project-wide / CI: add
|
|
1427
|
+
• Session-wide: export ${details.apiKeyEnvVar}=<your-api-key>
|
|
1428
|
+
• Project-wide / CI: add ${details.apiKeyEnvVar}=<your-api-key> to your pipeline environment variables
|
|
1358
1429
|
|
|
1359
1430
|
⭐️ Also:
|
|
1360
|
-
1. If you don't yet have a
|
|
1361
|
-
2. If you want to use a different LLM,
|
|
1362
|
-
3. If you
|
|
1431
|
+
1. If you don't yet have a ${details.name} API key, get one for free at ${details.getKeyLink}
|
|
1432
|
+
2. If you want to use a different LLM, update your configuration. Refer to documentation for help: https://docs.lingo.dev/
|
|
1433
|
+
3. If the model you want to use isn't supported yet, raise an issue in our open-source repo: https://lingo.dev/go/gh
|
|
1363
1434
|
|
|
1364
1435
|
✨
|
|
1365
1436
|
`
|
|
1366
1437
|
);
|
|
1367
1438
|
process.exit(1);
|
|
1368
1439
|
}
|
|
1369
|
-
|
|
1440
|
+
/**
|
|
1441
|
+
* Show an actionable error message and exit the process when an LLM API call
|
|
1442
|
+
* fails during local compilation.
|
|
1443
|
+
* @param providerId The ID of the LLM provider that failed.
|
|
1444
|
+
* @param targetLocale The target locale being translated to.
|
|
1445
|
+
* @param errorMessage The error message received from the API.
|
|
1446
|
+
*/
|
|
1447
|
+
static _failLLMFailureLocal(providerId, targetLocale, errorMessage) {
|
|
1448
|
+
const details = providerDetails[providerId];
|
|
1449
|
+
if (!details) {
|
|
1450
|
+
console.error(
|
|
1451
|
+
`Internal Error: Missing details for provider "${providerId}" when reporting local failure.`
|
|
1452
|
+
);
|
|
1453
|
+
console.error(`Original Error: ${errorMessage}`);
|
|
1454
|
+
process.exit(1);
|
|
1455
|
+
}
|
|
1370
1456
|
const isInvalidApiKey = errorMessage.match("Invalid API Key");
|
|
1371
1457
|
if (isInvalidApiKey) {
|
|
1372
1458
|
console.log(_dedent2.default`
|
|
1373
1459
|
\n
|
|
1374
|
-
⚠️ Lingo.dev Compiler requires a valid
|
|
1375
|
-
|
|
1376
|
-
It looks like you set
|
|
1460
|
+
⚠️ Lingo.dev Compiler requires a valid ${details.name} API key to translate your application.
|
|
1461
|
+
|
|
1462
|
+
It looks like you set ${details.name} API key but it is not valid. Please check your API key and try again.
|
|
1463
|
+
|
|
1464
|
+
Error details from ${details.name} API: ${errorMessage}
|
|
1377
1465
|
|
|
1378
|
-
Error details from Groq API: ${errorMessage}
|
|
1379
|
-
|
|
1380
1466
|
👉 You can set the API key in one of the following ways:
|
|
1381
|
-
1. User-wide: Run npx lingo.dev@latest config set
|
|
1382
|
-
2. Project-wide: Add
|
|
1383
|
-
3
|
|
1384
|
-
|
|
1467
|
+
1. User-wide: Run npx lingo.dev@latest config set ${details.apiKeyConfigKey} <your-api-key>
|
|
1468
|
+
2. Project-wide: Add ${details.apiKeyEnvVar}=<your-api-key> to .env file in every project that uses Lingo.dev Localization Compiler
|
|
1469
|
+
3 Session-wide: Run export ${details.apiKeyEnvVar}=<your-api-key> in your terminal before running the compiler to set the API key for the current session
|
|
1470
|
+
|
|
1385
1471
|
⭐️ Also:
|
|
1386
|
-
1. If you don't yet have a
|
|
1472
|
+
1. If you don't yet have a ${details.name} API key, get one for free at ${details.getKeyLink}
|
|
1387
1473
|
2. If you want to use a different LLM, raise an issue in our open-source repo: https://lingo.dev/go/gh
|
|
1388
1474
|
3. If you have questions, feature requests, or would like to contribute, join our Discord: https://lingo.dev/go/discord
|
|
1389
|
-
|
|
1475
|
+
|
|
1390
1476
|
✨
|
|
1391
1477
|
`);
|
|
1392
1478
|
} else {
|
|
1393
1479
|
console.log(
|
|
1394
1480
|
_dedent2.default`
|
|
1395
1481
|
\n
|
|
1396
|
-
⚠️ Lingo.dev Compiler tried to translate your application to "${targetLocale}" locale via
|
|
1482
|
+
⚠️ Lingo.dev Compiler tried to translate your application to "${targetLocale}" locale via ${details.name} but it failed.
|
|
1397
1483
|
|
|
1398
|
-
Error details from
|
|
1484
|
+
Error details from ${details.name} API: ${errorMessage}
|
|
1399
1485
|
|
|
1400
|
-
This error comes from
|
|
1486
|
+
This error comes from the ${details.name} API, please check their documentation for more details: ${details.docsLink}
|
|
1401
1487
|
|
|
1402
1488
|
⭐️ Also:
|
|
1403
|
-
1. Did you set
|
|
1404
|
-
2. Did you reach any limits of your
|
|
1489
|
+
1. Did you set ${details.apiKeyEnvVar} environment variable correctly?
|
|
1490
|
+
2. Did you reach any limits of your ${details.name} account?
|
|
1405
1491
|
3. If you have questions, feature requests, or would like to contribute, join our Discord: https://lingo.dev/go/discord
|
|
1406
1492
|
|
|
1407
1493
|
✨
|
|
@@ -2384,13 +2470,23 @@ var clientDictionaryLoaderMutation = createCodeMutation((payload) => {
|
|
|
2384
2470
|
});
|
|
2385
2471
|
|
|
2386
2472
|
// src/index.ts
|
|
2473
|
+
var keyCheckers = {
|
|
2474
|
+
groq: {
|
|
2475
|
+
checkEnv: getGroqKeyFromEnv,
|
|
2476
|
+
checkRc: getGroqKeyFromRc
|
|
2477
|
+
},
|
|
2478
|
+
google: {
|
|
2479
|
+
checkEnv: getGoogleKeyFromEnv,
|
|
2480
|
+
checkRc: getGoogleKeyFromRc
|
|
2481
|
+
}
|
|
2482
|
+
};
|
|
2387
2483
|
var unplugin = _unplugin.createUnplugin.call(void 0,
|
|
2388
2484
|
(_params, _meta) => {
|
|
2389
2485
|
console.log("\u2139\uFE0F Starting Lingo.dev compiler...");
|
|
2486
|
+
const params = _lodash2.default.defaults(_params, defaultParams);
|
|
2390
2487
|
if (!isRunningInCIOrDocker()) {
|
|
2391
|
-
|
|
2488
|
+
validateLLMKeyDetails(params.models);
|
|
2392
2489
|
}
|
|
2393
|
-
const params = _lodash2.default.defaults(_params, defaultParams);
|
|
2394
2490
|
const invalidLocales = getInvalidLocales(
|
|
2395
2491
|
params.models,
|
|
2396
2492
|
params.sourceLocale,
|
|
@@ -2405,7 +2501,7 @@ var unplugin = _unplugin.createUnplugin.call(void 0,
|
|
|
2405
2501
|
1. Refer to documentation for help: https://docs.lingo.dev/
|
|
2406
2502
|
2. If you want to use a different LLM, raise an issue in our open-source repo: https://lingo.dev/go/gh
|
|
2407
2503
|
3. If you have questions, feature requests, or would like to contribute, join our Discord: https://lingo.dev/go/discord
|
|
2408
|
-
|
|
2504
|
+
|
|
2409
2505
|
✨
|
|
2410
2506
|
`);
|
|
2411
2507
|
process.exit(1);
|
|
@@ -2504,56 +2600,81 @@ var src_default = {
|
|
|
2504
2600
|
return config2;
|
|
2505
2601
|
}
|
|
2506
2602
|
};
|
|
2507
|
-
function
|
|
2508
|
-
const
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2603
|
+
function validateLLMKeyDetails(models) {
|
|
2604
|
+
const configuredProviders = _lodash2.default.chain(Object.values(models)).map((modelString) => modelString.split(":")[0]).filter(Boolean).uniq().filter(
|
|
2605
|
+
(providerId) => providerDetails.hasOwnProperty(providerId) && keyCheckers.hasOwnProperty(providerId)
|
|
2606
|
+
).value();
|
|
2607
|
+
if (configuredProviders.length === 0) {
|
|
2608
|
+
return;
|
|
2609
|
+
}
|
|
2610
|
+
const keyStatuses = {};
|
|
2611
|
+
const missingProviders = [];
|
|
2612
|
+
const foundProviders = [];
|
|
2613
|
+
for (const providerId of configuredProviders) {
|
|
2614
|
+
const details = providerDetails[providerId];
|
|
2615
|
+
const checkers = keyCheckers[providerId];
|
|
2616
|
+
if (!details || !checkers) continue;
|
|
2617
|
+
const foundInEnv = checkers.checkEnv() !== void 0;
|
|
2618
|
+
const foundInRc = checkers.checkRc() !== void 0;
|
|
2619
|
+
keyStatuses[providerId] = { foundInEnv, foundInRc, details };
|
|
2620
|
+
if (!foundInEnv && !foundInRc) {
|
|
2621
|
+
missingProviders.push(providerId);
|
|
2622
|
+
} else {
|
|
2623
|
+
foundProviders.push(providerId);
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
if (missingProviders.length > 0) {
|
|
2513
2627
|
console.log(_dedent2.default`
|
|
2514
2628
|
\n
|
|
2515
|
-
💡
|
|
2629
|
+
💡 Lingo.dev Localization Compiler is configured to use the following LLM provider(s): ${configuredProviders.join(", ")}.
|
|
2516
2630
|
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2631
|
+
The compiler requires API keys for these providers to work, but the following keys are missing:
|
|
2632
|
+
`);
|
|
2633
|
+
for (const providerId of missingProviders) {
|
|
2634
|
+
const status = keyStatuses[providerId];
|
|
2635
|
+
if (!status) continue;
|
|
2636
|
+
console.log(_dedent2.default`
|
|
2637
|
+
⚠️ ${status.details.name} API key is missing. Set ${status.details.apiKeyEnvVar} environment variable.
|
|
2638
|
+
|
|
2639
|
+
👉 You can set the API key in one of the following ways:
|
|
2640
|
+
1. User-wide: Run npx lingo.dev@latest config set ${status.details.apiKeyConfigKey || "<config-key-not-available>"} <your-api-key>
|
|
2641
|
+
2. Project-wide: Add ${status.details.apiKeyEnvVar}=<your-api-key> to .env file in every project that uses Lingo.dev Localization Compiler
|
|
2642
|
+
3. Session-wide: Run export ${status.details.apiKeyEnvVar}=<your-api-key> in your terminal before running the compiler to set the API key for the current session
|
|
2521
2643
|
|
|
2644
|
+
⭐️ If you don't yet have a ${status.details.name} API key, get one for free at ${status.details.getKeyLink}
|
|
2645
|
+
`);
|
|
2646
|
+
}
|
|
2647
|
+
console.log(_dedent2.default`
|
|
2648
|
+
\n
|
|
2522
2649
|
⭐️ Also:
|
|
2523
|
-
1. If you
|
|
2524
|
-
2. If you want to use
|
|
2650
|
+
1. If you want to use a different LLM, update your configuration. Refer to documentation for help: https://docs.lingo.dev/
|
|
2651
|
+
2. If the model/provider you want to use isn't supported yet, raise an issue in our open-source repo: https://lingo.dev/go/gh
|
|
2525
2652
|
3. If you have questions, feature requests, or would like to contribute, join our Discord: https://lingo.dev/go/discord
|
|
2526
2653
|
|
|
2527
2654
|
✨
|
|
2528
2655
|
`);
|
|
2529
2656
|
process.exit(1);
|
|
2530
|
-
} else if (
|
|
2531
|
-
console.log(
|
|
2532
|
-
|
|
2533
|
-
🔑
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
);
|
|
2551
|
-
} else if (!groq.fromEnv && groq.fromRc) {
|
|
2552
|
-
console.log(
|
|
2553
|
-
_dedent2.default`
|
|
2554
|
-
🔑 GROQ API key loaded from your user-wide configuration.
|
|
2555
|
-
`
|
|
2556
|
-
);
|
|
2657
|
+
} else if (foundProviders.length > 0) {
|
|
2658
|
+
console.log(_dedent2.default`
|
|
2659
|
+
\n
|
|
2660
|
+
🔑 LLM API keys detected for configured providers: ${foundProviders.join(", ")}.
|
|
2661
|
+
`);
|
|
2662
|
+
for (const providerId of foundProviders) {
|
|
2663
|
+
const status = keyStatuses[providerId];
|
|
2664
|
+
if (!status) continue;
|
|
2665
|
+
let sourceMessage = "";
|
|
2666
|
+
if (status.foundInEnv && status.foundInRc) {
|
|
2667
|
+
sourceMessage = `from both environment variables (${status.details.apiKeyEnvVar}) and your user-wide configuration. The key from the environment will be used because it has higher priority.`;
|
|
2668
|
+
} else if (status.foundInEnv) {
|
|
2669
|
+
sourceMessage = `from environment variables (${status.details.apiKeyEnvVar}).`;
|
|
2670
|
+
} else if (status.foundInRc) {
|
|
2671
|
+
sourceMessage = `from your user-wide configuration${status.details.apiKeyConfigKey ? ` (${status.details.apiKeyConfigKey})` : ""}.`;
|
|
2672
|
+
}
|
|
2673
|
+
console.log(_dedent2.default`
|
|
2674
|
+
• ${status.details.name} API key loaded ${sourceMessage}
|
|
2675
|
+
`);
|
|
2676
|
+
}
|
|
2677
|
+
console.log("\u2728");
|
|
2557
2678
|
}
|
|
2558
2679
|
}
|
|
2559
2680
|
|
package/build/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { createUnplugin } from "unplugin";
|
|
|
4
4
|
// package.json
|
|
5
5
|
var package_default = {
|
|
6
6
|
name: "@lingo.dev/_compiler",
|
|
7
|
-
version: "0.
|
|
7
|
+
version: "0.2.0",
|
|
8
8
|
description: "Lingo.dev Compiler",
|
|
9
9
|
private: false,
|
|
10
10
|
publishConfig: {
|
|
@@ -40,6 +40,7 @@ var package_default = {
|
|
|
40
40
|
typescript: "^5.4.5"
|
|
41
41
|
},
|
|
42
42
|
dependencies: {
|
|
43
|
+
"@ai-sdk/google": "^1.2.19",
|
|
43
44
|
"@ai-sdk/groq": "^1.2.3",
|
|
44
45
|
"@babel/generator": "^7.26.5",
|
|
45
46
|
"@babel/parser": "^7.26.7",
|
|
@@ -919,6 +920,7 @@ var LCPCache = class {
|
|
|
919
920
|
|
|
920
921
|
// src/lib/lcp/api/index.ts
|
|
921
922
|
import { createGroq } from "@ai-sdk/groq";
|
|
923
|
+
import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
|
922
924
|
import { generateText } from "ai";
|
|
923
925
|
import _6 from "lodash";
|
|
924
926
|
|
|
@@ -1150,21 +1152,36 @@ function getRc() {
|
|
|
1150
1152
|
return data;
|
|
1151
1153
|
}
|
|
1152
1154
|
|
|
1153
|
-
// src/utils/
|
|
1155
|
+
// src/utils/llm-api-key.ts
|
|
1154
1156
|
import _5 from "lodash";
|
|
1155
1157
|
import * as dotenv from "dotenv";
|
|
1158
|
+
function getKeyFromEnv(envVarName) {
|
|
1159
|
+
const ephemeralEnv = {};
|
|
1160
|
+
dotenv.config({ processEnv: ephemeralEnv });
|
|
1161
|
+
return ephemeralEnv[envVarName];
|
|
1162
|
+
}
|
|
1163
|
+
function getKeyFromRc(rcPath) {
|
|
1164
|
+
const rc = getRc();
|
|
1165
|
+
const result = _5.get(rc, rcPath);
|
|
1166
|
+
return typeof result === "string" ? result : void 0;
|
|
1167
|
+
}
|
|
1156
1168
|
function getGroqKey() {
|
|
1157
1169
|
return getGroqKeyFromEnv() || getGroqKeyFromRc();
|
|
1158
1170
|
}
|
|
1159
1171
|
function getGroqKeyFromRc() {
|
|
1160
|
-
|
|
1161
|
-
const result = _5.get(rc, "llm.groqApiKey");
|
|
1162
|
-
return result;
|
|
1172
|
+
return getKeyFromRc("llm.groqApiKey");
|
|
1163
1173
|
}
|
|
1164
1174
|
function getGroqKeyFromEnv() {
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1175
|
+
return getKeyFromEnv("GROQ_API_KEY");
|
|
1176
|
+
}
|
|
1177
|
+
function getGoogleKey() {
|
|
1178
|
+
return getGoogleKeyFromEnv() || getGoogleKeyFromRc();
|
|
1179
|
+
}
|
|
1180
|
+
function getGoogleKeyFromRc() {
|
|
1181
|
+
return getKeyFromRc("llm.googleApiKey");
|
|
1182
|
+
}
|
|
1183
|
+
function getGoogleKeyFromEnv() {
|
|
1184
|
+
return getKeyFromEnv("GOOGLE_API_KEY");
|
|
1168
1185
|
}
|
|
1169
1186
|
|
|
1170
1187
|
// src/lib/lcp/api/index.ts
|
|
@@ -1176,6 +1193,24 @@ function isRunningInCIOrDocker() {
|
|
|
1176
1193
|
return Boolean(process.env.CI) || fs4.existsSync("/.dockerenv");
|
|
1177
1194
|
}
|
|
1178
1195
|
|
|
1196
|
+
// src/lib/lcp/api/provider-details.ts
|
|
1197
|
+
var providerDetails = {
|
|
1198
|
+
groq: {
|
|
1199
|
+
name: "Groq",
|
|
1200
|
+
apiKeyEnvVar: "GROQ_API_KEY",
|
|
1201
|
+
apiKeyConfigKey: "llm.groqApiKey",
|
|
1202
|
+
getKeyLink: "https://groq.com",
|
|
1203
|
+
docsLink: "https://console.groq.com/docs/errors"
|
|
1204
|
+
},
|
|
1205
|
+
google: {
|
|
1206
|
+
name: "Google",
|
|
1207
|
+
apiKeyEnvVar: "GOOGLE_API_KEY",
|
|
1208
|
+
apiKeyConfigKey: "llm.googleApiKey",
|
|
1209
|
+
getKeyLink: "https://ai.google.dev/",
|
|
1210
|
+
docsLink: "https://ai.google.dev/gemini-api/docs/troubleshooting"
|
|
1211
|
+
}
|
|
1212
|
+
};
|
|
1213
|
+
|
|
1179
1214
|
// src/lib/lcp/api/index.ts
|
|
1180
1215
|
var LCPAPI = class {
|
|
1181
1216
|
static async translate(models, sourceDictionary, sourceLocale, targetLocale) {
|
|
@@ -1260,148 +1295,199 @@ var LCPAPI = class {
|
|
|
1260
1295
|
return dictionary;
|
|
1261
1296
|
}
|
|
1262
1297
|
static async _translateChunk(models, sourceDictionary, sourceLocale, targetLocale) {
|
|
1263
|
-
try {
|
|
1264
|
-
return await this._translateChunkGroq(
|
|
1265
|
-
models,
|
|
1266
|
-
sourceDictionary,
|
|
1267
|
-
sourceLocale,
|
|
1268
|
-
targetLocale
|
|
1269
|
-
);
|
|
1270
|
-
} catch (error) {
|
|
1271
|
-
this._failGroqFailureLocal(
|
|
1272
|
-
targetLocale,
|
|
1273
|
-
error instanceof Error ? error.message : "Unknown error"
|
|
1274
|
-
);
|
|
1275
|
-
}
|
|
1276
|
-
if (isRunningInCIOrDocker()) {
|
|
1277
|
-
const groqFromEnv = getGroqKeyFromEnv();
|
|
1278
|
-
if (!groqFromEnv) {
|
|
1279
|
-
this._failMissingGroqKeyCi();
|
|
1280
|
-
}
|
|
1281
|
-
}
|
|
1282
|
-
throw new Error(
|
|
1283
|
-
"\u26A0\uFE0F No API key found. Please set GROQ_API_KEY environment variable. If you dont have one go to https://groq.com/"
|
|
1284
|
-
);
|
|
1285
|
-
}
|
|
1286
|
-
static async _translateChunkGroq(models, sourceDictionary, sourceLocale, targetLocale) {
|
|
1287
|
-
const groq = createGroq({ apiKey: getGroqKey() });
|
|
1288
|
-
console.log(`Created Groq client for ${targetLocale}`);
|
|
1289
1298
|
const { provider, model } = getLocaleModel(
|
|
1290
1299
|
models,
|
|
1291
1300
|
sourceLocale,
|
|
1292
1301
|
targetLocale
|
|
1293
1302
|
);
|
|
1294
|
-
if (!model) {
|
|
1303
|
+
if (!provider || !model) {
|
|
1295
1304
|
throw new Error(
|
|
1296
|
-
`\u26A0\uFE0F Locale ${targetLocale} is not configured. Add model for this locale to your config.`
|
|
1305
|
+
`\u26A0\uFE0F Locale "${targetLocale}" is not configured. Add provider and model for this locale to your config, e.g., "groq:llama3-8b-8192".`
|
|
1297
1306
|
);
|
|
1298
1307
|
}
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1308
|
+
try {
|
|
1309
|
+
const aiModel = this._createAiModel(provider, model, targetLocale);
|
|
1310
|
+
console.log(
|
|
1311
|
+
`\u2728 Using model "${model}" from "${provider}" to translate from "${sourceLocale}" to "${targetLocale}"`
|
|
1302
1312
|
);
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
);
|
|
1307
|
-
const groqModel = groq(model);
|
|
1308
|
-
console.log(`Created model ${model}`);
|
|
1309
|
-
const response = await generateText({
|
|
1310
|
-
model: groqModel,
|
|
1311
|
-
messages: [
|
|
1312
|
-
{
|
|
1313
|
-
role: "system",
|
|
1314
|
-
content: prompt_default({ sourceLocale, targetLocale })
|
|
1315
|
-
},
|
|
1316
|
-
...shots_default.flatMap((shotsTuple) => [
|
|
1313
|
+
const response = await generateText({
|
|
1314
|
+
model: aiModel,
|
|
1315
|
+
messages: [
|
|
1317
1316
|
{
|
|
1318
|
-
role: "
|
|
1319
|
-
content:
|
|
1317
|
+
role: "system",
|
|
1318
|
+
content: prompt_default({ sourceLocale, targetLocale })
|
|
1320
1319
|
},
|
|
1320
|
+
...shots_default.flatMap((shotsTuple) => [
|
|
1321
|
+
{
|
|
1322
|
+
role: "user",
|
|
1323
|
+
content: obj2xml(shotsTuple[0])
|
|
1324
|
+
},
|
|
1325
|
+
{
|
|
1326
|
+
role: "assistant",
|
|
1327
|
+
content: obj2xml(shotsTuple[1])
|
|
1328
|
+
}
|
|
1329
|
+
]),
|
|
1321
1330
|
{
|
|
1322
|
-
role: "
|
|
1323
|
-
content: obj2xml(
|
|
1331
|
+
role: "user",
|
|
1332
|
+
content: obj2xml(sourceDictionary)
|
|
1333
|
+
}
|
|
1334
|
+
]
|
|
1335
|
+
});
|
|
1336
|
+
console.log("Response text received for", targetLocale);
|
|
1337
|
+
let responseText = response.text;
|
|
1338
|
+
responseText = responseText.substring(
|
|
1339
|
+
responseText.indexOf("<"),
|
|
1340
|
+
responseText.lastIndexOf(">") + 1
|
|
1341
|
+
);
|
|
1342
|
+
return xml2obj(responseText);
|
|
1343
|
+
} catch (error) {
|
|
1344
|
+
this._failLLMFailureLocal(
|
|
1345
|
+
provider,
|
|
1346
|
+
targetLocale,
|
|
1347
|
+
error instanceof Error ? error.message : "Unknown error"
|
|
1348
|
+
);
|
|
1349
|
+
throw error;
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
/**
|
|
1353
|
+
* Instantiates an AI model based on provider and model ID.
|
|
1354
|
+
* Includes CI/CD API key checks.
|
|
1355
|
+
* @param providerId The ID of the AI provider (e.g., "groq", "google").
|
|
1356
|
+
* @param modelId The ID of the specific model (e.g., "llama3-8b-8192", "gemini-2.0-flash").
|
|
1357
|
+
* @param targetLocale The target locale being translated to (for logging/error messages).
|
|
1358
|
+
* @returns An instantiated AI LanguageModel.
|
|
1359
|
+
* @throws Error if the provider is not supported or API key is missing in CI/CD.
|
|
1360
|
+
*/
|
|
1361
|
+
static _createAiModel(providerId, modelId, targetLocale) {
|
|
1362
|
+
switch (providerId) {
|
|
1363
|
+
case "groq":
|
|
1364
|
+
if (isRunningInCIOrDocker()) {
|
|
1365
|
+
const groqFromEnv = getGroqKeyFromEnv();
|
|
1366
|
+
if (!groqFromEnv) {
|
|
1367
|
+
this._failMissingLLMKeyCi(providerId);
|
|
1324
1368
|
}
|
|
1325
|
-
]),
|
|
1326
|
-
{
|
|
1327
|
-
role: "user",
|
|
1328
|
-
content: obj2xml(sourceDictionary)
|
|
1329
1369
|
}
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1370
|
+
const groqKey = getGroqKey();
|
|
1371
|
+
if (!groqKey) {
|
|
1372
|
+
throw new Error(
|
|
1373
|
+
"\u26A0\uFE0F GROQ API key not found. Please set GROQ_API_KEY environment variable or configure it user-wide."
|
|
1374
|
+
);
|
|
1375
|
+
}
|
|
1376
|
+
console.log(
|
|
1377
|
+
`Creating Groq client for ${targetLocale} using model ${modelId}`
|
|
1378
|
+
);
|
|
1379
|
+
return createGroq({ apiKey: groqKey })(modelId);
|
|
1380
|
+
case "google":
|
|
1381
|
+
if (isRunningInCIOrDocker()) {
|
|
1382
|
+
const googleFromEnv = getGoogleKeyFromEnv();
|
|
1383
|
+
if (!googleFromEnv) {
|
|
1384
|
+
this._failMissingLLMKeyCi(providerId);
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
const googleKey = getGoogleKey();
|
|
1388
|
+
if (!googleKey) {
|
|
1389
|
+
throw new Error(
|
|
1390
|
+
"\u26A0\uFE0F Google API key not found. Please set GOOGLE_API_KEY environment variable or configure it user-wide."
|
|
1391
|
+
);
|
|
1392
|
+
}
|
|
1393
|
+
console.log(
|
|
1394
|
+
`Creating Google Generative AI client for ${targetLocale} using model ${modelId}`
|
|
1395
|
+
);
|
|
1396
|
+
return createGoogleGenerativeAI({ apiKey: googleKey })(modelId);
|
|
1397
|
+
default:
|
|
1398
|
+
throw new Error(
|
|
1399
|
+
`\u26A0\uFE0F Provider "${providerId}" for locale "${targetLocale}" is not supported. Only "groq" and "google" providers are supported at the moment.`
|
|
1400
|
+
);
|
|
1401
|
+
}
|
|
1339
1402
|
}
|
|
1340
1403
|
/**
|
|
1341
1404
|
* Show an actionable error message and exit the process when the compiler
|
|
1342
|
-
* is running in CI/CD without a
|
|
1405
|
+
* is running in CI/CD without a required LLM API key.
|
|
1343
1406
|
* The message explains why this situation is unusual and how to fix it.
|
|
1407
|
+
* @param providerId The ID of the LLM provider whose key is missing.
|
|
1344
1408
|
*/
|
|
1345
|
-
static
|
|
1409
|
+
static _failMissingLLMKeyCi(providerId) {
|
|
1410
|
+
let details = providerDetails[providerId];
|
|
1411
|
+
if (!details) {
|
|
1412
|
+
console.error(
|
|
1413
|
+
`Internal Error: Missing details for provider "${providerId}" when reporting missing key in CI/CD. You might be using an unsupported provider.`
|
|
1414
|
+
);
|
|
1415
|
+
process.exit(1);
|
|
1416
|
+
}
|
|
1346
1417
|
console.log(
|
|
1347
1418
|
dedent2`
|
|
1348
1419
|
\n
|
|
1349
1420
|
💡 You're using Lingo.dev Localization Compiler, and it detected unlocalized components in your app.
|
|
1350
1421
|
|
|
1351
|
-
The compiler needs a
|
|
1422
|
+
The compiler needs a ${details.name} API key to translate missing strings, but ${details.apiKeyEnvVar} is not set in the environment.
|
|
1352
1423
|
|
|
1353
1424
|
This is unexpected: typically you run a full build locally, commit the generated translation files, and push them to CI/CD.
|
|
1354
1425
|
|
|
1355
1426
|
However, If you want CI/CD to translate the new strings, provide the key with:
|
|
1356
|
-
• Session-wide: export
|
|
1357
|
-
• Project-wide / CI: add
|
|
1427
|
+
• Session-wide: export ${details.apiKeyEnvVar}=<your-api-key>
|
|
1428
|
+
• Project-wide / CI: add ${details.apiKeyEnvVar}=<your-api-key> to your pipeline environment variables
|
|
1358
1429
|
|
|
1359
1430
|
⭐️ Also:
|
|
1360
|
-
1. If you don't yet have a
|
|
1361
|
-
2. If you want to use a different LLM,
|
|
1362
|
-
3. If you
|
|
1431
|
+
1. If you don't yet have a ${details.name} API key, get one for free at ${details.getKeyLink}
|
|
1432
|
+
2. If you want to use a different LLM, update your configuration. Refer to documentation for help: https://docs.lingo.dev/
|
|
1433
|
+
3. If the model you want to use isn't supported yet, raise an issue in our open-source repo: https://lingo.dev/go/gh
|
|
1363
1434
|
|
|
1364
1435
|
✨
|
|
1365
1436
|
`
|
|
1366
1437
|
);
|
|
1367
1438
|
process.exit(1);
|
|
1368
1439
|
}
|
|
1369
|
-
|
|
1440
|
+
/**
|
|
1441
|
+
* Show an actionable error message and exit the process when an LLM API call
|
|
1442
|
+
* fails during local compilation.
|
|
1443
|
+
* @param providerId The ID of the LLM provider that failed.
|
|
1444
|
+
* @param targetLocale The target locale being translated to.
|
|
1445
|
+
* @param errorMessage The error message received from the API.
|
|
1446
|
+
*/
|
|
1447
|
+
static _failLLMFailureLocal(providerId, targetLocale, errorMessage) {
|
|
1448
|
+
const details = providerDetails[providerId];
|
|
1449
|
+
if (!details) {
|
|
1450
|
+
console.error(
|
|
1451
|
+
`Internal Error: Missing details for provider "${providerId}" when reporting local failure.`
|
|
1452
|
+
);
|
|
1453
|
+
console.error(`Original Error: ${errorMessage}`);
|
|
1454
|
+
process.exit(1);
|
|
1455
|
+
}
|
|
1370
1456
|
const isInvalidApiKey = errorMessage.match("Invalid API Key");
|
|
1371
1457
|
if (isInvalidApiKey) {
|
|
1372
1458
|
console.log(dedent2`
|
|
1373
1459
|
\n
|
|
1374
|
-
⚠️ Lingo.dev Compiler requires a valid
|
|
1375
|
-
|
|
1376
|
-
It looks like you set
|
|
1460
|
+
⚠️ Lingo.dev Compiler requires a valid ${details.name} API key to translate your application.
|
|
1461
|
+
|
|
1462
|
+
It looks like you set ${details.name} API key but it is not valid. Please check your API key and try again.
|
|
1463
|
+
|
|
1464
|
+
Error details from ${details.name} API: ${errorMessage}
|
|
1377
1465
|
|
|
1378
|
-
Error details from Groq API: ${errorMessage}
|
|
1379
|
-
|
|
1380
1466
|
👉 You can set the API key in one of the following ways:
|
|
1381
|
-
1. User-wide: Run npx lingo.dev@latest config set
|
|
1382
|
-
2. Project-wide: Add
|
|
1383
|
-
3
|
|
1384
|
-
|
|
1467
|
+
1. User-wide: Run npx lingo.dev@latest config set ${details.apiKeyConfigKey} <your-api-key>
|
|
1468
|
+
2. Project-wide: Add ${details.apiKeyEnvVar}=<your-api-key> to .env file in every project that uses Lingo.dev Localization Compiler
|
|
1469
|
+
3 Session-wide: Run export ${details.apiKeyEnvVar}=<your-api-key> in your terminal before running the compiler to set the API key for the current session
|
|
1470
|
+
|
|
1385
1471
|
⭐️ Also:
|
|
1386
|
-
1. If you don't yet have a
|
|
1472
|
+
1. If you don't yet have a ${details.name} API key, get one for free at ${details.getKeyLink}
|
|
1387
1473
|
2. If you want to use a different LLM, raise an issue in our open-source repo: https://lingo.dev/go/gh
|
|
1388
1474
|
3. If you have questions, feature requests, or would like to contribute, join our Discord: https://lingo.dev/go/discord
|
|
1389
|
-
|
|
1475
|
+
|
|
1390
1476
|
✨
|
|
1391
1477
|
`);
|
|
1392
1478
|
} else {
|
|
1393
1479
|
console.log(
|
|
1394
1480
|
dedent2`
|
|
1395
1481
|
\n
|
|
1396
|
-
⚠️ Lingo.dev Compiler tried to translate your application to "${targetLocale}" locale via
|
|
1482
|
+
⚠️ Lingo.dev Compiler tried to translate your application to "${targetLocale}" locale via ${details.name} but it failed.
|
|
1397
1483
|
|
|
1398
|
-
Error details from
|
|
1484
|
+
Error details from ${details.name} API: ${errorMessage}
|
|
1399
1485
|
|
|
1400
|
-
This error comes from
|
|
1486
|
+
This error comes from the ${details.name} API, please check their documentation for more details: ${details.docsLink}
|
|
1401
1487
|
|
|
1402
1488
|
⭐️ Also:
|
|
1403
|
-
1. Did you set
|
|
1404
|
-
2. Did you reach any limits of your
|
|
1489
|
+
1. Did you set ${details.apiKeyEnvVar} environment variable correctly?
|
|
1490
|
+
2. Did you reach any limits of your ${details.name} account?
|
|
1405
1491
|
3. If you have questions, feature requests, or would like to contribute, join our Discord: https://lingo.dev/go/discord
|
|
1406
1492
|
|
|
1407
1493
|
✨
|
|
@@ -2384,13 +2470,23 @@ var clientDictionaryLoaderMutation = createCodeMutation((payload) => {
|
|
|
2384
2470
|
});
|
|
2385
2471
|
|
|
2386
2472
|
// src/index.ts
|
|
2473
|
+
var keyCheckers = {
|
|
2474
|
+
groq: {
|
|
2475
|
+
checkEnv: getGroqKeyFromEnv,
|
|
2476
|
+
checkRc: getGroqKeyFromRc
|
|
2477
|
+
},
|
|
2478
|
+
google: {
|
|
2479
|
+
checkEnv: getGoogleKeyFromEnv,
|
|
2480
|
+
checkRc: getGoogleKeyFromRc
|
|
2481
|
+
}
|
|
2482
|
+
};
|
|
2387
2483
|
var unplugin = createUnplugin(
|
|
2388
2484
|
(_params, _meta) => {
|
|
2389
2485
|
console.log("\u2139\uFE0F Starting Lingo.dev compiler...");
|
|
2486
|
+
const params = _11.defaults(_params, defaultParams);
|
|
2390
2487
|
if (!isRunningInCIOrDocker()) {
|
|
2391
|
-
|
|
2488
|
+
validateLLMKeyDetails(params.models);
|
|
2392
2489
|
}
|
|
2393
|
-
const params = _11.defaults(_params, defaultParams);
|
|
2394
2490
|
const invalidLocales = getInvalidLocales(
|
|
2395
2491
|
params.models,
|
|
2396
2492
|
params.sourceLocale,
|
|
@@ -2405,7 +2501,7 @@ var unplugin = createUnplugin(
|
|
|
2405
2501
|
1. Refer to documentation for help: https://docs.lingo.dev/
|
|
2406
2502
|
2. If you want to use a different LLM, raise an issue in our open-source repo: https://lingo.dev/go/gh
|
|
2407
2503
|
3. If you have questions, feature requests, or would like to contribute, join our Discord: https://lingo.dev/go/discord
|
|
2408
|
-
|
|
2504
|
+
|
|
2409
2505
|
✨
|
|
2410
2506
|
`);
|
|
2411
2507
|
process.exit(1);
|
|
@@ -2504,56 +2600,81 @@ var src_default = {
|
|
|
2504
2600
|
return config2;
|
|
2505
2601
|
}
|
|
2506
2602
|
};
|
|
2507
|
-
function
|
|
2508
|
-
const
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2603
|
+
function validateLLMKeyDetails(models) {
|
|
2604
|
+
const configuredProviders = _11.chain(Object.values(models)).map((modelString) => modelString.split(":")[0]).filter(Boolean).uniq().filter(
|
|
2605
|
+
(providerId) => providerDetails.hasOwnProperty(providerId) && keyCheckers.hasOwnProperty(providerId)
|
|
2606
|
+
).value();
|
|
2607
|
+
if (configuredProviders.length === 0) {
|
|
2608
|
+
return;
|
|
2609
|
+
}
|
|
2610
|
+
const keyStatuses = {};
|
|
2611
|
+
const missingProviders = [];
|
|
2612
|
+
const foundProviders = [];
|
|
2613
|
+
for (const providerId of configuredProviders) {
|
|
2614
|
+
const details = providerDetails[providerId];
|
|
2615
|
+
const checkers = keyCheckers[providerId];
|
|
2616
|
+
if (!details || !checkers) continue;
|
|
2617
|
+
const foundInEnv = checkers.checkEnv() !== void 0;
|
|
2618
|
+
const foundInRc = checkers.checkRc() !== void 0;
|
|
2619
|
+
keyStatuses[providerId] = { foundInEnv, foundInRc, details };
|
|
2620
|
+
if (!foundInEnv && !foundInRc) {
|
|
2621
|
+
missingProviders.push(providerId);
|
|
2622
|
+
} else {
|
|
2623
|
+
foundProviders.push(providerId);
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
if (missingProviders.length > 0) {
|
|
2513
2627
|
console.log(dedent3`
|
|
2514
2628
|
\n
|
|
2515
|
-
💡
|
|
2629
|
+
💡 Lingo.dev Localization Compiler is configured to use the following LLM provider(s): ${configuredProviders.join(", ")}.
|
|
2630
|
+
|
|
2631
|
+
The compiler requires API keys for these providers to work, but the following keys are missing:
|
|
2632
|
+
`);
|
|
2633
|
+
for (const providerId of missingProviders) {
|
|
2634
|
+
const status = keyStatuses[providerId];
|
|
2635
|
+
if (!status) continue;
|
|
2636
|
+
console.log(dedent3`
|
|
2637
|
+
⚠️ ${status.details.name} API key is missing. Set ${status.details.apiKeyEnvVar} environment variable.
|
|
2516
2638
|
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2639
|
+
👉 You can set the API key in one of the following ways:
|
|
2640
|
+
1. User-wide: Run npx lingo.dev@latest config set ${status.details.apiKeyConfigKey || "<config-key-not-available>"} <your-api-key>
|
|
2641
|
+
2. Project-wide: Add ${status.details.apiKeyEnvVar}=<your-api-key> to .env file in every project that uses Lingo.dev Localization Compiler
|
|
2642
|
+
3. Session-wide: Run export ${status.details.apiKeyEnvVar}=<your-api-key> in your terminal before running the compiler to set the API key for the current session
|
|
2521
2643
|
|
|
2644
|
+
⭐️ If you don't yet have a ${status.details.name} API key, get one for free at ${status.details.getKeyLink}
|
|
2645
|
+
`);
|
|
2646
|
+
}
|
|
2647
|
+
console.log(dedent3`
|
|
2648
|
+
\n
|
|
2522
2649
|
⭐️ Also:
|
|
2523
|
-
1. If you
|
|
2524
|
-
2. If you want to use
|
|
2650
|
+
1. If you want to use a different LLM, update your configuration. Refer to documentation for help: https://docs.lingo.dev/
|
|
2651
|
+
2. If the model/provider you want to use isn't supported yet, raise an issue in our open-source repo: https://lingo.dev/go/gh
|
|
2525
2652
|
3. If you have questions, feature requests, or would like to contribute, join our Discord: https://lingo.dev/go/discord
|
|
2526
2653
|
|
|
2527
2654
|
✨
|
|
2528
2655
|
`);
|
|
2529
2656
|
process.exit(1);
|
|
2530
|
-
} else if (
|
|
2531
|
-
console.log(
|
|
2532
|
-
|
|
2533
|
-
🔑
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
);
|
|
2551
|
-
} else if (!groq.fromEnv && groq.fromRc) {
|
|
2552
|
-
console.log(
|
|
2553
|
-
dedent3`
|
|
2554
|
-
🔑 GROQ API key loaded from your user-wide configuration.
|
|
2555
|
-
`
|
|
2556
|
-
);
|
|
2657
|
+
} else if (foundProviders.length > 0) {
|
|
2658
|
+
console.log(dedent3`
|
|
2659
|
+
\n
|
|
2660
|
+
🔑 LLM API keys detected for configured providers: ${foundProviders.join(", ")}.
|
|
2661
|
+
`);
|
|
2662
|
+
for (const providerId of foundProviders) {
|
|
2663
|
+
const status = keyStatuses[providerId];
|
|
2664
|
+
if (!status) continue;
|
|
2665
|
+
let sourceMessage = "";
|
|
2666
|
+
if (status.foundInEnv && status.foundInRc) {
|
|
2667
|
+
sourceMessage = `from both environment variables (${status.details.apiKeyEnvVar}) and your user-wide configuration. The key from the environment will be used because it has higher priority.`;
|
|
2668
|
+
} else if (status.foundInEnv) {
|
|
2669
|
+
sourceMessage = `from environment variables (${status.details.apiKeyEnvVar}).`;
|
|
2670
|
+
} else if (status.foundInRc) {
|
|
2671
|
+
sourceMessage = `from your user-wide configuration${status.details.apiKeyConfigKey ? ` (${status.details.apiKeyConfigKey})` : ""}.`;
|
|
2672
|
+
}
|
|
2673
|
+
console.log(dedent3`
|
|
2674
|
+
• ${status.details.name} API key loaded ${sourceMessage}
|
|
2675
|
+
`);
|
|
2676
|
+
}
|
|
2677
|
+
console.log("\u2728");
|
|
2557
2678
|
}
|
|
2558
2679
|
}
|
|
2559
2680
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lingo.dev/_compiler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Lingo.dev Compiler",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"typescript": "^5.4.5"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
+
"@ai-sdk/google": "^1.2.19",
|
|
32
33
|
"@ai-sdk/groq": "^1.2.3",
|
|
33
34
|
"@babel/generator": "^7.26.5",
|
|
34
35
|
"@babel/parser": "^7.26.7",
|