fluxflow-cli 1.21.0 → 1.21.1
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/dist/fluxflow.js +147 -10
- package/package.json +1 -1
package/dist/fluxflow.js
CHANGED
|
@@ -1859,6 +1859,8 @@ function SettingsMenu({
|
|
|
1859
1859
|
setEditValue(systemSettings.autoDisallowCommands || "");
|
|
1860
1860
|
} else if (item.value === "apiTier") {
|
|
1861
1861
|
setActiveView("apiTier");
|
|
1862
|
+
} else if (item.value === "aiProvider") {
|
|
1863
|
+
setActiveView("selectProvider");
|
|
1862
1864
|
} else if (item.value === "autoDelete") {
|
|
1863
1865
|
const options = ["1d", "7d", "30d"];
|
|
1864
1866
|
const currentIndex = options.indexOf(systemSettings.autoDeleteHistory || "30d");
|
|
@@ -2283,18 +2285,20 @@ var init_paths = __esm({
|
|
|
2283
2285
|
var secrets_exports = {};
|
|
2284
2286
|
__export(secrets_exports, {
|
|
2285
2287
|
getAPIKey: () => getAPIKey,
|
|
2288
|
+
getProviderAPIKey: () => getProviderAPIKey,
|
|
2286
2289
|
getSearchSecrets: () => getSearchSecrets,
|
|
2287
2290
|
getSecret: () => getSecret,
|
|
2288
2291
|
removeAPIKey: () => removeAPIKey,
|
|
2289
2292
|
removeSecret: () => removeSecret,
|
|
2290
2293
|
saveAPIKey: () => saveAPIKey,
|
|
2294
|
+
saveProviderAPIKey: () => saveProviderAPIKey,
|
|
2291
2295
|
saveSearchId: () => saveSearchId,
|
|
2292
2296
|
saveSearchKey: () => saveSearchKey,
|
|
2293
2297
|
saveSecret: () => saveSecret
|
|
2294
2298
|
});
|
|
2295
2299
|
import fs3 from "fs-extra";
|
|
2296
2300
|
import path3 from "path";
|
|
2297
|
-
var SECRET_FILE, getAPIKey, getSecret, saveSecret, getSearchSecrets, saveAPIKey, saveSearchKey, saveSearchId, removeSecret, removeAPIKey;
|
|
2301
|
+
var SECRET_FILE, getAPIKey, getProviderAPIKey, saveProviderAPIKey, getSecret, saveSecret, getSearchSecrets, saveAPIKey, saveSearchKey, saveSearchId, removeSecret, removeAPIKey;
|
|
2298
2302
|
var init_secrets = __esm({
|
|
2299
2303
|
"src/utils/secrets.js"() {
|
|
2300
2304
|
init_crypto();
|
|
@@ -2308,6 +2312,26 @@ var init_secrets = __esm({
|
|
|
2308
2312
|
}
|
|
2309
2313
|
return null;
|
|
2310
2314
|
};
|
|
2315
|
+
getProviderAPIKey = async (provider) => {
|
|
2316
|
+
try {
|
|
2317
|
+
const secrets = readEncryptedJson(SECRET_FILE, {});
|
|
2318
|
+
if (provider === "Google") return secrets.GOOGLE_API_KEY || secrets.API_KEY || null;
|
|
2319
|
+
if (provider === "DeepSeek") return secrets.DEEPSEEK_API_KEY || null;
|
|
2320
|
+
if (provider === "OpenRouter") return secrets.OPENROUTER_API_KEY || null;
|
|
2321
|
+
} catch (e) {
|
|
2322
|
+
}
|
|
2323
|
+
return null;
|
|
2324
|
+
};
|
|
2325
|
+
saveProviderAPIKey = async (provider, key) => {
|
|
2326
|
+
if (provider === "Google") {
|
|
2327
|
+
await saveSecret("GOOGLE_API_KEY", key);
|
|
2328
|
+
await saveSecret("API_KEY", key);
|
|
2329
|
+
} else if (provider === "DeepSeek") {
|
|
2330
|
+
await saveSecret("DEEPSEEK_API_KEY", key);
|
|
2331
|
+
} else if (provider === "OpenRouter") {
|
|
2332
|
+
await saveSecret("OPENROUTER_API_KEY", key);
|
|
2333
|
+
}
|
|
2334
|
+
};
|
|
2311
2335
|
getSecret = async (key) => {
|
|
2312
2336
|
try {
|
|
2313
2337
|
const secrets = readEncryptedJson(SECRET_FILE, {});
|
|
@@ -5075,7 +5099,7 @@ var init_ai = __esm({
|
|
|
5075
5099
|
} catch (e) {
|
|
5076
5100
|
}
|
|
5077
5101
|
}
|
|
5078
|
-
if (Date.now() - lastFlushTime >=
|
|
5102
|
+
if (Date.now() - lastFlushTime >= 100 && hasNewData) {
|
|
5079
5103
|
yield {
|
|
5080
5104
|
candidates: pendingParts.length > 0 ? [{ content: { parts: [...pendingParts] } }] : [],
|
|
5081
5105
|
usageMetadata: latestUsageMetadata
|
|
@@ -5212,7 +5236,7 @@ var init_ai = __esm({
|
|
|
5212
5236
|
} catch (e) {
|
|
5213
5237
|
}
|
|
5214
5238
|
}
|
|
5215
|
-
if (Date.now() - lastFlushTime >=
|
|
5239
|
+
if (Date.now() - lastFlushTime >= 100 && hasNewData) {
|
|
5216
5240
|
yield {
|
|
5217
5241
|
candidates: pendingParts.length > 0 ? [{ content: { parts: [...pendingParts] } }] : [],
|
|
5218
5242
|
usageMetadata: latestUsageMetadata
|
|
@@ -6372,6 +6396,8 @@ ${thinkingLevel != "Fast" && aiProvider === "Google" ? `${modelName.toLowerCase(
|
|
|
6372
6396
|
yield { type: "status", content: "Working..." };
|
|
6373
6397
|
dedupeBuffer = "";
|
|
6374
6398
|
isDedupeActive = accumulatedContext.length > 0;
|
|
6399
|
+
let pendingGoogleText = "";
|
|
6400
|
+
let lastGoogleFlushTime = Date.now();
|
|
6375
6401
|
for await (const chunk of stream) {
|
|
6376
6402
|
if (TERMINATION_SIGNAL) {
|
|
6377
6403
|
yield { type: "status", content: "Termination Signal Received." };
|
|
@@ -6424,7 +6450,11 @@ ${thinkingLevel != "Fast" && aiProvider === "Google" ? `${modelName.toLowerCase(
|
|
|
6424
6450
|
const dedupeClean = hasOpenThink ? cleanText.replace(/^\s*(?:<(think|thought)>|\[(think|thought)\])\s*/gi, "") : cleanText.replace(/^\s*(?:<(think|thought)>|\[(think|thought)\])[\s\S]*?(?:<\/(think|thought)>|\[\/(think|thought)\])\s*/gi, "").replace(/^\s*(?:<(think|thought)>|\[(think|thought)\])\s*/gi, "");
|
|
6425
6451
|
if (dedupeClean) {
|
|
6426
6452
|
turnText += dedupeClean;
|
|
6427
|
-
|
|
6453
|
+
if (aiProvider === "Google") {
|
|
6454
|
+
pendingGoogleText += dedupeClean;
|
|
6455
|
+
} else {
|
|
6456
|
+
yield { type: "text", content: dedupeClean };
|
|
6457
|
+
}
|
|
6428
6458
|
}
|
|
6429
6459
|
}
|
|
6430
6460
|
isDedupeActive = false;
|
|
@@ -6433,7 +6463,11 @@ ${thinkingLevel != "Fast" && aiProvider === "Google" ? `${modelName.toLowerCase(
|
|
|
6433
6463
|
continue;
|
|
6434
6464
|
} else {
|
|
6435
6465
|
turnText += chunkText;
|
|
6436
|
-
|
|
6466
|
+
if (aiProvider === "Google") {
|
|
6467
|
+
pendingGoogleText += chunkText;
|
|
6468
|
+
} else {
|
|
6469
|
+
yield { type: "text", content: chunkText };
|
|
6470
|
+
}
|
|
6437
6471
|
}
|
|
6438
6472
|
const signalSafeText3 = getSanitizedText(turnText);
|
|
6439
6473
|
const toolContext = getActiveToolContext(turnText);
|
|
@@ -6914,6 +6948,11 @@ ${boxBottom}` };
|
|
|
6914
6948
|
if (normToolName === "memory" && result.includes("SUCCESS")) yield { type: "memory_updated" };
|
|
6915
6949
|
toolCallPointer++;
|
|
6916
6950
|
}
|
|
6951
|
+
if (aiProvider === "Google" && pendingGoogleText && Date.now() - lastGoogleFlushTime >= 100) {
|
|
6952
|
+
yield { type: "text", content: pendingGoogleText };
|
|
6953
|
+
pendingGoogleText = "";
|
|
6954
|
+
lastGoogleFlushTime = Date.now();
|
|
6955
|
+
}
|
|
6917
6956
|
}
|
|
6918
6957
|
if (chunk.usageMetadata) {
|
|
6919
6958
|
lastUsage = chunk.usageMetadata;
|
|
@@ -6928,7 +6967,11 @@ ${boxBottom}` };
|
|
|
6928
6967
|
dedupeBuffer += "</think>";
|
|
6929
6968
|
} else {
|
|
6930
6969
|
turnText += "</think>";
|
|
6931
|
-
|
|
6970
|
+
if (aiProvider === "Google") {
|
|
6971
|
+
pendingGoogleText += "</think>";
|
|
6972
|
+
} else {
|
|
6973
|
+
yield { type: "text", content: "</think>" };
|
|
6974
|
+
}
|
|
6932
6975
|
}
|
|
6933
6976
|
}
|
|
6934
6977
|
if (isDedupeActive && dedupeBuffer.length > 0) {
|
|
@@ -6946,12 +6989,20 @@ ${boxBottom}` };
|
|
|
6946
6989
|
const dedupeClean = hasOpenThink ? cleanText.replace(/^\s*(?:<(think|thought)>|\[(think|thought)\])\s*/gi, "") : cleanText.replace(/^\s*(?:<(think|thought)>|\[(think|thought)\])[\s\S]*?(?:<\/(think|thought)>|\[\/(think|thought)\])\s*/gi, "").replace(/^\s*(?:<(think|thought)>|\[(think|thought)\])\s*/gi, "");
|
|
6947
6990
|
if (dedupeClean) {
|
|
6948
6991
|
turnText += dedupeClean;
|
|
6949
|
-
|
|
6992
|
+
if (aiProvider === "Google") {
|
|
6993
|
+
pendingGoogleText += dedupeClean;
|
|
6994
|
+
} else {
|
|
6995
|
+
yield { type: "text", content: dedupeClean };
|
|
6996
|
+
}
|
|
6950
6997
|
}
|
|
6951
6998
|
}
|
|
6952
6999
|
isDedupeActive = false;
|
|
6953
7000
|
dedupeBuffer = "";
|
|
6954
7001
|
}
|
|
7002
|
+
if (aiProvider === "Google" && pendingGoogleText) {
|
|
7003
|
+
yield { type: "text", content: pendingGoogleText };
|
|
7004
|
+
pendingGoogleText = "";
|
|
7005
|
+
}
|
|
6955
7006
|
if (TERMINATION_SIGNAL) break;
|
|
6956
7007
|
const signalSafeText2 = (turnText || "").trim();
|
|
6957
7008
|
const hasFinish2 = /\[\s*(turn\s*:)?\s*finish\s*\]/i.test(signalSafeText2.toLowerCase());
|
|
@@ -8201,7 +8252,8 @@ function App({ args = [] }) {
|
|
|
8201
8252
|
setSystemSettings(freshSettings);
|
|
8202
8253
|
setProfileData(saved.profileData);
|
|
8203
8254
|
setImageSettings(saved.imageSettings || { keyType: "Default", quality: "Low-High", apiKey: "" });
|
|
8204
|
-
const
|
|
8255
|
+
const startupProvider = saved.aiProvider || "Google";
|
|
8256
|
+
const key = await getProviderAPIKey(startupProvider);
|
|
8205
8257
|
if (key) {
|
|
8206
8258
|
setApiKey(key);
|
|
8207
8259
|
initAI(key);
|
|
@@ -8284,7 +8336,7 @@ function App({ args = [] }) {
|
|
|
8284
8336
|
if (aiProvider === "OpenRouter") minLength = 10;
|
|
8285
8337
|
if (aiProvider === "DeepSeek") minLength = 20;
|
|
8286
8338
|
if (key.length >= minLength) {
|
|
8287
|
-
await
|
|
8339
|
+
await saveProviderAPIKey(aiProvider, key);
|
|
8288
8340
|
setApiKey(key);
|
|
8289
8341
|
initAI(key);
|
|
8290
8342
|
let defaultModel = "gemma-4-31b-it";
|
|
@@ -8390,7 +8442,19 @@ function App({ args = [] }) {
|
|
|
8390
8442
|
{ cmd: "Fast", desc: "Fastest" },
|
|
8391
8443
|
{ cmd: "Standard", desc: "Standard Reasoning" },
|
|
8392
8444
|
{ cmd: "xHigh", desc: "Extended Reasoning" }
|
|
8445
|
+
] : aiProvider === "OpenRouter" ? [
|
|
8446
|
+
{ cmd: "Fast", desc: "Fastest" },
|
|
8447
|
+
{ cmd: "Low", desc: "Quick Reasoning" },
|
|
8448
|
+
{ cmd: "Medium", desc: "Balanced Reasoning" },
|
|
8449
|
+
{ cmd: "High", desc: "Deep Reasoning" },
|
|
8450
|
+
{ cmd: "xHigh", desc: "Extended Reasoning" }
|
|
8451
|
+
] : activeModel && activeModel.toLowerCase().startsWith("gemini-3") ? [
|
|
8452
|
+
{ cmd: "Fast", desc: "Fastest" },
|
|
8453
|
+
{ cmd: "Low", desc: "Quick Reasoning" },
|
|
8454
|
+
{ cmd: "Medium", desc: "Balanced Reasoning" },
|
|
8455
|
+
{ cmd: "High", desc: "Deep Reasoning" }
|
|
8393
8456
|
] : [
|
|
8457
|
+
// Google General / Gemma
|
|
8394
8458
|
{ cmd: "Fast", desc: "Fastest" },
|
|
8395
8459
|
{ cmd: "Low", desc: "Quick Reasoning" },
|
|
8396
8460
|
{ cmd: "Medium", desc: "Balanced Reasoning" },
|
|
@@ -9656,6 +9720,59 @@ Selection: ${val}`,
|
|
|
9656
9720
|
aiProvider
|
|
9657
9721
|
}
|
|
9658
9722
|
);
|
|
9723
|
+
case "selectProvider":
|
|
9724
|
+
return /* @__PURE__ */ React13.createElement(
|
|
9725
|
+
CommandMenu,
|
|
9726
|
+
{
|
|
9727
|
+
title: "SELECT AI PROVIDER",
|
|
9728
|
+
items: [
|
|
9729
|
+
{ label: "Google (Free/Paid)", value: "Google" },
|
|
9730
|
+
{ label: "DeepSeek (Paid)", value: "DeepSeek" },
|
|
9731
|
+
{ label: "OpenRouter (Free/Paid) [EXPERIMENTAL]", value: "OpenRouter" },
|
|
9732
|
+
{ label: "Back", value: "settings" }
|
|
9733
|
+
],
|
|
9734
|
+
onSelect: async (item) => {
|
|
9735
|
+
if (item.value === "settings" || item.value === "Back") {
|
|
9736
|
+
setActiveView("settings");
|
|
9737
|
+
return;
|
|
9738
|
+
}
|
|
9739
|
+
const selectedProvider = item.value;
|
|
9740
|
+
const key = await getProviderAPIKey(selectedProvider);
|
|
9741
|
+
if (key) {
|
|
9742
|
+
setAiProvider(selectedProvider);
|
|
9743
|
+
setApiKey(key);
|
|
9744
|
+
initAI(key);
|
|
9745
|
+
let defaultModel = "gemma-4-31b-it";
|
|
9746
|
+
if (selectedProvider === "OpenRouter") {
|
|
9747
|
+
defaultModel = "google/gemma-4-31b-it:free";
|
|
9748
|
+
} else if (selectedProvider === "DeepSeek") {
|
|
9749
|
+
defaultModel = "deepseek-v4-flash";
|
|
9750
|
+
}
|
|
9751
|
+
setActiveModel(defaultModel);
|
|
9752
|
+
saveSettings({ aiProvider: selectedProvider, activeModel: defaultModel, apiTier, quotas });
|
|
9753
|
+
setMessages((prev) => [
|
|
9754
|
+
...prev,
|
|
9755
|
+
{
|
|
9756
|
+
role: "system",
|
|
9757
|
+
text: `\u2705 Switched to ${selectedProvider}! Key loaded from Vault. Model set to ${defaultModel}.`,
|
|
9758
|
+
isMeta: true
|
|
9759
|
+
}
|
|
9760
|
+
]);
|
|
9761
|
+
setActiveView("settings");
|
|
9762
|
+
} else {
|
|
9763
|
+
setInputConfig({
|
|
9764
|
+
label: `Enter ${selectedProvider} API Key:`,
|
|
9765
|
+
key: "providerKey",
|
|
9766
|
+
provider: selectedProvider,
|
|
9767
|
+
value: "",
|
|
9768
|
+
returnView: "settings"
|
|
9769
|
+
});
|
|
9770
|
+
setActiveView("input");
|
|
9771
|
+
}
|
|
9772
|
+
},
|
|
9773
|
+
onClose: () => setActiveView("settings")
|
|
9774
|
+
}
|
|
9775
|
+
);
|
|
9659
9776
|
case "apiTier":
|
|
9660
9777
|
return /* @__PURE__ */ React13.createElement(
|
|
9661
9778
|
CommandMenu,
|
|
@@ -9695,7 +9812,7 @@ Selection: ${val}`,
|
|
|
9695
9812
|
{
|
|
9696
9813
|
value: inputConfig?.value || "",
|
|
9697
9814
|
onChange: (val) => setInputConfig((prev) => ({ ...prev, value: val })),
|
|
9698
|
-
onSubmit: (val) => {
|
|
9815
|
+
onSubmit: async (val) => {
|
|
9699
9816
|
const { key, subKey, next } = inputConfig;
|
|
9700
9817
|
let newQuotas = { ...quotas };
|
|
9701
9818
|
let newSettings = {};
|
|
@@ -9737,6 +9854,26 @@ Selection: ${val}`,
|
|
|
9737
9854
|
return [...prev, { id: Date.now(), role: "system", text: `\u274C [IMAGE KEY ERROR] API key must start with sk_. Key strategy reset to Default.`, isMeta: true }];
|
|
9738
9855
|
});
|
|
9739
9856
|
}
|
|
9857
|
+
} else if (key === "providerKey") {
|
|
9858
|
+
const keyInput = val.trim();
|
|
9859
|
+
const prov = inputConfig.provider;
|
|
9860
|
+
await saveProviderAPIKey(prov, keyInput);
|
|
9861
|
+
setAiProvider(prov);
|
|
9862
|
+
setApiKey(keyInput);
|
|
9863
|
+
initAI(keyInput);
|
|
9864
|
+
let defaultModel = "gemma-4-31b-it";
|
|
9865
|
+
if (prov === "OpenRouter") {
|
|
9866
|
+
defaultModel = "google/gemma-4-31b-it:free";
|
|
9867
|
+
} else if (prov === "DeepSeek") {
|
|
9868
|
+
defaultModel = "deepseek-v4-flash";
|
|
9869
|
+
}
|
|
9870
|
+
setActiveModel(defaultModel);
|
|
9871
|
+
newSettings.aiProvider = prov;
|
|
9872
|
+
newSettings.activeModel = defaultModel;
|
|
9873
|
+
setMessages((prev) => {
|
|
9874
|
+
setCompletedIndex(prev.length + 1);
|
|
9875
|
+
return [...prev, { id: Date.now(), role: "system", text: `\u2705 ${prov} API Key saved successfully! Model set to ${defaultModel}.`, isMeta: true }];
|
|
9876
|
+
});
|
|
9740
9877
|
}
|
|
9741
9878
|
if (next) {
|
|
9742
9879
|
setInputConfig(next(key === "quotas" ? newQuotas : val));
|