@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.
Files changed (3) hide show
  1. package/build/index.cjs +259 -138
  2. package/build/index.mjs +259 -138
  3. 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.1.13",
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/groq.ts
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
- const rc = getRc();
1161
- const result = _lodash2.default.get(rc, "llm.groqApiKey");
1162
- return result;
1172
+ return getKeyFromRc("llm.groqApiKey");
1163
1173
  }
1164
1174
  function getGroqKeyFromEnv() {
1165
- const ephemeralEnv = {};
1166
- dotenv.config({ processEnv: ephemeralEnv });
1167
- return ephemeralEnv.GROQ_API_KEY;
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
- if (provider !== "groq") {
1300
- throw new Error(
1301
- `\u26A0\uFE0F Provider ${provider} is not supported. Only "groq" provider is supported at the moment.`
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
- console.log(
1305
- `\u2728 Using model "${model}" from "${provider}" to translate from "${sourceLocale}" to "${targetLocale}"`
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: "user",
1319
- content: obj2xml(shotsTuple[0])
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: "assistant",
1323
- content: obj2xml(shotsTuple[1])
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
- console.log("Response", response.text);
1333
- let responseText = response.text;
1334
- responseText = responseText.substring(
1335
- responseText.indexOf("<"),
1336
- responseText.lastIndexOf(">") + 1
1337
- );
1338
- return xml2obj(responseText);
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 GROQ API key.
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 _failMissingGroqKeyCi() {
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 GROQ API key to translate missing strings, but GROQ_API_KEY is not set in the environment.
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 GROQ_API_KEY=<your-api-key>
1357
- • Project-wide / CI: add GROQ_API_KEY=<your-api-key> to your pipeline environment variables
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 GROQ API key, get one for free at https://groq.com
1361
- 2. If you want to use a different LLM, raise an issue in our open-source repo: https://lingo.dev/go/gh
1362
- 3. If you have questions, feature requests, or would like to contribute, join our Discord: https://lingo.dev/go/discord
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
- static _failGroqFailureLocal(targetLocale, errorMessage) {
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 Groq API key to translate your application.
1375
-
1376
- It looks like you set Groq API key but it is not valid. Please check your API key and try again.
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 llm.groqApiKey <your-api-key>
1382
- 2. Project-wide: Add GROQ_API_KEY=<your-api-key> to .env file in every project that uses Lingo.dev Localization Compiler
1383
- 3. Session-wide: Run export GROQ_API_KEY=<your-api-key> in your terminal before running the compiler to set the API key for the current session
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 GROQ API key, get one for free at https://groq.com
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 Groq but it failed.
1482
+ ⚠️ Lingo.dev Compiler tried to translate your application to "${targetLocale}" locale via ${details.name} but it failed.
1397
1483
 
1398
- Error details from Groq API: ${errorMessage}
1484
+ Error details from ${details.name} API: ${errorMessage}
1399
1485
 
1400
- This error comes from Groq API, please check their documentation for more details: https://console.groq.com/docs/errors
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 GROQ_API_KEY environment variable?
1404
- 2. Did you reach any limits of your Groq account?
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
- validateGroqKeyDetails();
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 validateGroqKeyDetails() {
2508
- const groq = {
2509
- fromEnv: getGroqKeyFromEnv(),
2510
- fromRc: getGroqKeyFromRc()
2511
- };
2512
- if (!groq.fromEnv && !groq.fromRc) {
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
- 💡 You're using Lingo.dev Localization Compiler in your project, which requires a GROQ API key to work.
2629
+ 💡 Lingo.dev Localization Compiler is configured to use the following LLM provider(s): ${configuredProviders.join(", ")}.
2516
2630
 
2517
- 👉 You can set the API key in one of the following ways:
2518
- 1. User-wide: Run npx lingo.dev@latest config set llm.groqApiKey <your-api-key>
2519
- 2. Project-wide: Add GROQ_API_KEY=<your-api-key> to .env file in every project that uses Lingo.dev Localization Compiler
2520
- 3. Session-wide: Run export GROQ_API_KEY=<your-api-key> in your terminal before running the compiler to set the API key for the current session
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 don't yet have a GROQ API key, get one for free at https://groq.com
2524
- 2. If you want to use a different LLM, raise an issue in our open-source repo: https://lingo.dev/go/gh
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 (groq.fromEnv && groq.fromRc) {
2531
- console.log(
2532
- _dedent2.default`
2533
- 🔑 GROQ API key detected in both environment variables and your user-wide configuration.
2534
-
2535
- 👉 The compiler will use the key from the environment because it has higher priority.
2536
-
2537
- To update the user-wide key run: npx lingo.dev@latest config set llm.groqApiKey <your-api-key>
2538
- To remove it run: npx lingo.dev@latest config unset llm.groqApiKey
2539
- To remove the env variable from the current session run: unset GROQ_API_KEY
2540
- `
2541
- );
2542
- } else if (groq.fromEnv && !groq.fromRc) {
2543
- console.log(
2544
- _dedent2.default`
2545
- 🔑 GROQ API key loaded from environment variables.
2546
-
2547
- You can also save the key user-wide with: npx lingo.dev@latest config set llm.groqApiKey <your-api-key>
2548
- • Or remove the env variable from the current session with: unset GROQ_API_KEY
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.1.13",
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/groq.ts
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
- const rc = getRc();
1161
- const result = _5.get(rc, "llm.groqApiKey");
1162
- return result;
1172
+ return getKeyFromRc("llm.groqApiKey");
1163
1173
  }
1164
1174
  function getGroqKeyFromEnv() {
1165
- const ephemeralEnv = {};
1166
- dotenv.config({ processEnv: ephemeralEnv });
1167
- return ephemeralEnv.GROQ_API_KEY;
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
- if (provider !== "groq") {
1300
- throw new Error(
1301
- `\u26A0\uFE0F Provider ${provider} is not supported. Only "groq" provider is supported at the moment.`
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
- console.log(
1305
- `\u2728 Using model "${model}" from "${provider}" to translate from "${sourceLocale}" to "${targetLocale}"`
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: "user",
1319
- content: obj2xml(shotsTuple[0])
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: "assistant",
1323
- content: obj2xml(shotsTuple[1])
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
- console.log("Response", response.text);
1333
- let responseText = response.text;
1334
- responseText = responseText.substring(
1335
- responseText.indexOf("<"),
1336
- responseText.lastIndexOf(">") + 1
1337
- );
1338
- return xml2obj(responseText);
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 GROQ API key.
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 _failMissingGroqKeyCi() {
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 GROQ API key to translate missing strings, but GROQ_API_KEY is not set in the environment.
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 GROQ_API_KEY=<your-api-key>
1357
- • Project-wide / CI: add GROQ_API_KEY=<your-api-key> to your pipeline environment variables
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 GROQ API key, get one for free at https://groq.com
1361
- 2. If you want to use a different LLM, raise an issue in our open-source repo: https://lingo.dev/go/gh
1362
- 3. If you have questions, feature requests, or would like to contribute, join our Discord: https://lingo.dev/go/discord
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
- static _failGroqFailureLocal(targetLocale, errorMessage) {
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 Groq API key to translate your application.
1375
-
1376
- It looks like you set Groq API key but it is not valid. Please check your API key and try again.
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 llm.groqApiKey <your-api-key>
1382
- 2. Project-wide: Add GROQ_API_KEY=<your-api-key> to .env file in every project that uses Lingo.dev Localization Compiler
1383
- 3. Session-wide: Run export GROQ_API_KEY=<your-api-key> in your terminal before running the compiler to set the API key for the current session
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 GROQ API key, get one for free at https://groq.com
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 Groq but it failed.
1482
+ ⚠️ Lingo.dev Compiler tried to translate your application to "${targetLocale}" locale via ${details.name} but it failed.
1397
1483
 
1398
- Error details from Groq API: ${errorMessage}
1484
+ Error details from ${details.name} API: ${errorMessage}
1399
1485
 
1400
- This error comes from Groq API, please check their documentation for more details: https://console.groq.com/docs/errors
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 GROQ_API_KEY environment variable?
1404
- 2. Did you reach any limits of your Groq account?
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
- validateGroqKeyDetails();
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 validateGroqKeyDetails() {
2508
- const groq = {
2509
- fromEnv: getGroqKeyFromEnv(),
2510
- fromRc: getGroqKeyFromRc()
2511
- };
2512
- if (!groq.fromEnv && !groq.fromRc) {
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
- 💡 You're using Lingo.dev Localization Compiler in your project, which requires a GROQ API key to work.
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
- 👉 You can set the API key in one of the following ways:
2518
- 1. User-wide: Run npx lingo.dev@latest config set llm.groqApiKey <your-api-key>
2519
- 2. Project-wide: Add GROQ_API_KEY=<your-api-key> to .env file in every project that uses Lingo.dev Localization Compiler
2520
- 3. Session-wide: Run export GROQ_API_KEY=<your-api-key> in your terminal before running the compiler to set the API key for the current session
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 don't yet have a GROQ API key, get one for free at https://groq.com
2524
- 2. If you want to use a different LLM, raise an issue in our open-source repo: https://lingo.dev/go/gh
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 (groq.fromEnv && groq.fromRc) {
2531
- console.log(
2532
- dedent3`
2533
- 🔑 GROQ API key detected in both environment variables and your user-wide configuration.
2534
-
2535
- 👉 The compiler will use the key from the environment because it has higher priority.
2536
-
2537
- To update the user-wide key run: npx lingo.dev@latest config set llm.groqApiKey <your-api-key>
2538
- To remove it run: npx lingo.dev@latest config unset llm.groqApiKey
2539
- To remove the env variable from the current session run: unset GROQ_API_KEY
2540
- `
2541
- );
2542
- } else if (groq.fromEnv && !groq.fromRc) {
2543
- console.log(
2544
- dedent3`
2545
- 🔑 GROQ API key loaded from environment variables.
2546
-
2547
- You can also save the key user-wide with: npx lingo.dev@latest config set llm.groqApiKey <your-api-key>
2548
- • Or remove the env variable from the current session with: unset GROQ_API_KEY
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.1.13",
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",