farming-code 2.2.19 → 2.2.20
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/backend/server.js +5 -1
- package/backend/terminal-screen-worker-pool.js +15 -6
- package/backend/usage-monitor.js +11 -0
- package/dist/assets/{App-CbXYBccJ.js → App-BupehIbc.js} +12 -12
- package/dist/assets/{code-dark-qIBiLBWV.css → code-dark-BAt0Q_Op.css} +1 -1
- package/dist/assets/{index-DQdtPfCk.js → index-DuMjesL2.js} +2 -2
- package/dist/assets/{main-yzZEfgft.css → main-y2aK_56c.css} +1 -1
- package/dist/index.html +1 -1
- package/frontend/skins/crt/app.js +166 -26
- package/frontend/skins/crt/index.html +5 -10
- package/frontend/skins/crt/styles/billing.css +6 -1
- package/package.json +1 -1
package/dist/index.html
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
<link rel="apple-touch-icon" sizes="180x180" href="/farming/farming-2/app-icon-v2-180.png" />
|
|
16
16
|
<link rel="manifest" href="/farming/farming-2/site.webmanifest" />
|
|
17
17
|
<title>Farming 2</title>
|
|
18
|
-
<script type="module" crossorigin src="/farming/assets/index-
|
|
18
|
+
<script type="module" crossorigin src="/farming/assets/index-DuMjesL2.js"></script>
|
|
19
19
|
<link rel="modulepreload" crossorigin href="/farming/assets/chunk-DECur_0Z.js">
|
|
20
20
|
<link rel="modulepreload" crossorigin href="/farming/assets/preload-helper-mJowh_hw.js">
|
|
21
21
|
<link rel="modulepreload" crossorigin href="/farming/assets/jsx-runtime-BthL93pI.js">
|
|
@@ -55,6 +55,9 @@ let billingRequestSequence = 0;
|
|
|
55
55
|
let billingAbortController = null;
|
|
56
56
|
let billingRefreshTimer = null;
|
|
57
57
|
let billingLiveDayRefreshTimer = null;
|
|
58
|
+
let crtTokenRateRefreshTimer = null;
|
|
59
|
+
let crtTokenRateFirstLoadTimer = null;
|
|
60
|
+
let crtTokenRateAbortController = null;
|
|
58
61
|
let billingCanvasFrame = null;
|
|
59
62
|
let billingMode = 'days';
|
|
60
63
|
let billingSelectedDate = '';
|
|
@@ -116,8 +119,10 @@ const CRT_AGENT_GRID_GAP = 15;
|
|
|
116
119
|
const CRT_AGENT_GRID_PADDING = 20;
|
|
117
120
|
const CRT_SEARCH_DEBOUNCE_MS = 180;
|
|
118
121
|
const CRT_SEARCH_RESULT_LIMIT = 100;
|
|
119
|
-
const CRT_BILLING_REFRESH_MS =
|
|
122
|
+
const CRT_BILLING_REFRESH_MS = 15_000;
|
|
120
123
|
const CRT_BILLING_LIVE_DAY_REFRESH_MS = 5_000;
|
|
124
|
+
const CRT_TOKEN_RATE_REFRESH_MS = 60_000;
|
|
125
|
+
const CRT_TOKEN_RATE_FIRST_LOAD_MS = 1_500;
|
|
121
126
|
const CRT_BILLING_DAY_DETAIL_CACHE_MS = 30_000;
|
|
122
127
|
const CRT_BILLING_TOTAL_ANIMATION_MS = 900;
|
|
123
128
|
const CRT_BILLING_DAY_DETAIL_RETRY_MS = 750;
|
|
@@ -3159,6 +3164,7 @@ function setCrtMainView(view) {
|
|
|
3159
3164
|
if (historySidebarItem) historySidebarItem.classList.toggle('active', crtMainView === 'history');
|
|
3160
3165
|
if (searchSidebarItem) searchSidebarItem.classList.toggle('active', crtMainView === 'search');
|
|
3161
3166
|
if (billingSidebarItem) billingSidebarItem.classList.toggle('active', crtMainView === 'billing');
|
|
3167
|
+
if (previousView !== 'agents' && crtMainView === 'agents') checkMainAgentStatus();
|
|
3162
3168
|
}
|
|
3163
3169
|
|
|
3164
3170
|
function getCrtSearchResults() {
|
|
@@ -4006,6 +4012,30 @@ function scrollCrtBillingSelectedDayIntoView() {
|
|
|
4006
4012
|
else if (right > scroll.scrollLeft + scroll.clientWidth) scroll.scrollLeft = right - scroll.clientWidth;
|
|
4007
4013
|
}
|
|
4008
4014
|
|
|
4015
|
+
function crtBillingDayArrowTargetIndex(points, index, key) {
|
|
4016
|
+
if (!Array.isArray(points) || index < 0 || index >= points.length) return -1;
|
|
4017
|
+
const firstDate = parseCrtBillingDate(points[0] && points[0].date);
|
|
4018
|
+
const leadingDays = firstDate ? (firstDate.getDay() + 6) % 7 : 0;
|
|
4019
|
+
const position = leadingDays + index;
|
|
4020
|
+
const weekdayRow = position % 7;
|
|
4021
|
+
let targetPosition = position;
|
|
4022
|
+
if (key === 'ArrowUp') {
|
|
4023
|
+
if (weekdayRow === 0) return -1;
|
|
4024
|
+
targetPosition -= 1;
|
|
4025
|
+
} else if (key === 'ArrowDown') {
|
|
4026
|
+
if (weekdayRow === 6) return -1;
|
|
4027
|
+
targetPosition += 1;
|
|
4028
|
+
} else if (key === 'ArrowLeft') {
|
|
4029
|
+
targetPosition -= 7;
|
|
4030
|
+
} else if (key === 'ArrowRight') {
|
|
4031
|
+
targetPosition += 7;
|
|
4032
|
+
} else {
|
|
4033
|
+
return -1;
|
|
4034
|
+
}
|
|
4035
|
+
const targetIndex = targetPosition - leadingDays;
|
|
4036
|
+
return targetIndex >= 0 && targetIndex < points.length ? targetIndex : -1;
|
|
4037
|
+
}
|
|
4038
|
+
|
|
4009
4039
|
function selectCrtBillingDayByArrow(key) {
|
|
4010
4040
|
if (crtMainView !== 'billing' || billingMode !== 'days') return false;
|
|
4011
4041
|
const points = billingSummary && billingSummary.daily && Array.isArray(billingSummary.daily.points)
|
|
@@ -4014,8 +4044,8 @@ function selectCrtBillingDayByArrow(key) {
|
|
|
4014
4044
|
if (points.length === 0) return false;
|
|
4015
4045
|
let index = points.findIndex(point => point.date === billingSelectedDate);
|
|
4016
4046
|
if (index < 0) index = points.length - 1;
|
|
4017
|
-
const
|
|
4018
|
-
|
|
4047
|
+
const nextIndex = crtBillingDayArrowTargetIndex(points, index, key);
|
|
4048
|
+
if (nextIndex < 0) return false;
|
|
4019
4049
|
return selectCrtBillingDay(points[nextIndex].date, { focus: true });
|
|
4020
4050
|
}
|
|
4021
4051
|
|
|
@@ -4156,11 +4186,35 @@ function setCrtBillingMode(mode) {
|
|
|
4156
4186
|
}
|
|
4157
4187
|
const status = document.getElementById('billing-status');
|
|
4158
4188
|
if (status && billingSummary && !billingLoading && !billingError) {
|
|
4159
|
-
status.textContent =
|
|
4189
|
+
status.textContent = crtBillingStatusText();
|
|
4160
4190
|
}
|
|
4161
4191
|
if (billingMode === 'live') window.requestAnimationFrame(() => drawCrtBillingScope());
|
|
4162
4192
|
}
|
|
4163
4193
|
|
|
4194
|
+
function selectCrtBillingMode(mode) {
|
|
4195
|
+
setCrtBillingMode(mode);
|
|
4196
|
+
const selectedTab = document.getElementById(
|
|
4197
|
+
billingMode === 'live' ? 'billing-live-tab' : 'billing-days-tab',
|
|
4198
|
+
);
|
|
4199
|
+
if (selectedTab) setCrtNavigationSelection(selectedTab);
|
|
4200
|
+
if (billingMode === 'live' && !billingLoading) void loadCrtBilling();
|
|
4201
|
+
}
|
|
4202
|
+
|
|
4203
|
+
function crtBillingTimeline(summary = billingSummary) {
|
|
4204
|
+
return summary && summary.liveTimeline || summary && summary.timeline || null;
|
|
4205
|
+
}
|
|
4206
|
+
|
|
4207
|
+
function crtBillingStatusText(summary = billingSummary) {
|
|
4208
|
+
if (billingMode === 'days') return 'HISTORY READY';
|
|
4209
|
+
const sampledAt = Number(summary && summary.sampledAt);
|
|
4210
|
+
if (!Number.isFinite(sampledAt) || sampledAt <= 0) return 'LIVE';
|
|
4211
|
+
const sampled = new Date(sampledAt);
|
|
4212
|
+
const time = [sampled.getHours(), sampled.getMinutes(), sampled.getSeconds()]
|
|
4213
|
+
.map(value => String(value).padStart(2, '0'))
|
|
4214
|
+
.join(':');
|
|
4215
|
+
return `LIVE ${time}`;
|
|
4216
|
+
}
|
|
4217
|
+
|
|
4164
4218
|
function formatCrtBillingWindow(windowMinutes) {
|
|
4165
4219
|
const minutes = Number(windowMinutes);
|
|
4166
4220
|
if (!Number.isFinite(minutes) || minutes <= 0) return 'WINDOW';
|
|
@@ -4214,6 +4268,13 @@ function crtBillingCurrentRate(summary = billingSummary) {
|
|
|
4214
4268
|
return hasRate ? total : null;
|
|
4215
4269
|
}
|
|
4216
4270
|
|
|
4271
|
+
function renderCrtTopBarTokenRate(summary = billingSummary) {
|
|
4272
|
+
const tokensPerMinute = document.getElementById('tokens-per-minute');
|
|
4273
|
+
if (tokensPerMinute) {
|
|
4274
|
+
tokensPerMinute.textContent = formatCrtTokenRate(crtBillingCurrentRate(summary));
|
|
4275
|
+
}
|
|
4276
|
+
}
|
|
4277
|
+
|
|
4217
4278
|
function appendCrtBillingMessage(container, text, isError = false) {
|
|
4218
4279
|
const message = document.createElement('div');
|
|
4219
4280
|
message.className = `billing-message${isError ? ' is-error' : ''}`;
|
|
@@ -4314,7 +4375,7 @@ function drawCrtBillingScope(summary = billingSummary) {
|
|
|
4314
4375
|
context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
|
|
4315
4376
|
context.clearRect(0, 0, rect.width, rect.height);
|
|
4316
4377
|
|
|
4317
|
-
const timeline = summary
|
|
4378
|
+
const timeline = crtBillingTimeline(summary);
|
|
4318
4379
|
const points = timeline && Array.isArray(timeline.points) ? timeline.points : [];
|
|
4319
4380
|
const values = points.map(point => Math.max(0, Number(point.tokensPerMinute) || 0));
|
|
4320
4381
|
const providerNames = points.length > 0 ? Object.keys(points[0].providers || {}) : [];
|
|
@@ -4392,7 +4453,7 @@ function renderCrtBilling() {
|
|
|
4392
4453
|
const status = document.getElementById('billing-status');
|
|
4393
4454
|
const refresh = document.getElementById('billing-refresh');
|
|
4394
4455
|
const empty = document.getElementById('billing-scope-empty');
|
|
4395
|
-
const timeline =
|
|
4456
|
+
const timeline = crtBillingTimeline();
|
|
4396
4457
|
const hasSignal = Boolean(timeline && Number(timeline.totalTokens) > 0);
|
|
4397
4458
|
if (status) {
|
|
4398
4459
|
status.classList.toggle('is-busy', billingLoading);
|
|
@@ -4402,7 +4463,7 @@ function renderCrtBilling() {
|
|
|
4402
4463
|
: billingLoading
|
|
4403
4464
|
? (billingSummary ? 'REFRESHING' : 'SCANNING LOGS')
|
|
4404
4465
|
: billingSummary
|
|
4405
|
-
? (
|
|
4466
|
+
? crtBillingStatusText()
|
|
4406
4467
|
: 'STANDBY';
|
|
4407
4468
|
}
|
|
4408
4469
|
if (refresh) refresh.disabled = billingLoading;
|
|
@@ -4449,13 +4510,18 @@ async function loadCrtBilling({ fresh = false } = {}) {
|
|
|
4449
4510
|
billingRequestSequence += 1;
|
|
4450
4511
|
const requestSequence = billingRequestSequence;
|
|
4451
4512
|
if (billingAbortController) billingAbortController.abort();
|
|
4513
|
+
if (crtTokenRateAbortController) {
|
|
4514
|
+
crtTokenRateAbortController.abort();
|
|
4515
|
+
crtTokenRateAbortController = null;
|
|
4516
|
+
}
|
|
4452
4517
|
const controller = new window.AbortController();
|
|
4453
4518
|
billingAbortController = controller;
|
|
4454
4519
|
billingLoading = true;
|
|
4455
4520
|
billingError = '';
|
|
4456
4521
|
renderCrtBilling();
|
|
4457
4522
|
try {
|
|
4458
|
-
const
|
|
4523
|
+
const query = fresh ? '?fresh=1' : billingMode === 'live' ? '?live=1' : '';
|
|
4524
|
+
const response = await fetch(farmingApiPath(`/usage${query}`), {
|
|
4459
4525
|
signal: controller.signal,
|
|
4460
4526
|
cache: 'no-store',
|
|
4461
4527
|
});
|
|
@@ -4463,6 +4529,7 @@ async function loadCrtBilling({ fresh = false } = {}) {
|
|
|
4463
4529
|
if (!response.ok || !data || !data.usage) throw new Error(data && data.error ? data.error : `Usage request failed (${response.status})`);
|
|
4464
4530
|
if (requestSequence !== billingRequestSequence) return;
|
|
4465
4531
|
billingSummary = data.usage;
|
|
4532
|
+
renderCrtTopBarTokenRate();
|
|
4466
4533
|
} catch (error) {
|
|
4467
4534
|
if (controller.signal.aborted || requestSequence !== billingRequestSequence) return;
|
|
4468
4535
|
billingError = error instanceof Error ? error.message : 'Failed to load token telemetry';
|
|
@@ -4481,6 +4548,58 @@ async function loadCrtBilling({ fresh = false } = {}) {
|
|
|
4481
4548
|
}
|
|
4482
4549
|
}
|
|
4483
4550
|
|
|
4551
|
+
async function loadCrtTopBarTokenRate() {
|
|
4552
|
+
if (billingLoading || crtTokenRateAbortController) return;
|
|
4553
|
+
const controller = new window.AbortController();
|
|
4554
|
+
crtTokenRateAbortController = controller;
|
|
4555
|
+
try {
|
|
4556
|
+
const response = await fetch(farmingApiPath('/usage'), {
|
|
4557
|
+
signal: controller.signal,
|
|
4558
|
+
cache: 'no-store',
|
|
4559
|
+
});
|
|
4560
|
+
const data = await response.json().catch(() => null);
|
|
4561
|
+
if (controller.signal.aborted) return;
|
|
4562
|
+
if (!response.ok || !data || !data.usage) {
|
|
4563
|
+
throw new Error(data && data.error ? data.error : `Usage request failed (${response.status})`);
|
|
4564
|
+
}
|
|
4565
|
+
renderCrtTopBarTokenRate(data.usage);
|
|
4566
|
+
} catch {
|
|
4567
|
+
if (!controller.signal.aborted) renderCrtTopBarTokenRate(null);
|
|
4568
|
+
} finally {
|
|
4569
|
+
if (crtTokenRateAbortController === controller) crtTokenRateAbortController = null;
|
|
4570
|
+
}
|
|
4571
|
+
}
|
|
4572
|
+
|
|
4573
|
+
function stopCrtTopBarTokenRateRefresh({ abort = false } = {}) {
|
|
4574
|
+
if (crtTokenRateFirstLoadTimer !== null) {
|
|
4575
|
+
clearTimeout(crtTokenRateFirstLoadTimer);
|
|
4576
|
+
crtTokenRateFirstLoadTimer = null;
|
|
4577
|
+
}
|
|
4578
|
+
if (crtTokenRateRefreshTimer !== null) {
|
|
4579
|
+
clearInterval(crtTokenRateRefreshTimer);
|
|
4580
|
+
crtTokenRateRefreshTimer = null;
|
|
4581
|
+
}
|
|
4582
|
+
if (abort && crtTokenRateAbortController) {
|
|
4583
|
+
crtTokenRateAbortController.abort();
|
|
4584
|
+
crtTokenRateAbortController = null;
|
|
4585
|
+
}
|
|
4586
|
+
}
|
|
4587
|
+
|
|
4588
|
+
function startCrtTopBarTokenRateRefresh({ immediate = false } = {}) {
|
|
4589
|
+
stopCrtTopBarTokenRateRefresh();
|
|
4590
|
+
if (immediate) {
|
|
4591
|
+
void loadCrtTopBarTokenRate();
|
|
4592
|
+
} else {
|
|
4593
|
+
crtTokenRateFirstLoadTimer = setTimeout(() => {
|
|
4594
|
+
crtTokenRateFirstLoadTimer = null;
|
|
4595
|
+
if (document.visibilityState !== 'hidden') void loadCrtTopBarTokenRate();
|
|
4596
|
+
}, CRT_TOKEN_RATE_FIRST_LOAD_MS);
|
|
4597
|
+
}
|
|
4598
|
+
crtTokenRateRefreshTimer = setInterval(() => {
|
|
4599
|
+
if (document.visibilityState !== 'hidden') void loadCrtTopBarTokenRate();
|
|
4600
|
+
}, CRT_TOKEN_RATE_REFRESH_MS);
|
|
4601
|
+
}
|
|
4602
|
+
|
|
4484
4603
|
function stopCrtBillingRefresh({ abort = false } = {}) {
|
|
4485
4604
|
if (billingRefreshTimer !== null) {
|
|
4486
4605
|
clearInterval(billingRefreshTimer);
|
|
@@ -5485,7 +5604,7 @@ function connect() {
|
|
|
5485
5604
|
else scheduleCrtPreviewCardRender(agent);
|
|
5486
5605
|
}
|
|
5487
5606
|
} else if (data.type === 'system-stats') {
|
|
5488
|
-
updateSystemStats(data.stats, data.uptime
|
|
5607
|
+
updateSystemStats(data.stats, data.uptime);
|
|
5489
5608
|
} else if (data.type === 'error') {
|
|
5490
5609
|
waitingForAgent = false;
|
|
5491
5610
|
if (workspaceDirectoryPrompt?.kind === 'creating') {
|
|
@@ -5532,6 +5651,7 @@ function connect() {
|
|
|
5532
5651
|
function suspendCrtPageConnection() {
|
|
5533
5652
|
document.body.classList.add('page-hidden');
|
|
5534
5653
|
stopCrtBillingRefresh({ abort: true });
|
|
5654
|
+
stopCrtTopBarTokenRateRefresh({ abort: true });
|
|
5535
5655
|
if (wsReconnectTimer) {
|
|
5536
5656
|
clearTimeout(wsReconnectTimer);
|
|
5537
5657
|
wsReconnectTimer = null;
|
|
@@ -5545,6 +5665,7 @@ function resumeCrtPageConnection() {
|
|
|
5545
5665
|
if (document.visibilityState === 'hidden') return;
|
|
5546
5666
|
document.body.classList.remove('page-hidden');
|
|
5547
5667
|
connect();
|
|
5668
|
+
startCrtTopBarTokenRateRefresh({ immediate: true });
|
|
5548
5669
|
if (crtMainView === 'billing') {
|
|
5549
5670
|
startCrtBillingRefresh();
|
|
5550
5671
|
void loadCrtBilling();
|
|
@@ -5554,15 +5675,33 @@ function resumeCrtPageConnection() {
|
|
|
5554
5675
|
function checkMainAgentStatus() {
|
|
5555
5676
|
if (!state) return;
|
|
5556
5677
|
|
|
5557
|
-
const
|
|
5558
|
-
|
|
5559
|
-
:
|
|
5560
|
-
|
|
5561
|
-
|
|
5678
|
+
const inputDialog = document.getElementById('input-dialog');
|
|
5679
|
+
const action = getCrtMainAgentDialogAction({
|
|
5680
|
+
currentState: state,
|
|
5681
|
+
mainView: crtMainView,
|
|
5682
|
+
dialogActive: Boolean(inputDialog && inputDialog.classList.contains('active')),
|
|
5683
|
+
pendingMainAgent: pendingMainAgentLaunch,
|
|
5684
|
+
});
|
|
5685
|
+
if (action === 'hide') {
|
|
5686
|
+
hideInputDialog();
|
|
5687
|
+
} else if (action === 'show') {
|
|
5562
5688
|
showInputDialog();
|
|
5563
5689
|
}
|
|
5564
5690
|
}
|
|
5565
5691
|
|
|
5692
|
+
function getCrtMainAgentDialogAction({
|
|
5693
|
+
currentState,
|
|
5694
|
+
mainView = 'agents',
|
|
5695
|
+
dialogActive = false,
|
|
5696
|
+
pendingMainAgent = false,
|
|
5697
|
+
} = {}) {
|
|
5698
|
+
if (!needsMainAgent(currentState)) {
|
|
5699
|
+
return dialogActive && pendingMainAgent ? 'hide' : 'none';
|
|
5700
|
+
}
|
|
5701
|
+
if (mainView !== 'agents' || dialogActive) return 'none';
|
|
5702
|
+
return 'show';
|
|
5703
|
+
}
|
|
5704
|
+
|
|
5566
5705
|
function formatSystemClock(timestamp, timeZone) {
|
|
5567
5706
|
if (!Number.isFinite(timestamp)) return '--';
|
|
5568
5707
|
try {
|
|
@@ -5582,21 +5721,22 @@ function formatSystemClock(timestamp, timeZone) {
|
|
|
5582
5721
|
}
|
|
5583
5722
|
|
|
5584
5723
|
function formatCrtTokenRate(value) {
|
|
5724
|
+
if (value === null || value === undefined || value === '') return '--';
|
|
5585
5725
|
const rate = Number(value);
|
|
5586
5726
|
if (!Number.isFinite(rate) || rate < 0) return '--';
|
|
5587
5727
|
const rounded = rate < 10 ? Math.round(rate * 10) / 10 : Math.round(rate);
|
|
5588
5728
|
if (rounded >= 1_000_000) {
|
|
5589
5729
|
const compact = rounded / 1_000_000;
|
|
5590
|
-
return
|
|
5730
|
+
return `${compact >= 10 ? Math.round(compact) : Math.round(compact * 10) / 10}M`;
|
|
5591
5731
|
}
|
|
5592
5732
|
if (rounded >= 1_000) {
|
|
5593
5733
|
const compact = rounded / 1_000;
|
|
5594
|
-
return
|
|
5734
|
+
return `${compact >= 10 ? Math.round(compact) : Math.round(compact * 10) / 10}K`;
|
|
5595
5735
|
}
|
|
5596
|
-
return
|
|
5736
|
+
return String(rounded);
|
|
5597
5737
|
}
|
|
5598
5738
|
|
|
5599
|
-
function updateSystemStats(stats, uptime
|
|
5739
|
+
function updateSystemStats(stats, uptime) {
|
|
5600
5740
|
if (stats.cpu !== undefined) {
|
|
5601
5741
|
document.getElementById('cpu-usage').textContent = stats.cpu;
|
|
5602
5742
|
}
|
|
@@ -5613,11 +5753,6 @@ function updateSystemStats(stats, uptime, usageRate) {
|
|
|
5613
5753
|
document.getElementById('system-time').textContent = formatSystemClock(stats.timestamp, stats.timeZone);
|
|
5614
5754
|
}
|
|
5615
5755
|
|
|
5616
|
-
const tokensPerMinute = document.getElementById('tokens-per-minute');
|
|
5617
|
-
if (tokensPerMinute) {
|
|
5618
|
-
tokensPerMinute.textContent = formatCrtTokenRate(usageRate && usageRate.estimatedTokensPerMinute);
|
|
5619
|
-
}
|
|
5620
|
-
|
|
5621
5756
|
if (uptime !== undefined) {
|
|
5622
5757
|
const hours = Math.floor(uptime / 3600);
|
|
5623
5758
|
const minutes = Math.floor((uptime % 3600) / 60);
|
|
@@ -7952,13 +8087,14 @@ if (typeof document !== 'undefined') {
|
|
|
7952
8087
|
|
|
7953
8088
|
if (
|
|
7954
8089
|
crtMainView === 'billing'
|
|
8090
|
+
&& billingMode === 'days'
|
|
7955
8091
|
&& !sessionActive
|
|
7956
8092
|
&& !e.ctrlKey
|
|
7957
8093
|
&& !e.metaKey
|
|
7958
8094
|
&& !e.altKey
|
|
7959
8095
|
&& navigationArrow
|
|
7960
|
-
&& selectCrtBillingDayByArrow(e.key)
|
|
7961
8096
|
) {
|
|
8097
|
+
selectCrtBillingDayByArrow(e.key);
|
|
7962
8098
|
e.preventDefault();
|
|
7963
8099
|
return;
|
|
7964
8100
|
}
|
|
@@ -8152,13 +8288,13 @@ if (typeof document !== 'undefined') {
|
|
|
8152
8288
|
}
|
|
8153
8289
|
|
|
8154
8290
|
if ((e.key === 'd' || e.key === 'D') && crtMainView === 'billing') {
|
|
8155
|
-
|
|
8291
|
+
selectCrtBillingMode('days');
|
|
8156
8292
|
e.preventDefault();
|
|
8157
8293
|
return;
|
|
8158
8294
|
}
|
|
8159
8295
|
|
|
8160
8296
|
if ((e.key === 'l' || e.key === 'L') && crtMainView === 'billing') {
|
|
8161
|
-
|
|
8297
|
+
selectCrtBillingMode('live');
|
|
8162
8298
|
e.preventDefault();
|
|
8163
8299
|
return;
|
|
8164
8300
|
}
|
|
@@ -8329,7 +8465,9 @@ if (typeof module !== 'undefined' && module.exports) {
|
|
|
8329
8465
|
crtAgentSessionKey,
|
|
8330
8466
|
crtResumedSessionFromSource,
|
|
8331
8467
|
crtDashboardStateSignature,
|
|
8468
|
+
crtBillingDayArrowTargetIndex,
|
|
8332
8469
|
crtBillingTimelineLabels,
|
|
8470
|
+
crtBillingTimeline,
|
|
8333
8471
|
crtBillingCurrentRate,
|
|
8334
8472
|
findDefaultNewAgentIndex,
|
|
8335
8473
|
findDirectionalNavigationIndex,
|
|
@@ -8354,6 +8492,7 @@ if (typeof module !== 'undefined' && module.exports) {
|
|
|
8354
8492
|
getCrtAgentVerticalPageTarget,
|
|
8355
8493
|
getCrtLiveAgents,
|
|
8356
8494
|
getCrtRegularAgents,
|
|
8495
|
+
getCrtMainAgentDialogAction,
|
|
8357
8496
|
getCrtAgentRemovalFallback,
|
|
8358
8497
|
getAgentDisplayText,
|
|
8359
8498
|
getCrtPreviewCellStyle,
|
|
@@ -8398,5 +8537,6 @@ if (typeof module !== 'undefined' && module.exports) {
|
|
|
8398
8537
|
});
|
|
8399
8538
|
window.addEventListener('pagehide', suspendCrtPageConnection);
|
|
8400
8539
|
window.addEventListener('pageshow', resumeCrtPageConnection);
|
|
8540
|
+
startCrtTopBarTokenRateRefresh();
|
|
8401
8541
|
connect();
|
|
8402
8542
|
}
|
|
@@ -1475,7 +1475,7 @@
|
|
|
1475
1475
|
<div class="top-bar">
|
|
1476
1476
|
<div class="top-bar-item">AGENTS: <span id="active-agents">0</span>/<span id="total-agents">0</span></div>
|
|
1477
1477
|
<div class="top-bar-item" id="agent-page-item" hidden>PAGE: <span id="agent-page-status">1/1</span></div>
|
|
1478
|
-
<div class="top-bar-item" title="
|
|
1478
|
+
<div class="top-bar-item" title="Provider-reported tokens per minute over the last 5 minutes">TOK/MIN: <span id="tokens-per-minute">--</span></div>
|
|
1479
1479
|
<div class="top-bar-item">CPU: <span id="cpu-usage">--</span>%</div>
|
|
1480
1480
|
<div class="top-bar-item">MEM: <span id="mem-percentage">--</span>%</div>
|
|
1481
1481
|
<div class="top-bar-item" id="focus-region" style="display: none;">Focus: <span id="focus-region-name">--</span></div>
|
|
@@ -1545,8 +1545,8 @@
|
|
|
1545
1545
|
<h2>Billing</h2>
|
|
1546
1546
|
<div class="billing-header-actions">
|
|
1547
1547
|
<div class="billing-view-switch" role="tablist" aria-label="Billing view">
|
|
1548
|
-
<button type="button" id="billing-days-tab" class="active" role="tab" aria-selected="true" data-crt-nav-key="billing:days" tabindex="-1" onclick="
|
|
1549
|
-
<button type="button" id="billing-live-tab" role="tab" aria-selected="false" data-crt-nav-key="billing:live" tabindex="-1" onclick="
|
|
1548
|
+
<button type="button" id="billing-days-tab" class="active" role="tab" aria-selected="true" data-crt-nav-key="billing:days" tabindex="-1" onclick="selectCrtBillingMode('days')">[D] DAYS</button>
|
|
1549
|
+
<button type="button" id="billing-live-tab" role="tab" aria-selected="false" data-crt-nav-key="billing:live" tabindex="-1" onclick="selectCrtBillingMode('live')">[L] LIVE</button>
|
|
1550
1550
|
</div>
|
|
1551
1551
|
<span class="billing-status" id="billing-status">STANDBY</span>
|
|
1552
1552
|
</div>
|
|
@@ -1960,13 +1960,8 @@
|
|
|
1960
1960
|
</div>
|
|
1961
1961
|
</div>
|
|
1962
1962
|
|
|
1963
|
-
<h3 style="margin: 30px 0 15px; color: #00ff00;">
|
|
1964
|
-
<div id="
|
|
1965
|
-
<div class="settings-panel">
|
|
1966
|
-
<label style="display: block; color: #00ff00; margin-bottom: 10px;">Coding Agent Engine</label>
|
|
1967
|
-
<div class="settings-static-value">built-in</div>
|
|
1968
|
-
<div style="color: #888; font-size: 12px; margin-top: 8px;">Uses Farming's built-in local session runtime.</div>
|
|
1969
|
-
</div>
|
|
1963
|
+
<h3 style="margin: 30px 0 15px; color: #00ff00;">Agent Permissions</h3>
|
|
1964
|
+
<div id="agent-permission-settings">
|
|
1970
1965
|
<div class="settings-panel">
|
|
1971
1966
|
<label class="crt-checkbox-label" tabindex="-1" data-crt-nav-key="settings:skip-permissions">
|
|
1972
1967
|
<input type="checkbox" id="skip-permission-check-by-default" class="crt-checkbox danger">
|
|
@@ -50,7 +50,12 @@
|
|
|
50
50
|
|
|
51
51
|
#farming-crt .billing-view-switch button:hover,
|
|
52
52
|
#farming-crt .billing-view-switch button:focus-visible,
|
|
53
|
-
#farming-crt .billing-view-switch button.crt-nav-selected
|
|
53
|
+
#farming-crt .billing-view-switch button.crt-nav-selected {
|
|
54
|
+
color: var(--crt-phosphor-bright);
|
|
55
|
+
border-color: rgba(85, 245, 155, 0.72);
|
|
56
|
+
outline: none;
|
|
57
|
+
}
|
|
58
|
+
|
|
54
59
|
#farming-crt .billing-view-switch button.active {
|
|
55
60
|
color: var(--crt-background);
|
|
56
61
|
background: var(--crt-phosphor-bright);
|