fluxflow-cli 2.14.2 → 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 +418 -111
- 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:
|
|
@@ -7081,6 +7094,26 @@ var init_usage = __esm({
|
|
|
7081
7094
|
cachedUsage.stats[key] = Array.from(uniqueMap.values());
|
|
7082
7095
|
} else if (typeof cachedUsage.stats[key] === "number") {
|
|
7083
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
|
+
}
|
|
7084
7117
|
}
|
|
7085
7118
|
}
|
|
7086
7119
|
}
|
|
@@ -7224,12 +7257,18 @@ var init_usage = __esm({
|
|
|
7224
7257
|
}
|
|
7225
7258
|
return summed;
|
|
7226
7259
|
};
|
|
7227
|
-
incrementUsage = async (key) => {
|
|
7260
|
+
incrementUsage = async (key, provider) => {
|
|
7228
7261
|
const stats = await getDailyUsage();
|
|
7229
7262
|
if (stats[key] !== void 0) {
|
|
7230
7263
|
stats[key]++;
|
|
7231
|
-
queueFlush();
|
|
7232
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();
|
|
7233
7272
|
};
|
|
7234
7273
|
addToUsage = async (key, amount, provider, model) => {
|
|
7235
7274
|
const stats = await getDailyUsage();
|
|
@@ -7324,14 +7363,30 @@ var init_usage = __esm({
|
|
|
7324
7363
|
checkQuota = async (key, settings) => {
|
|
7325
7364
|
const tier = settings.apiTier || "Free";
|
|
7326
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
|
+
};
|
|
7327
7384
|
if (tier === "Free") {
|
|
7328
7385
|
if (key === "agent") {
|
|
7329
|
-
const
|
|
7330
|
-
const tokenLimit = quotas.tokenLimit || 99999999999999;
|
|
7331
|
-
const monthlyTokenLimit = quotas.monthlyTokenLimit || 99999999999999;
|
|
7386
|
+
const { agentLimit, tokenLimit, monthlyTokenLimit } = resolveAgentLimits();
|
|
7332
7387
|
const dailyUsage = await getDailyUsage();
|
|
7333
7388
|
if (dailyUsage.agent + dailyUsage.background >= 999999) return false;
|
|
7334
|
-
const dailyOk = dailyUsage.agent <
|
|
7389
|
+
const dailyOk = dailyUsage.agent < agentLimit && (dailyUsage.tokens || 0) < tokenLimit;
|
|
7335
7390
|
if (!dailyOk) return false;
|
|
7336
7391
|
let monthlyUsage;
|
|
7337
7392
|
if (quotas.resetMode === "Custom") {
|
|
@@ -7353,11 +7408,9 @@ var init_usage = __esm({
|
|
|
7353
7408
|
}
|
|
7354
7409
|
if (tier === "Paid" || tier === "Custom") {
|
|
7355
7410
|
if (key === "agent") {
|
|
7356
|
-
const
|
|
7357
|
-
const tokenLimit = quotas.tokenLimit || 99999999999999;
|
|
7358
|
-
const monthlyTokenLimit = quotas.monthlyTokenLimit || 99999999999999;
|
|
7411
|
+
const { agentLimit, tokenLimit, monthlyTokenLimit } = resolveAgentLimits();
|
|
7359
7412
|
const dailyUsage = await getDailyUsage();
|
|
7360
|
-
const dailyOk = dailyUsage.agent <
|
|
7413
|
+
const dailyOk = dailyUsage.agent < agentLimit && (dailyUsage.tokens || 0) < tokenLimit;
|
|
7361
7414
|
if (!dailyOk) return false;
|
|
7362
7415
|
let monthlyUsage;
|
|
7363
7416
|
if (quotas.resetMode === "Custom") {
|
|
@@ -8400,6 +8453,37 @@ async function getFilesRecursively(dir, excludes, baseDir = dir, depth = 1) {
|
|
|
8400
8453
|
}
|
|
8401
8454
|
return results;
|
|
8402
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
|
+
}
|
|
8403
8487
|
var search_keyword;
|
|
8404
8488
|
var init_search_keyword = __esm({
|
|
8405
8489
|
"src/tools/search_keyword.js"() {
|
|
@@ -8407,7 +8491,7 @@ var init_search_keyword = __esm({
|
|
|
8407
8491
|
search_keyword = async (args) => {
|
|
8408
8492
|
const { keyword, file, subString } = parseArgs(args);
|
|
8409
8493
|
if (!keyword) return 'ERROR: Missing "keyword" argument.';
|
|
8410
|
-
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;
|
|
8411
8495
|
const wordRegex = new RegExp(`(?<![\\w])${keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![\\w])`, "i");
|
|
8412
8496
|
const excludes = [
|
|
8413
8497
|
"node_modules",
|
|
@@ -8448,30 +8532,50 @@ var init_search_keyword = __esm({
|
|
|
8448
8532
|
const lines = content.split(/\r?\n/);
|
|
8449
8533
|
const fileMatches = [];
|
|
8450
8534
|
for (let i = 0; i < lines.length; i++) {
|
|
8451
|
-
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]);
|
|
8452
8536
|
if (matched) {
|
|
8453
|
-
|
|
8454
|
-
fileMatches.push(`${displayPath} \u2192 ${i + 1}`);
|
|
8537
|
+
fileMatches.push({ line: i + 1, content: lines[i].trim() });
|
|
8455
8538
|
}
|
|
8456
8539
|
}
|
|
8457
|
-
return
|
|
8540
|
+
if (fileMatches.length === 0) return null;
|
|
8541
|
+
const displayPath = fileObj.relativePath.replace(/\\/g, "/");
|
|
8542
|
+
return { path: displayPath, matches: fileMatches };
|
|
8458
8543
|
} catch {
|
|
8459
8544
|
return [];
|
|
8460
8545
|
}
|
|
8461
8546
|
});
|
|
8462
8547
|
const settledResults = await Promise.all(searchPromises);
|
|
8463
|
-
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
|
+
}
|
|
8464
8558
|
if (typeof global.gc === "function") {
|
|
8465
8559
|
global.gc();
|
|
8466
8560
|
}
|
|
8467
|
-
if (
|
|
8561
|
+
if (fileGroups.length === 0) {
|
|
8468
8562
|
return `Found 0 matches for keyword: "${keyword}"${file ? ` in file: ${file}` : ". Try to specify files"} ${matchSubstring ? "(subString mode)" : ""}`;
|
|
8469
8563
|
}
|
|
8470
|
-
let output = `Found ${
|
|
8564
|
+
let output = `Found ${totalMatches} match${totalMatches === 1 ? "" : "es"} across ${fileGroups.length} file${fileGroups.length === 1 ? "" : "s"} ${matchSubstring ? "(subString mode)" : ""}:
|
|
8471
8565
|
|
|
8472
8566
|
`;
|
|
8473
|
-
|
|
8474
|
-
|
|
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();
|
|
8475
8579
|
} catch (error) {
|
|
8476
8580
|
return `ERROR: ${error.message}`;
|
|
8477
8581
|
}
|
|
@@ -12869,7 +12973,7 @@ ${boxBottom}`}`) };
|
|
|
12869
12973
|
const { keyword, file } = parseArgs(toolCall.args);
|
|
12870
12974
|
let matchCount = 0;
|
|
12871
12975
|
if (result) {
|
|
12872
|
-
const m = result.match(/Found (\d+)
|
|
12976
|
+
const m = result.match(/Found (\d+) match/i);
|
|
12873
12977
|
if (m) {
|
|
12874
12978
|
matchCount = parseInt(m[1]);
|
|
12875
12979
|
}
|
|
@@ -13034,7 +13138,7 @@ ${colorMainWords(output)}` };
|
|
|
13034
13138
|
if (!hasFinish2 && !hasContinue2 && !didCallTool && signalSafeText2.length > 0 && !endsNormally && !isThinkingLoop && !isStutteringLoop && !isGeneralLoop) {
|
|
13035
13139
|
}
|
|
13036
13140
|
success = true;
|
|
13037
|
-
await incrementUsage("agent");
|
|
13141
|
+
await incrementUsage("agent", aiProvider);
|
|
13038
13142
|
} catch (err) {
|
|
13039
13143
|
if (TERMINATION_SIGNAL) {
|
|
13040
13144
|
yield { type: "status", content: "Request Cancelled" };
|
|
@@ -13052,7 +13156,7 @@ ${colorMainWords(output)}` };
|
|
|
13052
13156
|
}
|
|
13053
13157
|
}
|
|
13054
13158
|
success = true;
|
|
13055
|
-
await incrementUsage("agent");
|
|
13159
|
+
await incrementUsage("agent", aiProvider);
|
|
13056
13160
|
break;
|
|
13057
13161
|
}
|
|
13058
13162
|
if (inThinkingState) {
|
|
@@ -14568,8 +14672,13 @@ function App({ args = [] }) {
|
|
|
14568
14672
|
};
|
|
14569
14673
|
const [activeView, setActiveView] = useState14("chat");
|
|
14570
14674
|
const [apiTier, setApiTier] = useState14("Free");
|
|
14571
|
-
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: {} });
|
|
14572
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({});
|
|
14573
14682
|
const [systemSettings, setSystemSettings] = useState14({ memory: true, compression: 0, autoExec: false, autoDeleteHistory: "7d", autoUpdate: false, updateManager: "npm", customUpdateCommand: "" });
|
|
14574
14683
|
const [profileData, setProfileData] = useState14({ name: null, nickname: null, instructions: null });
|
|
14575
14684
|
const [imageSettings, setImageSettings] = useState14({ keyType: "Default", quality: "Low-High", apiKey: "" });
|
|
@@ -15025,6 +15134,34 @@ function App({ args = [] }) {
|
|
|
15025
15134
|
}
|
|
15026
15135
|
return;
|
|
15027
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
|
+
}
|
|
15028
15165
|
if (key.escape) {
|
|
15029
15166
|
if (showBtwBox) {
|
|
15030
15167
|
setShowBtwBox(false);
|
|
@@ -15183,7 +15320,8 @@ function App({ args = [] }) {
|
|
|
15183
15320
|
}
|
|
15184
15321
|
const startupProvider = parsedArgs.provider || saved.aiProvider || "Google";
|
|
15185
15322
|
setAiProvider(startupProvider);
|
|
15186
|
-
const
|
|
15323
|
+
const providerTiers = saved.quotas?.providerTiers || {};
|
|
15324
|
+
const currentTier = providerTiers[startupProvider] || saved.apiTier || "Free";
|
|
15187
15325
|
persistedModelRef.current = saved.activeModel;
|
|
15188
15326
|
if (parsedArgs.model) {
|
|
15189
15327
|
setActiveModel(parsedArgs.model);
|
|
@@ -15215,8 +15353,8 @@ function App({ args = [] }) {
|
|
|
15215
15353
|
setActiveModel(saved.activeModel);
|
|
15216
15354
|
}
|
|
15217
15355
|
setShowFullThinking(saved.showFullThinking);
|
|
15218
|
-
setApiTier(
|
|
15219
|
-
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: {} });
|
|
15220
15358
|
const freshSettings = {
|
|
15221
15359
|
memory: true,
|
|
15222
15360
|
compression: 0,
|
|
@@ -15735,7 +15873,8 @@ function App({ args = [] }) {
|
|
|
15735
15873
|
desc: "Set or View budget limits",
|
|
15736
15874
|
subs: [
|
|
15737
15875
|
{ cmd: "view", desc: "View current usage budget bars" },
|
|
15738
|
-
{ 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" }
|
|
15739
15878
|
]
|
|
15740
15879
|
},
|
|
15741
15880
|
{
|
|
@@ -16386,28 +16525,8 @@ ${list || "No saved chats found."}`, isMeta: true }];
|
|
|
16386
16525
|
case "/budget": {
|
|
16387
16526
|
const sub = parts[1]?.toLowerCase();
|
|
16388
16527
|
if (sub === "set") {
|
|
16389
|
-
|
|
16390
|
-
|
|
16391
|
-
key: "quotas",
|
|
16392
|
-
subKey: "agentLimit",
|
|
16393
|
-
value: getPrefilledValue(quotas.agentLimit),
|
|
16394
|
-
returnView: "chat",
|
|
16395
|
-
next: (newQuotas) => ({
|
|
16396
|
-
label: "Enter Agent daily budget (tokens used):",
|
|
16397
|
-
key: "quotas",
|
|
16398
|
-
subKey: "tokenLimit",
|
|
16399
|
-
value: getPrefilledValue(newQuotas.tokenLimit),
|
|
16400
|
-
returnView: "chat",
|
|
16401
|
-
next: (q2) => ({
|
|
16402
|
-
label: "Enter Agent monthly budget (tokens used):",
|
|
16403
|
-
key: "quotas",
|
|
16404
|
-
subKey: "monthlyTokenLimit",
|
|
16405
|
-
value: getPrefilledValue(q2.monthlyTokenLimit),
|
|
16406
|
-
returnView: "budgetResetMode"
|
|
16407
|
-
})
|
|
16408
|
-
})
|
|
16409
|
-
});
|
|
16410
|
-
setActiveView("input");
|
|
16528
|
+
setBudgetReturnView("chat");
|
|
16529
|
+
setActiveView("budgetTypeSelect");
|
|
16411
16530
|
} else if (sub === "view") {
|
|
16412
16531
|
const run = async () => {
|
|
16413
16532
|
const usage = await getDailyUsage();
|
|
@@ -16419,10 +16538,34 @@ ${list || "No saved chats found."}`, isMeta: true }];
|
|
|
16419
16538
|
setActiveView("budgetView");
|
|
16420
16539
|
};
|
|
16421
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
|
+
});
|
|
16422
16565
|
} else {
|
|
16423
16566
|
setMessages((prev) => {
|
|
16424
16567
|
setCompletedIndex(prev.length + 1);
|
|
16425
|
-
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 }];
|
|
16426
16569
|
});
|
|
16427
16570
|
}
|
|
16428
16571
|
break;
|
|
@@ -17230,6 +17373,87 @@ Selection: ${val}`,
|
|
|
17230
17373
|
useEffect11(() => {
|
|
17231
17374
|
setSelectedIndex(0);
|
|
17232
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]);
|
|
17233
17457
|
const CustomMenuItem = ({ label: label2, isSelected }) => {
|
|
17234
17458
|
const isCancel = label2 === "Cancel" || label2 === "Back" || label2.toLowerCase().includes("exit") || label2.toLowerCase().includes("back");
|
|
17235
17459
|
return /* @__PURE__ */ React15.createElement(
|
|
@@ -17308,7 +17532,9 @@ Selection: ${val}`,
|
|
|
17308
17532
|
defaultModel = "moonshotai/kimi-k2.6";
|
|
17309
17533
|
}
|
|
17310
17534
|
setActiveModel(defaultModel);
|
|
17311
|
-
|
|
17535
|
+
const targetTier = (quotas.providerTiers || {})[selectedProvider] || "Free";
|
|
17536
|
+
setApiTier(targetTier);
|
|
17537
|
+
saveSettings({ aiProvider: selectedProvider, activeModel: defaultModel, apiTier: targetTier, quotas });
|
|
17312
17538
|
setMessages((prev) => [
|
|
17313
17539
|
...prev,
|
|
17314
17540
|
{
|
|
@@ -17333,30 +17559,12 @@ Selection: ${val}`,
|
|
|
17333
17559
|
}
|
|
17334
17560
|
);
|
|
17335
17561
|
case "apiTier": {
|
|
17336
|
-
|
|
17337
|
-
const reqLimit = quotas.agentLimit || 99999999;
|
|
17338
|
-
const tokenCurrent = dailyUsage?.tokens || 0;
|
|
17339
|
-
const tokenLimit = quotas.tokenLimit || 99999999999999;
|
|
17340
|
-
const monthlyCurrent = quotas.resetMode === "Custom" ? customPeriodUsage?.tokens || 0 : monthlyUsage?.tokens || 0;
|
|
17341
|
-
const monthlyLimit = quotas.monthlyTokenLimit || 99999999999999;
|
|
17342
|
-
let resetInfo = "";
|
|
17343
|
-
if (quotas.resetMode === "Custom") {
|
|
17344
|
-
const today = /* @__PURE__ */ new Date();
|
|
17345
|
-
const resetDay = quotas.resetDay || 1;
|
|
17346
|
-
let resetMonth = today.getMonth();
|
|
17347
|
-
if (today.getDate() >= resetDay) {
|
|
17348
|
-
resetMonth += 1;
|
|
17349
|
-
}
|
|
17350
|
-
const resetDate = new Date(today.getFullYear(), resetMonth, resetDay);
|
|
17351
|
-
const monthName = resetDate.toLocaleString("default", { month: "short" });
|
|
17352
|
-
resetInfo = `Resets on: ${resetDay}-${monthName}`;
|
|
17353
|
-
}
|
|
17354
|
-
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(
|
|
17355
17563
|
SelectInput2,
|
|
17356
17564
|
{
|
|
17357
17565
|
items: [
|
|
17358
|
-
{ label: "
|
|
17359
|
-
{ label: `
|
|
17566
|
+
{ label: "Free Key [Basic set of Models]", value: "Free" },
|
|
17567
|
+
{ label: `Billing Key [Premium Models Available] ${apiTier === "Paid" ? "\u25CF" : ""}`, value: "Paid" },
|
|
17360
17568
|
{ label: "Back", value: "settings" }
|
|
17361
17569
|
],
|
|
17362
17570
|
onSelect: (item) => {
|
|
@@ -17366,40 +17574,22 @@ Selection: ${val}`,
|
|
|
17366
17574
|
}
|
|
17367
17575
|
const newTier = item.value;
|
|
17368
17576
|
setApiTier(newTier);
|
|
17369
|
-
|
|
17370
|
-
|
|
17371
|
-
|
|
17372
|
-
|
|
17373
|
-
|
|
17374
|
-
|
|
17375
|
-
|
|
17376
|
-
|
|
17377
|
-
|
|
17378
|
-
|
|
17379
|
-
|
|
17380
|
-
value: getPrefilledValue(newQuotas.tokenLimit),
|
|
17381
|
-
returnView: "settings",
|
|
17382
|
-
next: (q2) => ({
|
|
17383
|
-
label: "Enter Agent monthly budget (tokens used):",
|
|
17384
|
-
key: "quotas",
|
|
17385
|
-
subKey: "monthlyTokenLimit",
|
|
17386
|
-
value: getPrefilledValue(q2.monthlyTokenLimit),
|
|
17387
|
-
returnView: "resetMode"
|
|
17388
|
-
})
|
|
17389
|
-
})
|
|
17390
|
-
});
|
|
17391
|
-
setActiveView("input");
|
|
17392
|
-
} else {
|
|
17393
|
-
const newQuotas = { ...quotas, agentLimit: 99999999, tokenLimit: 99999999999999, monthlyTokenLimit: 99999999999999 };
|
|
17394
|
-
setQuotas(newQuotas);
|
|
17395
|
-
saveSettings({ apiTier: newTier, quotas: newQuotas });
|
|
17396
|
-
setActiveView("settings");
|
|
17397
|
-
}
|
|
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");
|
|
17398
17588
|
},
|
|
17399
17589
|
itemComponent: CustomMenuItem,
|
|
17400
17590
|
indicatorComponent: () => null
|
|
17401
17591
|
}
|
|
17402
|
-
),
|
|
17592
|
+
), /* @__PURE__ */ React15.createElement(Box15, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text16, { color: "gray", italic: true }, "(Arrows to select \u2022 Enter to confirm)")));
|
|
17403
17593
|
}
|
|
17404
17594
|
case "resetMode":
|
|
17405
17595
|
return /* @__PURE__ */ React15.createElement(
|
|
@@ -17436,6 +17626,82 @@ Selection: ${val}`,
|
|
|
17436
17626
|
onClose: () => setActiveView("apiTier")
|
|
17437
17627
|
}
|
|
17438
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;
|
|
17439
17705
|
case "budgetResetMode":
|
|
17440
17706
|
return /* @__PURE__ */ React15.createElement(
|
|
17441
17707
|
CommandMenu,
|
|
@@ -17479,7 +17745,12 @@ Selection: ${val}`,
|
|
|
17479
17745
|
const monthlyCurrent = quotas.resetMode === "Custom" ? customPeriodUsage?.tokens || 0 : monthlyUsage?.tokens || 0;
|
|
17480
17746
|
const monthlyLimit = quotas.monthlyTokenLimit || 99999999999999;
|
|
17481
17747
|
const isFreeTier = apiTier !== "Paid";
|
|
17482
|
-
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));
|
|
17483
17754
|
let resetInfo = "";
|
|
17484
17755
|
if (quotas.resetMode === "Custom") {
|
|
17485
17756
|
const today = /* @__PURE__ */ new Date();
|
|
@@ -17492,7 +17763,22 @@ Selection: ${val}`,
|
|
|
17492
17763
|
const monthName = resetDate.toLocaleString("default", { month: "short" });
|
|
17493
17764
|
resetInfo = `Resets on: ${resetDay}-${monthName}`;
|
|
17494
17765
|
}
|
|
17495
|
-
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"))));
|
|
17496
17782
|
}
|
|
17497
17783
|
case "input":
|
|
17498
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(
|
|
@@ -17501,7 +17787,7 @@ Selection: ${val}`,
|
|
|
17501
17787
|
value: inputConfig?.value || "",
|
|
17502
17788
|
onChange: (val) => setInputConfig((prev) => ({ ...prev, value: val })),
|
|
17503
17789
|
onSubmit: async (val) => {
|
|
17504
|
-
const { key, subKey, next } = inputConfig;
|
|
17790
|
+
const { key, subKey, next, onDone } = inputConfig;
|
|
17505
17791
|
let newQuotas = { ...quotas };
|
|
17506
17792
|
let newSettings = {};
|
|
17507
17793
|
if (key === "quotas") {
|
|
@@ -17512,6 +17798,19 @@ Selection: ${val}`,
|
|
|
17512
17798
|
newQuotas[subKey] = parsedValue;
|
|
17513
17799
|
setQuotas(newQuotas);
|
|
17514
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;
|
|
17515
17814
|
} else if (key === "activeModel") {
|
|
17516
17815
|
setActiveModel(val);
|
|
17517
17816
|
newSettings.activeModel = val;
|
|
@@ -17561,15 +17860,23 @@ Selection: ${val}`,
|
|
|
17561
17860
|
defaultModel = "moonshotai/kimi-k2.6";
|
|
17562
17861
|
}
|
|
17563
17862
|
setActiveModel(defaultModel);
|
|
17863
|
+
const targetTier = (quotas.providerTiers || {})[prov] || "Free";
|
|
17864
|
+
setApiTier(targetTier);
|
|
17564
17865
|
newSettings.aiProvider = prov;
|
|
17565
17866
|
newSettings.activeModel = defaultModel;
|
|
17867
|
+
newSettings.apiTier = targetTier;
|
|
17566
17868
|
setMessages((prev) => {
|
|
17567
17869
|
setCompletedIndex(prev.length + 1);
|
|
17568
17870
|
return [...prev, { id: Date.now(), role: "system", text: `\u2705 ${prov} API Key saved successfully! Model set to ${defaultModel}.`, isMeta: true }];
|
|
17569
17871
|
});
|
|
17570
17872
|
}
|
|
17571
17873
|
if (next) {
|
|
17572
|
-
|
|
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);
|
|
17573
17880
|
} else {
|
|
17574
17881
|
saveSettings({ ...newSettings, apiTier, quotas: newQuotas, imageSettings: newSettings.imageSettings || imageSettings });
|
|
17575
17882
|
setInputConfig(null);
|
|
@@ -18063,7 +18370,7 @@ Selection: ${val}`,
|
|
|
18063
18370
|
setSetupStep(1);
|
|
18064
18371
|
}
|
|
18065
18372
|
}
|
|
18066
|
-
))) : /* @__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(
|
|
18067
18374
|
TextInput4,
|
|
18068
18375
|
{
|
|
18069
18376
|
value: tempKey,
|