fluxflow-cli 2.14.1 → 2.15.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/dist/fluxflow.js +460 -128
- package/package.json +2 -2
package/dist/fluxflow.js
CHANGED
|
@@ -305,7 +305,13 @@ var init_settings = __esm({
|
|
|
305
305
|
backgroundLimit: 999999,
|
|
306
306
|
searchLimit: 100,
|
|
307
307
|
customModelId: "",
|
|
308
|
-
customLimit: 0
|
|
308
|
+
customLimit: 0,
|
|
309
|
+
providerTiers: {
|
|
310
|
+
Google: "Free",
|
|
311
|
+
DeepSeek: "Free",
|
|
312
|
+
NVIDIA: "Free",
|
|
313
|
+
OpenRouter: "Free"
|
|
314
|
+
}
|
|
309
315
|
},
|
|
310
316
|
systemSettings: {
|
|
311
317
|
memory: true,
|
|
@@ -345,7 +351,14 @@ var init_settings = __esm({
|
|
|
345
351
|
settingsObj = {
|
|
346
352
|
...DEFAULT_SETTINGS,
|
|
347
353
|
...saved,
|
|
348
|
-
quotas: {
|
|
354
|
+
quotas: {
|
|
355
|
+
...DEFAULT_SETTINGS.quotas,
|
|
356
|
+
...saved.quotas,
|
|
357
|
+
providerTiers: {
|
|
358
|
+
...DEFAULT_SETTINGS.quotas.providerTiers,
|
|
359
|
+
...saved.quotas?.providerTiers || {}
|
|
360
|
+
}
|
|
361
|
+
},
|
|
349
362
|
systemSettings: { ...DEFAULT_SETTINGS.systemSettings, ...saved.systemSettings },
|
|
350
363
|
profileData: { ...DEFAULT_SETTINGS.profileData, ...saved.profileData },
|
|
351
364
|
imageSettings: { ...DEFAULT_SETTINGS.imageSettings, ...saved.imageSettings }
|
|
@@ -5746,7 +5759,7 @@ function SettingsMenu({
|
|
|
5746
5759
|
case "other":
|
|
5747
5760
|
return [
|
|
5748
5761
|
{ label: "Current Provider", value: "aiProvider", status: aiProvider },
|
|
5749
|
-
{ label: "
|
|
5762
|
+
{ label: "Key Strategy", value: "apiTier", status: apiTier === "Free" ? "Free" : quotas?.providerBudgets?.__useProvider ? "Paid" : "Paid" },
|
|
5750
5763
|
{ label: "Download Language Parsers", value: "parserDownload", status: "ACTION" }
|
|
5751
5764
|
];
|
|
5752
5765
|
default:
|
|
@@ -6256,9 +6269,9 @@ ${userMemories}` : "";
|
|
|
6256
6269
|
${parts.join("\n\n")}
|
|
6257
6270
|
` : "";
|
|
6258
6271
|
};
|
|
6259
|
-
getSystemInstruction = (profile, thinkingLevel, mode, systemSettings, isMemoryEnabled = true, isFirstPrompt = false, aiProvider = "Google", isMultiModal = false) => {
|
|
6272
|
+
getSystemInstruction = (profile, thinkingLevel, mode, systemSettings, isMemoryEnabled = true, isFirstPrompt = false, aiProvider = "Google", isMultiModal = false, isGemini) => {
|
|
6260
6273
|
let thinkingConfig = "";
|
|
6261
|
-
if (
|
|
6274
|
+
if (!isGemini && aiProvider === "Google") {
|
|
6262
6275
|
let levelKey = thinkingLevel;
|
|
6263
6276
|
if (thinkingLevel === "Fast") levelKey = "Off";
|
|
6264
6277
|
if (thinkingLevel === "Low") levelKey = "Minimal";
|
|
@@ -6266,6 +6279,23 @@ ${parts.join("\n\n")}
|
|
|
6266
6279
|
if (thinkingLevel === "xHigh" || thinkingLevel === "Max") levelKey = "xHigh";
|
|
6267
6280
|
thinkingConfig = thinking_prompts_default[levelKey] || thinking_prompts_default["Medium"];
|
|
6268
6281
|
}
|
|
6282
|
+
if (isGemini || aiProvider !== "Google") {
|
|
6283
|
+
const MAP_FOR_NON_GOOGLE_OR_GEMINI = {
|
|
6284
|
+
"Fast": "LOWEST",
|
|
6285
|
+
"Low": "LOW",
|
|
6286
|
+
"Medium": "MEDIUM",
|
|
6287
|
+
"Standard": "MEDIUM",
|
|
6288
|
+
"High": "HIGH",
|
|
6289
|
+
"xHigh": "HIGH",
|
|
6290
|
+
"Max": "HIGH"
|
|
6291
|
+
};
|
|
6292
|
+
thinkingConfig = thinking_prompts_default["xHigh"];
|
|
6293
|
+
thinkingConfig = thinkingConfig.replace("EFFORT LEVEL: HIGH\nThink in a continuous, relentless analytical monologue. ", `EFFORT LEVEL: ${MAP_FOR_NON_GOOGLE_OR_GEMINI[thinkingLevel]}
|
|
6294
|
+
`).replace("- MANDATORY THINKING: Full reasoning required for ALL requests/greetings", "");
|
|
6295
|
+
if (thinkingLevel === "Fast") {
|
|
6296
|
+
thinkingConfig = "EFFORT LEVEL: LOWEST\nNo thinking. Immediate response\nRULES:\n- Verify ALL imports and system stability, AVOID ANY Syntax errors, re-read TOOL RESULTS/files to verify\n";
|
|
6297
|
+
}
|
|
6298
|
+
}
|
|
6269
6299
|
const osDetected = process.platform === "win32" ? "Windows" : process.platform === "darwin" ? "macOS" : "Linux";
|
|
6270
6300
|
const userInstrStr = profile.instructions && profile.instructions?.length > 0 ? `User Instructions: ${profile.instructions}
|
|
6271
6301
|
|
|
@@ -6311,12 +6341,13 @@ Mode: ${mode}${thinkingLevel !== "Fast" ? " (Thinking)" : ""}. ${mode === "Flux"
|
|
|
6311
6341
|
-- MARKERS --
|
|
6312
6342
|
- TOOL SYSTEM: [TOOL RESULT]
|
|
6313
6343
|
- SYSTEM NOTIFICATION: [SYSTEM] in user turn
|
|
6314
|
-
|
|
6344
|
+
|
|
6315
6345
|
-- THINKING RULES --
|
|
6316
|
-
${thinkingConfig}
|
|
6317
|
-
${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" ? `
|
|
6346
|
+
${aiProvider === "Google" && !isGemini ? `${thinkingConfig}
|
|
6347
|
+
${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" && !isGemini ? `
|
|
6318
6348
|
CRITICAL THINKING POLICY
|
|
6319
|
-
- ALWAYS use <think> ... </think> before responding, even with simple queries/greetings
|
|
6349
|
+
- ALWAYS use <think> ... </think> before responding, even with simple queries/greetings
|
|
6350
|
+
` : ""}` : `${thinkingConfig}`}
|
|
6320
6351
|
${TOOL_PROTOCOL(mode, osDetected, aiProvider.toLowerCase() === "deepseek" ? false : isMultiModal, aiProvider)}
|
|
6321
6352
|
${projectContextBlock}
|
|
6322
6353
|
-- MEMORY RULES --
|
|
@@ -7063,6 +7094,26 @@ var init_usage = __esm({
|
|
|
7063
7094
|
cachedUsage.stats[key] = Array.from(uniqueMap.values());
|
|
7064
7095
|
} else if (typeof cachedUsage.stats[key] === "number") {
|
|
7065
7096
|
cachedUsage.stats[key] = Math.max(cachedUsage.stats[key], Number(diskData.stats[key]) || 0);
|
|
7097
|
+
} else if (cachedUsage.stats[key] && typeof cachedUsage.stats[key] === "object") {
|
|
7098
|
+
const diskObj = diskData.stats[key] || {};
|
|
7099
|
+
const memObj = cachedUsage.stats[key];
|
|
7100
|
+
for (const subKey in diskObj) {
|
|
7101
|
+
if (typeof diskObj[subKey] === "number") {
|
|
7102
|
+
memObj[subKey] = Math.max(memObj[subKey] || 0, diskObj[subKey]);
|
|
7103
|
+
} else if (diskObj[subKey] && typeof diskObj[subKey] === "object") {
|
|
7104
|
+
if (!memObj[subKey]) memObj[subKey] = {};
|
|
7105
|
+
for (const mKey in diskObj[subKey]) {
|
|
7106
|
+
if (typeof diskObj[subKey][mKey] === "number") {
|
|
7107
|
+
memObj[subKey][mKey] = Math.max(memObj[subKey][mKey] || 0, diskObj[subKey][mKey]);
|
|
7108
|
+
} else if (diskObj[subKey][mKey] && typeof diskObj[subKey][mKey] === "object") {
|
|
7109
|
+
if (!memObj[subKey][mKey]) memObj[subKey][mKey] = {};
|
|
7110
|
+
for (const valKey in diskObj[subKey][mKey]) {
|
|
7111
|
+
memObj[subKey][mKey][valKey] = Math.max(memObj[subKey][mKey][valKey] || 0, diskObj[subKey][mKey][valKey]);
|
|
7112
|
+
}
|
|
7113
|
+
}
|
|
7114
|
+
}
|
|
7115
|
+
}
|
|
7116
|
+
}
|
|
7066
7117
|
}
|
|
7067
7118
|
}
|
|
7068
7119
|
}
|
|
@@ -7206,12 +7257,18 @@ var init_usage = __esm({
|
|
|
7206
7257
|
}
|
|
7207
7258
|
return summed;
|
|
7208
7259
|
};
|
|
7209
|
-
incrementUsage = async (key) => {
|
|
7260
|
+
incrementUsage = async (key, provider) => {
|
|
7210
7261
|
const stats = await getDailyUsage();
|
|
7211
7262
|
if (stats[key] !== void 0) {
|
|
7212
7263
|
stats[key]++;
|
|
7213
|
-
queueFlush();
|
|
7214
7264
|
}
|
|
7265
|
+
if (provider && key === "agent") {
|
|
7266
|
+
if (!stats.providerRequests) {
|
|
7267
|
+
stats.providerRequests = {};
|
|
7268
|
+
}
|
|
7269
|
+
stats.providerRequests[provider] = (stats.providerRequests[provider] || 0) + 1;
|
|
7270
|
+
}
|
|
7271
|
+
queueFlush();
|
|
7215
7272
|
};
|
|
7216
7273
|
addToUsage = async (key, amount, provider, model) => {
|
|
7217
7274
|
const stats = await getDailyUsage();
|
|
@@ -7306,14 +7363,30 @@ var init_usage = __esm({
|
|
|
7306
7363
|
checkQuota = async (key, settings) => {
|
|
7307
7364
|
const tier = settings.apiTier || "Free";
|
|
7308
7365
|
const quotas = settings.quotas || {};
|
|
7366
|
+
const resolveAgentLimits = () => {
|
|
7367
|
+
const providerBudgets = quotas.providerBudgets || {};
|
|
7368
|
+
const useProvider = !!providerBudgets.__useProvider;
|
|
7369
|
+
const currentProvider = settings.aiProvider || "Google";
|
|
7370
|
+
if (useProvider && providerBudgets[currentProvider]) {
|
|
7371
|
+
const pb = providerBudgets[currentProvider];
|
|
7372
|
+
return {
|
|
7373
|
+
agentLimit: typeof pb.agentLimit === "number" && pb.agentLimit > 0 ? pb.agentLimit : 99999999,
|
|
7374
|
+
tokenLimit: typeof pb.tokenLimit === "number" && pb.tokenLimit > 0 ? pb.tokenLimit : 99999999999999,
|
|
7375
|
+
monthlyTokenLimit: typeof pb.monthlyTokenLimit === "number" && pb.monthlyTokenLimit > 0 ? pb.monthlyTokenLimit : 99999999999999
|
|
7376
|
+
};
|
|
7377
|
+
}
|
|
7378
|
+
return {
|
|
7379
|
+
agentLimit: quotas.agentLimit || 99999999,
|
|
7380
|
+
tokenLimit: quotas.tokenLimit || 99999999999999,
|
|
7381
|
+
monthlyTokenLimit: quotas.monthlyTokenLimit || 99999999999999
|
|
7382
|
+
};
|
|
7383
|
+
};
|
|
7309
7384
|
if (tier === "Free") {
|
|
7310
7385
|
if (key === "agent") {
|
|
7311
|
-
const
|
|
7312
|
-
const tokenLimit = quotas.tokenLimit || 99999999999999;
|
|
7313
|
-
const monthlyTokenLimit = quotas.monthlyTokenLimit || 99999999999999;
|
|
7386
|
+
const { agentLimit, tokenLimit, monthlyTokenLimit } = resolveAgentLimits();
|
|
7314
7387
|
const dailyUsage = await getDailyUsage();
|
|
7315
7388
|
if (dailyUsage.agent + dailyUsage.background >= 999999) return false;
|
|
7316
|
-
const dailyOk = dailyUsage.agent <
|
|
7389
|
+
const dailyOk = dailyUsage.agent < agentLimit && (dailyUsage.tokens || 0) < tokenLimit;
|
|
7317
7390
|
if (!dailyOk) return false;
|
|
7318
7391
|
let monthlyUsage;
|
|
7319
7392
|
if (quotas.resetMode === "Custom") {
|
|
@@ -7335,11 +7408,9 @@ var init_usage = __esm({
|
|
|
7335
7408
|
}
|
|
7336
7409
|
if (tier === "Paid" || tier === "Custom") {
|
|
7337
7410
|
if (key === "agent") {
|
|
7338
|
-
const
|
|
7339
|
-
const tokenLimit = quotas.tokenLimit || 99999999999999;
|
|
7340
|
-
const monthlyTokenLimit = quotas.monthlyTokenLimit || 99999999999999;
|
|
7411
|
+
const { agentLimit, tokenLimit, monthlyTokenLimit } = resolveAgentLimits();
|
|
7341
7412
|
const dailyUsage = await getDailyUsage();
|
|
7342
|
-
const dailyOk = dailyUsage.agent <
|
|
7413
|
+
const dailyOk = dailyUsage.agent < agentLimit && (dailyUsage.tokens || 0) < tokenLimit;
|
|
7343
7414
|
if (!dailyOk) return false;
|
|
7344
7415
|
let monthlyUsage;
|
|
7345
7416
|
if (quotas.resetMode === "Custom") {
|
|
@@ -8382,6 +8453,37 @@ async function getFilesRecursively(dir, excludes, baseDir = dir, depth = 1) {
|
|
|
8382
8453
|
}
|
|
8383
8454
|
return results;
|
|
8384
8455
|
}
|
|
8456
|
+
function normStr(s) {
|
|
8457
|
+
return s.toLowerCase().replace(/[^a-z0-9\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
8458
|
+
}
|
|
8459
|
+
function levenshtein(a, b) {
|
|
8460
|
+
if (a === b) return 0;
|
|
8461
|
+
if (a.length === 0) return b.length;
|
|
8462
|
+
if (b.length === 0) return a.length;
|
|
8463
|
+
const cap = Math.floor(Math.max(a.length, b.length) / 2) + 1;
|
|
8464
|
+
const dp = Array.from({ length: a.length + 1 }, (_, i) => i);
|
|
8465
|
+
for (let j = 1; j <= b.length; j++) {
|
|
8466
|
+
let prev = dp[0];
|
|
8467
|
+
dp[0] = j;
|
|
8468
|
+
for (let i = 1; i <= a.length; i++) {
|
|
8469
|
+
const tmp = dp[i];
|
|
8470
|
+
dp[i] = b[j - 1] === a[i - 1] ? prev : 1 + Math.min(prev, dp[i], dp[i - 1]);
|
|
8471
|
+
prev = tmp;
|
|
8472
|
+
}
|
|
8473
|
+
if (Math.min(...dp) > cap) return cap + 1;
|
|
8474
|
+
}
|
|
8475
|
+
return dp[a.length];
|
|
8476
|
+
}
|
|
8477
|
+
function fuzzyMatch(line, keyword) {
|
|
8478
|
+
const normLine = normStr(line);
|
|
8479
|
+
const lineWords = normLine.split(" ");
|
|
8480
|
+
const kwTokens = normStr(keyword).split(" ").filter(Boolean);
|
|
8481
|
+
if (normLine.includes(normStr(keyword))) return true;
|
|
8482
|
+
return kwTokens.every((token) => {
|
|
8483
|
+
const maxDist = token.length <= 2 ? 0 : token.length <= 5 ? 1 : 2;
|
|
8484
|
+
return lineWords.some((word) => levenshtein(token, word) <= maxDist);
|
|
8485
|
+
});
|
|
8486
|
+
}
|
|
8385
8487
|
var search_keyword;
|
|
8386
8488
|
var init_search_keyword = __esm({
|
|
8387
8489
|
"src/tools/search_keyword.js"() {
|
|
@@ -8389,7 +8491,7 @@ var init_search_keyword = __esm({
|
|
|
8389
8491
|
search_keyword = async (args) => {
|
|
8390
8492
|
const { keyword, file, subString } = parseArgs(args);
|
|
8391
8493
|
if (!keyword) return 'ERROR: Missing "keyword" argument.';
|
|
8392
|
-
const matchSubstring = subString === true || subString === "true" || subString === 1 || subString === "1" || subString === "true";
|
|
8494
|
+
const matchSubstring = subString === true || subString === "true" || subString === 1 || subString === "1" || subString === "true" || subString === "yes" || subString === "yes" || false;
|
|
8393
8495
|
const wordRegex = new RegExp(`(?<![\\w])${keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![\\w])`, "i");
|
|
8394
8496
|
const excludes = [
|
|
8395
8497
|
"node_modules",
|
|
@@ -8430,30 +8532,50 @@ var init_search_keyword = __esm({
|
|
|
8430
8532
|
const lines = content.split(/\r?\n/);
|
|
8431
8533
|
const fileMatches = [];
|
|
8432
8534
|
for (let i = 0; i < lines.length; i++) {
|
|
8433
|
-
const matched = matchSubstring ? lines[i].toLowerCase().includes(keyword.toLowerCase()) : wordRegex.test(lines[i]);
|
|
8535
|
+
const matched = matchSubstring ? lines[i].toLowerCase().includes(keyword.toLowerCase()) || fuzzyMatch(lines[i], keyword) : wordRegex.test(lines[i]);
|
|
8434
8536
|
if (matched) {
|
|
8435
|
-
|
|
8436
|
-
fileMatches.push(`${displayPath} \u2192 ${i + 1}`);
|
|
8537
|
+
fileMatches.push({ line: i + 1, content: lines[i].trim() });
|
|
8437
8538
|
}
|
|
8438
8539
|
}
|
|
8439
|
-
return
|
|
8540
|
+
if (fileMatches.length === 0) return null;
|
|
8541
|
+
const displayPath = fileObj.relativePath.replace(/\\/g, "/");
|
|
8542
|
+
return { path: displayPath, matches: fileMatches };
|
|
8440
8543
|
} catch {
|
|
8441
8544
|
return [];
|
|
8442
8545
|
}
|
|
8443
8546
|
});
|
|
8444
8547
|
const settledResults = await Promise.all(searchPromises);
|
|
8445
|
-
const
|
|
8548
|
+
const fileGroups = [];
|
|
8549
|
+
let totalMatches = 0;
|
|
8550
|
+
for (const result of settledResults) {
|
|
8551
|
+
if (!result) continue;
|
|
8552
|
+
if (totalMatches >= maxMatches) break;
|
|
8553
|
+
const remaining = maxMatches - totalMatches;
|
|
8554
|
+
const trimmedMatches = result.matches.slice(0, remaining);
|
|
8555
|
+
fileGroups.push({ path: result.path, matches: trimmedMatches });
|
|
8556
|
+
totalMatches += trimmedMatches.length;
|
|
8557
|
+
}
|
|
8446
8558
|
if (typeof global.gc === "function") {
|
|
8447
8559
|
global.gc();
|
|
8448
8560
|
}
|
|
8449
|
-
if (
|
|
8561
|
+
if (fileGroups.length === 0) {
|
|
8450
8562
|
return `Found 0 matches for keyword: "${keyword}"${file ? ` in file: ${file}` : ". Try to specify files"} ${matchSubstring ? "(subString mode)" : ""}`;
|
|
8451
8563
|
}
|
|
8452
|
-
let output = `Found ${
|
|
8564
|
+
let output = `Found ${totalMatches} match${totalMatches === 1 ? "" : "es"} across ${fileGroups.length} file${fileGroups.length === 1 ? "" : "s"} ${matchSubstring ? "(subString mode)" : ""}:
|
|
8453
8565
|
|
|
8454
8566
|
`;
|
|
8455
|
-
|
|
8456
|
-
|
|
8567
|
+
for (const group of fileGroups) {
|
|
8568
|
+
output += `${group.path}
|
|
8569
|
+
`;
|
|
8570
|
+
for (let i = 0; i < group.matches.length; i++) {
|
|
8571
|
+
const isLast = i === group.matches.length - 1;
|
|
8572
|
+
const prefix = isLast ? "\u2514\u2500\u2500" : "\u251C\u2500\u2500";
|
|
8573
|
+
output += `${prefix} ${group.matches[i].line}: ${group.matches[i].content}
|
|
8574
|
+
`;
|
|
8575
|
+
}
|
|
8576
|
+
output += "\n";
|
|
8577
|
+
}
|
|
8578
|
+
return output.trimEnd();
|
|
8457
8579
|
} catch (error) {
|
|
8458
8580
|
return `ERROR: ${error.message}`;
|
|
8459
8581
|
}
|
|
@@ -11579,7 +11701,7 @@ ${activeSummaryBlock}${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" &&
|
|
|
11579
11701
|
} else if (retryCount > 0) {
|
|
11580
11702
|
yield { type: "model_update", content: null };
|
|
11581
11703
|
}
|
|
11582
|
-
currentSystemInstruction = getSystemInstruction(profile, !(targetModel || "gemma").toLowerCase().startsWith("gemma") ?
|
|
11704
|
+
currentSystemInstruction = getSystemInstruction(profile, !(targetModel || "gemma").toLowerCase().startsWith("gemma") ? thinkingLevel : thinkingLevel, mode, systemSettings, isMemoryEnabled, isFirstPrompt, aiProvider, aiProvider === "Google" ? true : isMultiModal, !(targetModel || "gemma").toLowerCase().startsWith("gemma") ? true : false);
|
|
11583
11705
|
const lastUserMsg = contents[contents.length - 1];
|
|
11584
11706
|
if (isBridgeConnected() & loop > 0) {
|
|
11585
11707
|
yield { type: "status", content: "Checking Code..." };
|
|
@@ -12851,7 +12973,7 @@ ${boxBottom}`}`) };
|
|
|
12851
12973
|
const { keyword, file } = parseArgs(toolCall.args);
|
|
12852
12974
|
let matchCount = 0;
|
|
12853
12975
|
if (result) {
|
|
12854
|
-
const m = result.match(/Found (\d+)
|
|
12976
|
+
const m = result.match(/Found (\d+) match/i);
|
|
12855
12977
|
if (m) {
|
|
12856
12978
|
matchCount = parseInt(m[1]);
|
|
12857
12979
|
}
|
|
@@ -13016,7 +13138,7 @@ ${colorMainWords(output)}` };
|
|
|
13016
13138
|
if (!hasFinish2 && !hasContinue2 && !didCallTool && signalSafeText2.length > 0 && !endsNormally && !isThinkingLoop && !isStutteringLoop && !isGeneralLoop) {
|
|
13017
13139
|
}
|
|
13018
13140
|
success = true;
|
|
13019
|
-
await incrementUsage("agent");
|
|
13141
|
+
await incrementUsage("agent", aiProvider);
|
|
13020
13142
|
} catch (err) {
|
|
13021
13143
|
if (TERMINATION_SIGNAL) {
|
|
13022
13144
|
yield { type: "status", content: "Request Cancelled" };
|
|
@@ -13034,7 +13156,7 @@ ${colorMainWords(output)}` };
|
|
|
13034
13156
|
}
|
|
13035
13157
|
}
|
|
13036
13158
|
success = true;
|
|
13037
|
-
await incrementUsage("agent");
|
|
13159
|
+
await incrementUsage("agent", aiProvider);
|
|
13038
13160
|
break;
|
|
13039
13161
|
}
|
|
13040
13162
|
if (inThinkingState) {
|
|
@@ -14550,8 +14672,13 @@ function App({ args = [] }) {
|
|
|
14550
14672
|
};
|
|
14551
14673
|
const [activeView, setActiveView] = useState14("chat");
|
|
14552
14674
|
const [apiTier, setApiTier] = useState14("Free");
|
|
14553
|
-
const [quotas, setQuotas] = useState14({ limitMode: "Daily", agentLimit: 99999999, tokenLimit: 99999999999999, backgroundLimit: 999999, searchLimit: 100, customModelId: "", customLimit: 0 });
|
|
14675
|
+
const [quotas, setQuotas] = useState14({ limitMode: "Daily", agentLimit: 99999999, tokenLimit: 99999999999999, backgroundLimit: 999999, searchLimit: 100, customModelId: "", customLimit: 0, providerBudgets: {} });
|
|
14554
14676
|
const [inputConfig, setInputConfig] = useState14(null);
|
|
14677
|
+
const [budgetReturnView, setBudgetReturnView] = useState14("chat");
|
|
14678
|
+
const [providerBudgetQueue, setProviderBudgetQueue] = useState14([]);
|
|
14679
|
+
const [providerBudgetCursor, setProviderBudgetCursor] = useState14(0);
|
|
14680
|
+
const [pbsCursor, setPbsCursor] = useState14(0);
|
|
14681
|
+
const [pbsSelected, setPbsSelected] = useState14({});
|
|
14555
14682
|
const [systemSettings, setSystemSettings] = useState14({ memory: true, compression: 0, autoExec: false, autoDeleteHistory: "7d", autoUpdate: false, updateManager: "npm", customUpdateCommand: "" });
|
|
14556
14683
|
const [profileData, setProfileData] = useState14({ name: null, nickname: null, instructions: null });
|
|
14557
14684
|
const [imageSettings, setImageSettings] = useState14({ keyType: "Default", quality: "Low-High", apiKey: "" });
|
|
@@ -15007,6 +15134,34 @@ function App({ args = [] }) {
|
|
|
15007
15134
|
}
|
|
15008
15135
|
return;
|
|
15009
15136
|
}
|
|
15137
|
+
if (activeView === "providerBudgetSelect") {
|
|
15138
|
+
const PBS_PROVIDERS = ["Google", "DeepSeek", "NVIDIA", "OpenRouter"];
|
|
15139
|
+
if (key.upArrow) {
|
|
15140
|
+
setPbsCursor((c) => (c - 1 + PBS_PROVIDERS.length) % PBS_PROVIDERS.length);
|
|
15141
|
+
return;
|
|
15142
|
+
} else if (key.downArrow) {
|
|
15143
|
+
setPbsCursor((c) => (c + 1) % PBS_PROVIDERS.length);
|
|
15144
|
+
return;
|
|
15145
|
+
} else if (inputText === " ") {
|
|
15146
|
+
const prov = PBS_PROVIDERS[pbsCursor];
|
|
15147
|
+
setPbsSelected((s) => ({ ...s, [prov]: !s[prov] }));
|
|
15148
|
+
return;
|
|
15149
|
+
} else if (key.return) {
|
|
15150
|
+
const chosenProviders = PBS_PROVIDERS.filter((p) => pbsSelected[p]);
|
|
15151
|
+
if (chosenProviders.length === 0) return;
|
|
15152
|
+
const updatedQuotas = { ...quotas, providerBudgets: { ...quotas.providerBudgets || {}, __useProvider: true } };
|
|
15153
|
+
setQuotas(updatedQuotas);
|
|
15154
|
+
setProviderBudgetQueue(chosenProviders);
|
|
15155
|
+
setProviderBudgetCursor(0);
|
|
15156
|
+
setPbsCursor(0);
|
|
15157
|
+
setActiveView("providerBudgetFlow");
|
|
15158
|
+
return;
|
|
15159
|
+
} else if (key.escape) {
|
|
15160
|
+
setActiveView("budgetTypeSelect");
|
|
15161
|
+
return;
|
|
15162
|
+
}
|
|
15163
|
+
return;
|
|
15164
|
+
}
|
|
15010
15165
|
if (key.escape) {
|
|
15011
15166
|
if (showBtwBox) {
|
|
15012
15167
|
setShowBtwBox(false);
|
|
@@ -15165,7 +15320,8 @@ function App({ args = [] }) {
|
|
|
15165
15320
|
}
|
|
15166
15321
|
const startupProvider = parsedArgs.provider || saved.aiProvider || "Google";
|
|
15167
15322
|
setAiProvider(startupProvider);
|
|
15168
|
-
const
|
|
15323
|
+
const providerTiers = saved.quotas?.providerTiers || {};
|
|
15324
|
+
const currentTier = providerTiers[startupProvider] || saved.apiTier || "Free";
|
|
15169
15325
|
persistedModelRef.current = saved.activeModel;
|
|
15170
15326
|
if (parsedArgs.model) {
|
|
15171
15327
|
setActiveModel(parsedArgs.model);
|
|
@@ -15197,8 +15353,8 @@ function App({ args = [] }) {
|
|
|
15197
15353
|
setActiveModel(saved.activeModel);
|
|
15198
15354
|
}
|
|
15199
15355
|
setShowFullThinking(saved.showFullThinking);
|
|
15200
|
-
setApiTier(
|
|
15201
|
-
setQuotas(saved.quotas || { limitMode: "Daily", agentLimit: 99999999, tokenLimit: 99999999999999, backgroundLimit: 999999, searchLimit: 100, customModelId: "", customLimit: 0 });
|
|
15356
|
+
setApiTier(currentTier);
|
|
15357
|
+
setQuotas(saved.quotas || { limitMode: "Daily", agentLimit: 99999999, tokenLimit: 99999999999999, backgroundLimit: 999999, searchLimit: 100, customModelId: "", customLimit: 0, providerBudgets: {} });
|
|
15202
15358
|
const freshSettings = {
|
|
15203
15359
|
memory: true,
|
|
15204
15360
|
compression: 0,
|
|
@@ -15458,14 +15614,6 @@ function App({ args = [] }) {
|
|
|
15458
15614
|
{ cmd: "/export", desc: "Export current chat in a .txt file" },
|
|
15459
15615
|
{ cmd: "/chats", desc: "List all chat sessions" },
|
|
15460
15616
|
{ cmd: "/btw", desc: "Ask a question without intefering with ongoing tasks" },
|
|
15461
|
-
{
|
|
15462
|
-
cmd: "/mode",
|
|
15463
|
-
desc: "Toggle Flux/Flow modes",
|
|
15464
|
-
subs: [
|
|
15465
|
-
{ cmd: "flux", desc: "Enable Dev toolset" },
|
|
15466
|
-
{ cmd: "flow", desc: "Enable Chat mode" }
|
|
15467
|
-
]
|
|
15468
|
-
},
|
|
15469
15617
|
{
|
|
15470
15618
|
cmd: "/thinking",
|
|
15471
15619
|
desc: "Set AI reasoning depth",
|
|
@@ -15696,6 +15844,14 @@ function App({ args = [] }) {
|
|
|
15696
15844
|
}
|
|
15697
15845
|
]
|
|
15698
15846
|
},
|
|
15847
|
+
{
|
|
15848
|
+
cmd: "/mode",
|
|
15849
|
+
desc: "Toggle Flux/Flow modes",
|
|
15850
|
+
subs: [
|
|
15851
|
+
{ cmd: "flux", desc: "Enable Dev toolset" },
|
|
15852
|
+
{ cmd: "flow", desc: "Enable Chat mode" }
|
|
15853
|
+
]
|
|
15854
|
+
},
|
|
15699
15855
|
{ cmd: "/settings", desc: "Configure system prefs" },
|
|
15700
15856
|
{ cmd: "/key", desc: "Manage API keys" },
|
|
15701
15857
|
{ cmd: "/profile", desc: "Edit developer persona" },
|
|
@@ -15717,7 +15873,8 @@ function App({ args = [] }) {
|
|
|
15717
15873
|
desc: "Set or View budget limits",
|
|
15718
15874
|
subs: [
|
|
15719
15875
|
{ cmd: "view", desc: "View current usage budget bars" },
|
|
15720
|
-
{ cmd: "set", desc: "Configure budgets (Daily/Monthly limits)" }
|
|
15876
|
+
{ cmd: "set", desc: "Configure budgets (Daily/Monthly limits)" },
|
|
15877
|
+
{ cmd: "reset", desc: "Reset budgets to default limits" }
|
|
15721
15878
|
]
|
|
15722
15879
|
},
|
|
15723
15880
|
{
|
|
@@ -16368,28 +16525,8 @@ ${list || "No saved chats found."}`, isMeta: true }];
|
|
|
16368
16525
|
case "/budget": {
|
|
16369
16526
|
const sub = parts[1]?.toLowerCase();
|
|
16370
16527
|
if (sub === "set") {
|
|
16371
|
-
|
|
16372
|
-
|
|
16373
|
-
key: "quotas",
|
|
16374
|
-
subKey: "agentLimit",
|
|
16375
|
-
value: getPrefilledValue(quotas.agentLimit),
|
|
16376
|
-
returnView: "chat",
|
|
16377
|
-
next: (newQuotas) => ({
|
|
16378
|
-
label: "Enter Agent daily budget (tokens used):",
|
|
16379
|
-
key: "quotas",
|
|
16380
|
-
subKey: "tokenLimit",
|
|
16381
|
-
value: getPrefilledValue(newQuotas.tokenLimit),
|
|
16382
|
-
returnView: "chat",
|
|
16383
|
-
next: (q2) => ({
|
|
16384
|
-
label: "Enter Agent monthly budget (tokens used):",
|
|
16385
|
-
key: "quotas",
|
|
16386
|
-
subKey: "monthlyTokenLimit",
|
|
16387
|
-
value: getPrefilledValue(q2.monthlyTokenLimit),
|
|
16388
|
-
returnView: "budgetResetMode"
|
|
16389
|
-
})
|
|
16390
|
-
})
|
|
16391
|
-
});
|
|
16392
|
-
setActiveView("input");
|
|
16528
|
+
setBudgetReturnView("chat");
|
|
16529
|
+
setActiveView("budgetTypeSelect");
|
|
16393
16530
|
} else if (sub === "view") {
|
|
16394
16531
|
const run = async () => {
|
|
16395
16532
|
const usage = await getDailyUsage();
|
|
@@ -16401,10 +16538,34 @@ ${list || "No saved chats found."}`, isMeta: true }];
|
|
|
16401
16538
|
setActiveView("budgetView");
|
|
16402
16539
|
};
|
|
16403
16540
|
run();
|
|
16541
|
+
} else if (sub === "reset") {
|
|
16542
|
+
const defaultQuotas = {
|
|
16543
|
+
limitMode: "Daily",
|
|
16544
|
+
agentLimit: 99999999,
|
|
16545
|
+
tokenLimit: 99999999999999,
|
|
16546
|
+
backgroundLimit: 999999,
|
|
16547
|
+
searchLimit: 100,
|
|
16548
|
+
customModelId: "",
|
|
16549
|
+
customLimit: 0,
|
|
16550
|
+
providerBudgets: {},
|
|
16551
|
+
providerTiers: {
|
|
16552
|
+
Google: "Free",
|
|
16553
|
+
DeepSeek: "Free",
|
|
16554
|
+
NVIDIA: "Free",
|
|
16555
|
+
OpenRouter: "Free"
|
|
16556
|
+
}
|
|
16557
|
+
};
|
|
16558
|
+
setQuotas(defaultQuotas);
|
|
16559
|
+
setApiTier("Free");
|
|
16560
|
+
saveSettings({ apiTier: "Free", quotas: defaultQuotas });
|
|
16561
|
+
setMessages((prev) => {
|
|
16562
|
+
setCompletedIndex(prev.length + 1);
|
|
16563
|
+
return [...prev, { id: Date.now(), role: "system", text: `\u2705 [BUDGET] Budgets and limits reset to default values successfully.`, isMeta: true }];
|
|
16564
|
+
});
|
|
16404
16565
|
} else {
|
|
16405
16566
|
setMessages((prev) => {
|
|
16406
16567
|
setCompletedIndex(prev.length + 1);
|
|
16407
|
-
return [...prev, { id: Date.now(), role: "system", text: `Usage: /budget <Set|View>`, isMeta: true }];
|
|
16568
|
+
return [...prev, { id: Date.now(), role: "system", text: `Usage: /budget <Set|View|Reset>`, isMeta: true }];
|
|
16408
16569
|
});
|
|
16409
16570
|
}
|
|
16410
16571
|
break;
|
|
@@ -17212,6 +17373,87 @@ Selection: ${val}`,
|
|
|
17212
17373
|
useEffect11(() => {
|
|
17213
17374
|
setSelectedIndex(0);
|
|
17214
17375
|
}, [suggestions]);
|
|
17376
|
+
useEffect11(() => {
|
|
17377
|
+
if (activeView !== "providerBudgetSelect") return;
|
|
17378
|
+
const PBS_PROVIDERS = ["Google", "DeepSeek", "NVIDIA", "OpenRouter"];
|
|
17379
|
+
const existingBudgets = quotas.providerBudgets || {};
|
|
17380
|
+
const initialSelected = PBS_PROVIDERS.reduce((acc, p) => {
|
|
17381
|
+
acc[p] = !!(existingBudgets[p] && (existingBudgets[p].agentLimit || existingBudgets[p].tokenLimit));
|
|
17382
|
+
return acc;
|
|
17383
|
+
}, {});
|
|
17384
|
+
setPbsSelected(initialSelected);
|
|
17385
|
+
setPbsCursor(0);
|
|
17386
|
+
}, [activeView]);
|
|
17387
|
+
useEffect11(() => {
|
|
17388
|
+
if (activeView !== "providerBudgetFlow") return;
|
|
17389
|
+
const currentProvider = providerBudgetQueue[providerBudgetCursor];
|
|
17390
|
+
if (!currentProvider) {
|
|
17391
|
+
const returnMode = budgetReturnView === "settings" ? "resetMode" : "budgetResetMode";
|
|
17392
|
+
const rawPB = quotas.providerBudgets || {};
|
|
17393
|
+
const cleaned = { __useProvider: true };
|
|
17394
|
+
for (const prov of providerBudgetQueue) {
|
|
17395
|
+
if (rawPB[prov]) cleaned[prov] = rawPB[prov];
|
|
17396
|
+
}
|
|
17397
|
+
const finalCleanedQuotas = { ...quotas, providerBudgets: cleaned };
|
|
17398
|
+
setQuotas(finalCleanedQuotas);
|
|
17399
|
+
saveSettings({ apiTier, quotas: finalCleanedQuotas });
|
|
17400
|
+
setActiveView(returnMode);
|
|
17401
|
+
return;
|
|
17402
|
+
}
|
|
17403
|
+
const existingPB = (quotas.providerBudgets || {})[currentProvider] || {};
|
|
17404
|
+
const totalProviders = providerBudgetQueue.length;
|
|
17405
|
+
const currentStep = providerBudgetCursor + 1;
|
|
17406
|
+
const providerLabel = `[${currentStep}/${totalProviders}] ${currentProvider}`;
|
|
17407
|
+
const advanceToNext = (finalQuotas) => {
|
|
17408
|
+
if (providerBudgetCursor + 1 < providerBudgetQueue.length) {
|
|
17409
|
+
setProviderBudgetCursor((c) => c + 1);
|
|
17410
|
+
setActiveView("providerBudgetFlow");
|
|
17411
|
+
} else {
|
|
17412
|
+
const rawPB = finalQuotas.providerBudgets || {};
|
|
17413
|
+
const cleaned = { __useProvider: true };
|
|
17414
|
+
for (const prov of providerBudgetQueue) {
|
|
17415
|
+
if (rawPB[prov]) cleaned[prov] = rawPB[prov];
|
|
17416
|
+
}
|
|
17417
|
+
const finalCleanedQuotas = { ...finalQuotas, providerBudgets: cleaned };
|
|
17418
|
+
setQuotas(finalCleanedQuotas);
|
|
17419
|
+
const rm = budgetReturnView === "settings" ? "resetMode" : "budgetResetMode";
|
|
17420
|
+
saveSettings({ apiTier, quotas: finalCleanedQuotas });
|
|
17421
|
+
setActiveView(rm);
|
|
17422
|
+
}
|
|
17423
|
+
};
|
|
17424
|
+
setInputConfig({
|
|
17425
|
+
label: `${providerLabel} \u2014 Daily budget (requests/day):`,
|
|
17426
|
+
key: "providerBudgets",
|
|
17427
|
+
providerKey: currentProvider,
|
|
17428
|
+
subKey: "agentLimit",
|
|
17429
|
+
value: getPrefilledValue(existingPB.agentLimit),
|
|
17430
|
+
returnView: "providerBudgetSelect",
|
|
17431
|
+
next: (newQuotas) => {
|
|
17432
|
+
const updatedPB = (newQuotas.providerBudgets || {})[currentProvider] || {};
|
|
17433
|
+
return {
|
|
17434
|
+
label: `${providerLabel} \u2014 Daily budget (tokens/day):`,
|
|
17435
|
+
key: "providerBudgets",
|
|
17436
|
+
providerKey: currentProvider,
|
|
17437
|
+
subKey: "tokenLimit",
|
|
17438
|
+
value: getPrefilledValue(updatedPB.tokenLimit),
|
|
17439
|
+
returnView: "providerBudgetSelect",
|
|
17440
|
+
next: (q2) => {
|
|
17441
|
+
const pb2 = (q2.providerBudgets || {})[currentProvider] || {};
|
|
17442
|
+
return {
|
|
17443
|
+
label: `${providerLabel} \u2014 Monthly budget (tokens/month):`,
|
|
17444
|
+
key: "providerBudgets",
|
|
17445
|
+
providerKey: currentProvider,
|
|
17446
|
+
subKey: "monthlyTokenLimit",
|
|
17447
|
+
value: getPrefilledValue(pb2.monthlyTokenLimit),
|
|
17448
|
+
returnView: "providerBudgetFlow",
|
|
17449
|
+
onDone: advanceToNext
|
|
17450
|
+
};
|
|
17451
|
+
}
|
|
17452
|
+
};
|
|
17453
|
+
}
|
|
17454
|
+
});
|
|
17455
|
+
setActiveView("input");
|
|
17456
|
+
}, [activeView, providerBudgetCursor]);
|
|
17215
17457
|
const CustomMenuItem = ({ label: label2, isSelected }) => {
|
|
17216
17458
|
const isCancel = label2 === "Cancel" || label2 === "Back" || label2.toLowerCase().includes("exit") || label2.toLowerCase().includes("back");
|
|
17217
17459
|
return /* @__PURE__ */ React15.createElement(
|
|
@@ -17290,7 +17532,9 @@ Selection: ${val}`,
|
|
|
17290
17532
|
defaultModel = "moonshotai/kimi-k2.6";
|
|
17291
17533
|
}
|
|
17292
17534
|
setActiveModel(defaultModel);
|
|
17293
|
-
|
|
17535
|
+
const targetTier = (quotas.providerTiers || {})[selectedProvider] || "Free";
|
|
17536
|
+
setApiTier(targetTier);
|
|
17537
|
+
saveSettings({ aiProvider: selectedProvider, activeModel: defaultModel, apiTier: targetTier, quotas });
|
|
17294
17538
|
setMessages((prev) => [
|
|
17295
17539
|
...prev,
|
|
17296
17540
|
{
|
|
@@ -17315,30 +17559,12 @@ Selection: ${val}`,
|
|
|
17315
17559
|
}
|
|
17316
17560
|
);
|
|
17317
17561
|
case "apiTier": {
|
|
17318
|
-
|
|
17319
|
-
const reqLimit = quotas.agentLimit || 99999999;
|
|
17320
|
-
const tokenCurrent = dailyUsage?.tokens || 0;
|
|
17321
|
-
const tokenLimit = quotas.tokenLimit || 99999999999999;
|
|
17322
|
-
const monthlyCurrent = quotas.resetMode === "Custom" ? customPeriodUsage?.tokens || 0 : monthlyUsage?.tokens || 0;
|
|
17323
|
-
const monthlyLimit = quotas.monthlyTokenLimit || 99999999999999;
|
|
17324
|
-
let resetInfo = "";
|
|
17325
|
-
if (quotas.resetMode === "Custom") {
|
|
17326
|
-
const today = /* @__PURE__ */ new Date();
|
|
17327
|
-
const resetDay = quotas.resetDay || 1;
|
|
17328
|
-
let resetMonth = today.getMonth();
|
|
17329
|
-
if (today.getDate() >= resetDay) {
|
|
17330
|
-
resetMonth += 1;
|
|
17331
|
-
}
|
|
17332
|
-
const resetDate = new Date(today.getFullYear(), resetMonth, resetDay);
|
|
17333
|
-
const monthName = resetDate.toLocaleString("default", { month: "short" });
|
|
17334
|
-
resetInfo = `Resets on: ${resetDay}-${monthName}`;
|
|
17335
|
-
}
|
|
17336
|
-
return /* @__PURE__ */ React15.createElement(Box15, { flexDirection: "column", borderStyle: "round", borderColor: "white", padding: 0, width: "100%" }, /* @__PURE__ */ React15.createElement(Box15, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text16, { color: "gray", bold: true }, "SELECT YOUR CURRENT API TIER BASED ON YOUR PROVIDER. (Provider: ", aiProvider, ")")), /* @__PURE__ */ React15.createElement(
|
|
17562
|
+
return /* @__PURE__ */ React15.createElement(Box15, { flexDirection: "column", borderStyle: "round", borderColor: "white", padding: 0, width: "100%" }, /* @__PURE__ */ React15.createElement(Box15, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text16, { color: "gray", bold: true }, "SET API KEY STRATEGY FOR ", aiProvider, ".")), /* @__PURE__ */ React15.createElement(
|
|
17337
17563
|
SelectInput2,
|
|
17338
17564
|
{
|
|
17339
17565
|
items: [
|
|
17340
|
-
{ label: "
|
|
17341
|
-
{ label: `
|
|
17566
|
+
{ label: "Free Key [Basic set of Models]", value: "Free" },
|
|
17567
|
+
{ label: `Billing Key [Premium Models Available] ${apiTier === "Paid" ? "\u25CF" : ""}`, value: "Paid" },
|
|
17342
17568
|
{ label: "Back", value: "settings" }
|
|
17343
17569
|
],
|
|
17344
17570
|
onSelect: (item) => {
|
|
@@ -17348,40 +17574,22 @@ Selection: ${val}`,
|
|
|
17348
17574
|
}
|
|
17349
17575
|
const newTier = item.value;
|
|
17350
17576
|
setApiTier(newTier);
|
|
17351
|
-
|
|
17352
|
-
|
|
17353
|
-
|
|
17354
|
-
|
|
17355
|
-
|
|
17356
|
-
|
|
17357
|
-
|
|
17358
|
-
|
|
17359
|
-
|
|
17360
|
-
|
|
17361
|
-
|
|
17362
|
-
value: getPrefilledValue(newQuotas.tokenLimit),
|
|
17363
|
-
returnView: "settings",
|
|
17364
|
-
next: (q2) => ({
|
|
17365
|
-
label: "Enter Agent monthly budget (tokens used):",
|
|
17366
|
-
key: "quotas",
|
|
17367
|
-
subKey: "monthlyTokenLimit",
|
|
17368
|
-
value: getPrefilledValue(q2.monthlyTokenLimit),
|
|
17369
|
-
returnView: "resetMode"
|
|
17370
|
-
})
|
|
17371
|
-
})
|
|
17372
|
-
});
|
|
17373
|
-
setActiveView("input");
|
|
17374
|
-
} else {
|
|
17375
|
-
const newQuotas = { ...quotas, agentLimit: 99999999, tokenLimit: 99999999999999, monthlyTokenLimit: 99999999999999 };
|
|
17376
|
-
setQuotas(newQuotas);
|
|
17377
|
-
saveSettings({ apiTier: newTier, quotas: newQuotas });
|
|
17378
|
-
setActiveView("settings");
|
|
17379
|
-
}
|
|
17577
|
+
const updatedProviderTiers = {
|
|
17578
|
+
...quotas.providerTiers || {},
|
|
17579
|
+
[aiProvider]: newTier
|
|
17580
|
+
};
|
|
17581
|
+
const newQuotas = {
|
|
17582
|
+
...quotas,
|
|
17583
|
+
providerTiers: updatedProviderTiers
|
|
17584
|
+
};
|
|
17585
|
+
setQuotas(newQuotas);
|
|
17586
|
+
saveSettings({ apiTier: newTier, quotas: newQuotas });
|
|
17587
|
+
setActiveView("settings");
|
|
17380
17588
|
},
|
|
17381
17589
|
itemComponent: CustomMenuItem,
|
|
17382
17590
|
indicatorComponent: () => null
|
|
17383
17591
|
}
|
|
17384
|
-
),
|
|
17592
|
+
), /* @__PURE__ */ React15.createElement(Box15, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text16, { color: "gray", italic: true }, "(Arrows to select \u2022 Enter to confirm)")));
|
|
17385
17593
|
}
|
|
17386
17594
|
case "resetMode":
|
|
17387
17595
|
return /* @__PURE__ */ React15.createElement(
|
|
@@ -17418,6 +17626,82 @@ Selection: ${val}`,
|
|
|
17418
17626
|
onClose: () => setActiveView("apiTier")
|
|
17419
17627
|
}
|
|
17420
17628
|
);
|
|
17629
|
+
case "budgetTypeSelect":
|
|
17630
|
+
return /* @__PURE__ */ React15.createElement(
|
|
17631
|
+
CommandMenu,
|
|
17632
|
+
{
|
|
17633
|
+
title: "SELECT BUDGET TYPE",
|
|
17634
|
+
items: [
|
|
17635
|
+
{ label: `Global Budget (single limit for all providers) ${apiTier === "Paid" && !quotas.providerBudgets?.["__useProvider"] ? "\u25CF" : ""}`, value: "global" },
|
|
17636
|
+
{ label: `Provider Budgets (set limits per provider individually) ${quotas.providerBudgets?.["__useProvider"] ? "\u25CF" : ""}`, value: "provider" },
|
|
17637
|
+
{ label: "Back", value: budgetReturnView }
|
|
17638
|
+
],
|
|
17639
|
+
onSelect: (item) => {
|
|
17640
|
+
if (item.value === budgetReturnView || item.value === "Back") {
|
|
17641
|
+
setActiveView(budgetReturnView);
|
|
17642
|
+
return;
|
|
17643
|
+
}
|
|
17644
|
+
if (item.value === "global") {
|
|
17645
|
+
const updatedQuotas = {
|
|
17646
|
+
...quotas,
|
|
17647
|
+
agentLimit: 99999999,
|
|
17648
|
+
tokenLimit: 99999999999999,
|
|
17649
|
+
monthlyTokenLimit: 99999999999999,
|
|
17650
|
+
providerBudgets: { __useProvider: false }
|
|
17651
|
+
};
|
|
17652
|
+
setQuotas(updatedQuotas);
|
|
17653
|
+
const returnMode = budgetReturnView === "settings" ? "resetMode" : "budgetResetMode";
|
|
17654
|
+
setInputConfig({
|
|
17655
|
+
label: "Enter Agent daily budget (requests made):",
|
|
17656
|
+
key: "quotas",
|
|
17657
|
+
subKey: "agentLimit",
|
|
17658
|
+
value: getPrefilledValue(updatedQuotas.agentLimit),
|
|
17659
|
+
returnView: budgetReturnView,
|
|
17660
|
+
next: (newQuotas) => ({
|
|
17661
|
+
label: "Enter Agent daily budget (tokens used):",
|
|
17662
|
+
key: "quotas",
|
|
17663
|
+
subKey: "tokenLimit",
|
|
17664
|
+
value: getPrefilledValue(newQuotas.tokenLimit),
|
|
17665
|
+
returnView: budgetReturnView,
|
|
17666
|
+
next: (q2) => ({
|
|
17667
|
+
label: "Enter Agent monthly budget (tokens used):",
|
|
17668
|
+
key: "quotas",
|
|
17669
|
+
subKey: "monthlyTokenLimit",
|
|
17670
|
+
value: getPrefilledValue(q2.monthlyTokenLimit),
|
|
17671
|
+
returnView: returnMode
|
|
17672
|
+
})
|
|
17673
|
+
})
|
|
17674
|
+
});
|
|
17675
|
+
setActiveView("input");
|
|
17676
|
+
} else if (item.value === "provider") {
|
|
17677
|
+
const updatedQuotas = {
|
|
17678
|
+
...quotas,
|
|
17679
|
+
agentLimit: 99999999,
|
|
17680
|
+
tokenLimit: 99999999999999,
|
|
17681
|
+
monthlyTokenLimit: 99999999999999,
|
|
17682
|
+
providerBudgets: {
|
|
17683
|
+
...quotas.providerBudgets || {},
|
|
17684
|
+
__useProvider: true
|
|
17685
|
+
}
|
|
17686
|
+
};
|
|
17687
|
+
setQuotas(updatedQuotas);
|
|
17688
|
+
setActiveView("providerBudgetSelect");
|
|
17689
|
+
}
|
|
17690
|
+
},
|
|
17691
|
+
onClose: () => setActiveView(budgetReturnView)
|
|
17692
|
+
}
|
|
17693
|
+
);
|
|
17694
|
+
case "providerBudgetSelect": {
|
|
17695
|
+
const PROVIDERS_LIST = ["Google", "DeepSeek", "NVIDIA", "OpenRouter"];
|
|
17696
|
+
const anySelected = PROVIDERS_LIST.some((p) => pbsSelected[p]);
|
|
17697
|
+
return /* @__PURE__ */ React15.createElement(Box15, { flexDirection: "column", borderStyle: "round", borderColor: "white", padding: 0, width: "100%" }, /* @__PURE__ */ React15.createElement(Box15, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text16, { color: "gray", bold: true }, "SELECT PROVIDERS TO SET BUDGETS FOR")), PROVIDERS_LIST.map((prov, i) => {
|
|
17698
|
+
const isActive = i === pbsCursor;
|
|
17699
|
+
const isChecked = !!pbsSelected[prov];
|
|
17700
|
+
return /* @__PURE__ */ React15.createElement(Box15, { key: prov, backgroundColor: isActive ? "#2a2a2a" : void 0, paddingX: 1, width: "100%" }, /* @__PURE__ */ React15.createElement(Text16, { color: isActive ? "white" : "gray", bold: isActive }, isActive ? "\u276F " : " ", /* @__PURE__ */ React15.createElement(Text16, { color: isChecked ? "green" : "gray" }, isChecked ? "\u2611" : "\u2610"), " ", prov, isChecked && quotas.providerBudgets?.[prov]?.agentLimit ? /* @__PURE__ */ React15.createElement(Text16, { color: "cyan" }, " (budget set)") : null));
|
|
17701
|
+
}), /* @__PURE__ */ React15.createElement(Box15, { paddingX: 1, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React15.createElement(Text16, { color: "gray", italic: true }, "\u2191\u2193 Navigate \u2022 Space to toggle \u2022 Enter to confirm \u2022 ESC to go back"), !anySelected && /* @__PURE__ */ React15.createElement(Text16, { color: "yellow", italic: true }, " Select at least one provider to continue")));
|
|
17702
|
+
}
|
|
17703
|
+
case "providerBudgetFlow":
|
|
17704
|
+
return null;
|
|
17421
17705
|
case "budgetResetMode":
|
|
17422
17706
|
return /* @__PURE__ */ React15.createElement(
|
|
17423
17707
|
CommandMenu,
|
|
@@ -17461,7 +17745,12 @@ Selection: ${val}`,
|
|
|
17461
17745
|
const monthlyCurrent = quotas.resetMode === "Custom" ? customPeriodUsage?.tokens || 0 : monthlyUsage?.tokens || 0;
|
|
17462
17746
|
const monthlyLimit = quotas.monthlyTokenLimit || 99999999999999;
|
|
17463
17747
|
const isFreeTier = apiTier !== "Paid";
|
|
17464
|
-
const
|
|
17748
|
+
const usingProviderBudgets = !!quotas.providerBudgets?.__useProvider;
|
|
17749
|
+
const providerBudgetsMap = quotas.providerBudgets || {};
|
|
17750
|
+
const configuredProviders = ["Google", "DeepSeek", "NVIDIA", "OpenRouter"].filter(
|
|
17751
|
+
(p) => providerBudgetsMap[p] && (providerBudgetsMap[p].agentLimit || providerBudgetsMap[p].tokenLimit || providerBudgetsMap[p].monthlyTokenLimit)
|
|
17752
|
+
);
|
|
17753
|
+
const limitsNotSet = !usingProviderBudgets && (shouldClearValue(reqLimit) || shouldClearValue(tokenLimit) || shouldClearValue(monthlyLimit));
|
|
17465
17754
|
let resetInfo = "";
|
|
17466
17755
|
if (quotas.resetMode === "Custom") {
|
|
17467
17756
|
const today = /* @__PURE__ */ new Date();
|
|
@@ -17474,7 +17763,22 @@ Selection: ${val}`,
|
|
|
17474
17763
|
const monthName = resetDate.toLocaleString("default", { month: "short" });
|
|
17475
17764
|
resetInfo = `Resets on: ${resetDay}-${monthName}`;
|
|
17476
17765
|
}
|
|
17477
|
-
return /* @__PURE__ */ React15.createElement(Box15, { flexDirection: "column", borderStyle: "round", borderColor: "white", padding: 1, width: "100%" }, /* @__PURE__ */ React15.createElement(Box15, { marginBottom: 1, justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React15.createElement(Text16, { color: "white", bold: true, underline: true }, "BUDGET LIMIT STATUS", isFreeTier ? " (Isn't it fun to see numbers go BRRRR)" : ""), /* @__PURE__ */ React15.createElement(Text16, { color: "gray" }, "[ ESC to Close ]")), limitsNotSet ? /* @__PURE__ */ React15.createElement(Box15, { padding: 1, justifyContent: "center", alignItems: "center", width: "100%" }, /* @__PURE__ */ React15.createElement(Text16, { color: "yellow", bold: true }, "LIMITS NOT SET")) :
|
|
17766
|
+
return /* @__PURE__ */ React15.createElement(Box15, { flexDirection: "column", borderStyle: "round", borderColor: "white", padding: 1, width: "100%" }, /* @__PURE__ */ React15.createElement(Box15, { marginBottom: 1, justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React15.createElement(Text16, { color: "white", bold: true, underline: true }, "BUDGET LIMIT STATUS", isFreeTier && !usingProviderBudgets ? " (Isn't it fun to see numbers go BRRRR)" : ""), /* @__PURE__ */ React15.createElement(Text16, { color: "gray" }, "[ ESC to Close ]")), limitsNotSet ? /* @__PURE__ */ React15.createElement(Box15, { padding: 1, justifyContent: "center", alignItems: "center", width: "100%" }, /* @__PURE__ */ React15.createElement(Text16, { color: "yellow", bold: true }, "LIMITS NOT SET")) : usingProviderBudgets && configuredProviders.length > 0 ? /* @__PURE__ */ React15.createElement(Box15, { flexDirection: "column", gap: 1, width: "100%" }, configuredProviders.map((prov) => {
|
|
17767
|
+
const pb = providerBudgetsMap[prov];
|
|
17768
|
+
const provReqCurrent = dailyUsage?.providerRequests?.[prov] || 0;
|
|
17769
|
+
let provTokenCurrent = 0;
|
|
17770
|
+
const dailyModels = dailyUsage?.models?.[prov] || {};
|
|
17771
|
+
for (const m in dailyModels) {
|
|
17772
|
+
provTokenCurrent += dailyModels[m]?.tokens || 0;
|
|
17773
|
+
}
|
|
17774
|
+
let provMonthlyCurrent = 0;
|
|
17775
|
+
const monthlySource = quotas.resetMode === "Custom" ? customPeriodUsage : monthlyUsage;
|
|
17776
|
+
const monthlyModels = monthlySource?.models?.[prov] || {};
|
|
17777
|
+
for (const m in monthlyModels) {
|
|
17778
|
+
provMonthlyCurrent += monthlyModels[m]?.tokens || 0;
|
|
17779
|
+
}
|
|
17780
|
+
return /* @__PURE__ */ React15.createElement(Box15, { key: prov, flexDirection: "column", borderStyle: "single", borderColor: "gray", paddingX: 1, width: "100%" }, /* @__PURE__ */ React15.createElement(Box15, { marginBottom: 0 }, /* @__PURE__ */ React15.createElement(Text16, { color: "cyan", bold: true }, "\u25C6 ", prov)), renderProgressBar("Daily Requests", provReqCurrent, pb.agentLimit || 99999999, "cyan"), renderProgressBar("Daily Tokens", provTokenCurrent, pb.tokenLimit || 99999999999999, "green"), renderProgressBar("Monthly Tokens", provMonthlyCurrent, pb.monthlyTokenLimit || 99999999999999, "yellow"));
|
|
17781
|
+
}), resetInfo ? /* @__PURE__ */ React15.createElement(Box15, { marginLeft: 4 }, /* @__PURE__ */ React15.createElement(Text16, { color: "gray" }, "Monthly Reset : "), /* @__PURE__ */ React15.createElement(Text16, { color: "magenta", bold: true }, resetInfo)) : /* @__PURE__ */ React15.createElement(Box15, { marginLeft: 4 }, /* @__PURE__ */ React15.createElement(Text16, { color: "gray" }, "Monthly Reset : "), /* @__PURE__ */ React15.createElement(Text16, { color: "blue", bold: true }, "Rolling 30-Day Window"))) : /* @__PURE__ */ React15.createElement(Box15, { flexDirection: "column", borderStyle: "single", borderColor: "gray", paddingX: 1, width: "100%" }, renderProgressBar("Daily Requests", reqCurrent, reqLimit, "cyan"), renderProgressBar("Daily Tokens", tokenCurrent, tokenLimit, "green"), renderProgressBar("Monthly Tokens", monthlyCurrent, monthlyLimit, "yellow"), resetInfo ? /* @__PURE__ */ React15.createElement(Box15, { marginLeft: 4, marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text16, { color: "gray" }, "Monthly Reset : "), /* @__PURE__ */ React15.createElement(Text16, { color: "magenta", bold: true }, resetInfo)) : /* @__PURE__ */ React15.createElement(Box15, { marginLeft: 4, marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text16, { color: "gray" }, "Monthly Reset : "), /* @__PURE__ */ React15.createElement(Text16, { color: "blue", bold: true }, "Rolling 30-Day Window"))));
|
|
17478
17782
|
}
|
|
17479
17783
|
case "input":
|
|
17480
17784
|
return /* @__PURE__ */ React15.createElement(Box15, { flexDirection: "column", borderStyle: "round", borderColor: "white", padding: 0, width: "100%" }, /* @__PURE__ */ React15.createElement(Box15, { paddingX: 1 }, /* @__PURE__ */ React15.createElement(Text16, { color: "white", bold: true }, "DATA CONFIGURATION")), inputConfig?.note && /* @__PURE__ */ React15.createElement(Box15, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text16, { color: "gray", italic: true }, inputConfig.note)), /* @__PURE__ */ React15.createElement(Box15, { paddingX: 1, flexDirection: "row" }, /* @__PURE__ */ React15.createElement(Text16, { color: "white", bold: true }, inputConfig?.label, " "), /* @__PURE__ */ React15.createElement(
|
|
@@ -17483,7 +17787,7 @@ Selection: ${val}`,
|
|
|
17483
17787
|
value: inputConfig?.value || "",
|
|
17484
17788
|
onChange: (val) => setInputConfig((prev) => ({ ...prev, value: val })),
|
|
17485
17789
|
onSubmit: async (val) => {
|
|
17486
|
-
const { key, subKey, next } = inputConfig;
|
|
17790
|
+
const { key, subKey, next, onDone } = inputConfig;
|
|
17487
17791
|
let newQuotas = { ...quotas };
|
|
17488
17792
|
let newSettings = {};
|
|
17489
17793
|
if (key === "quotas") {
|
|
@@ -17494,6 +17798,19 @@ Selection: ${val}`,
|
|
|
17494
17798
|
newQuotas[subKey] = parsedValue;
|
|
17495
17799
|
setQuotas(newQuotas);
|
|
17496
17800
|
newSettings.quotas = newQuotas;
|
|
17801
|
+
} else if (key === "providerBudgets") {
|
|
17802
|
+
const prov = inputConfig.providerKey;
|
|
17803
|
+
const parsedValue = subKey.toLowerCase().includes("limit") ? parseInt(val) || 0 : val;
|
|
17804
|
+
const existingPBudgets = newQuotas.providerBudgets || {};
|
|
17805
|
+
newQuotas.providerBudgets = {
|
|
17806
|
+
...existingPBudgets,
|
|
17807
|
+
[prov]: {
|
|
17808
|
+
...existingPBudgets[prov] || {},
|
|
17809
|
+
[subKey]: parsedValue
|
|
17810
|
+
}
|
|
17811
|
+
};
|
|
17812
|
+
setQuotas(newQuotas);
|
|
17813
|
+
newSettings.quotas = newQuotas;
|
|
17497
17814
|
} else if (key === "activeModel") {
|
|
17498
17815
|
setActiveModel(val);
|
|
17499
17816
|
newSettings.activeModel = val;
|
|
@@ -17543,15 +17860,23 @@ Selection: ${val}`,
|
|
|
17543
17860
|
defaultModel = "moonshotai/kimi-k2.6";
|
|
17544
17861
|
}
|
|
17545
17862
|
setActiveModel(defaultModel);
|
|
17863
|
+
const targetTier = (quotas.providerTiers || {})[prov] || "Free";
|
|
17864
|
+
setApiTier(targetTier);
|
|
17546
17865
|
newSettings.aiProvider = prov;
|
|
17547
17866
|
newSettings.activeModel = defaultModel;
|
|
17867
|
+
newSettings.apiTier = targetTier;
|
|
17548
17868
|
setMessages((prev) => {
|
|
17549
17869
|
setCompletedIndex(prev.length + 1);
|
|
17550
17870
|
return [...prev, { id: Date.now(), role: "system", text: `\u2705 ${prov} API Key saved successfully! Model set to ${defaultModel}.`, isMeta: true }];
|
|
17551
17871
|
});
|
|
17552
17872
|
}
|
|
17553
17873
|
if (next) {
|
|
17554
|
-
|
|
17874
|
+
const nextConfig = next(key === "quotas" || key === "providerBudgets" ? newQuotas : val);
|
|
17875
|
+
setInputConfig(nextConfig);
|
|
17876
|
+
} else if (onDone) {
|
|
17877
|
+
saveSettings({ ...newSettings, apiTier, quotas: newQuotas, imageSettings: newSettings.imageSettings || imageSettings });
|
|
17878
|
+
setInputConfig(null);
|
|
17879
|
+
onDone(newQuotas);
|
|
17555
17880
|
} else {
|
|
17556
17881
|
saveSettings({ ...newSettings, apiTier, quotas: newQuotas, imageSettings: newSettings.imageSettings || imageSettings });
|
|
17557
17882
|
setInputConfig(null);
|
|
@@ -18045,7 +18370,7 @@ Selection: ${val}`,
|
|
|
18045
18370
|
setSetupStep(1);
|
|
18046
18371
|
}
|
|
18047
18372
|
}
|
|
18048
|
-
))) : /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(Text16, { color: "white" }, "Please enter your ", aiProvider, " API Key to initialize the agent (If billing is enabled set
|
|
18373
|
+
))) : /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(Text16, { color: "white" }, "Please enter your ", aiProvider, " API Key to initialize the agent (If billing is enabled set /settings \u2192 Others \u2192 API Strategy to use premium models. Set budget limit at /budgets.)."), /* @__PURE__ */ React15.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text16, { color: "gray", bold: true }, " ", ">", " "), /* @__PURE__ */ React15.createElement(
|
|
18049
18374
|
TextInput4,
|
|
18050
18375
|
{
|
|
18051
18376
|
value: tempKey,
|
|
@@ -18409,13 +18734,20 @@ var calculatedLimit = Math.floor(totalSystemRamMB * SAFETY_MARGIN);
|
|
|
18409
18734
|
var _rawArgs = process.argv.slice(2);
|
|
18410
18735
|
var _allocIdx = _rawArgs.indexOf("--allocation");
|
|
18411
18736
|
var _allocValue = _allocIdx !== -1 ? parseInt(_rawArgs[_allocIdx + 1], 10) : NaN;
|
|
18737
|
+
if (!isNaN(_allocValue) && _allocValue < 64) {
|
|
18738
|
+
console.error(`
|
|
18739
|
+
[ERROR] Allocation value '${_allocValue} MB' is too low. Minimum: 64 MB, Recommended: 4096 MB.
|
|
18740
|
+
`);
|
|
18741
|
+
process.exit(1);
|
|
18742
|
+
}
|
|
18412
18743
|
var _maxAllowed = Math.floor(totalSystemRamMB * 0.75);
|
|
18413
18744
|
var HEAP_LIMIT = !isNaN(_allocValue) && _allocValue > 0 ? Math.min(_allocValue, _maxAllowed) : Math.max(1536, Math.min(32768, calculatedLimit));
|
|
18414
18745
|
var isBundled = fileURLToPath2(import.meta.url).endsWith(".js");
|
|
18415
18746
|
if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-size"))) {
|
|
18416
18747
|
if (!Number.isNaN(_allocValue)) {
|
|
18417
|
-
console.log(
|
|
18418
|
-
|
|
18748
|
+
console.log(`
|
|
18749
|
+
[MEMORY] Starting with: '${_allocValue > _maxAllowed ? _maxAllowed : _allocValue} MB' Allocation ${_allocValue > _maxAllowed ? "(Max allowed: '" + _maxAllowed + " MB')" : ""}. Please Wait...`);
|
|
18750
|
+
await new Promise((resolve) => setTimeout(resolve, 5e3));
|
|
18419
18751
|
}
|
|
18420
18752
|
const cp = spawn3(process.execPath, [
|
|
18421
18753
|
`--max-old-space-size=${HEAP_LIMIT}`,
|