pi-mega-compact 0.4.18 → 0.4.19
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.
|
@@ -99,6 +99,7 @@ function readSnapshot(snapshotPath) {
|
|
|
99
99
|
crew: { activeAgents: 0, currentTurn: 0 },
|
|
100
100
|
repo: { checkpointCount: 0, totalTokenEstimate: 0, originalTokens: 0, tokensSaved: 0, sessionCount: 0, dedupAttempts: 0, dedupCollapsed: 0, storageDedupRate: 0 },
|
|
101
101
|
integrity: { regionsRetained: 0, compressedOriginalBytes: 0, duplicatesCollapsed: 0, bytesPermanentlyDeleted: 0 },
|
|
102
|
+
model: undefined,
|
|
102
103
|
};
|
|
103
104
|
}
|
|
104
105
|
}
|
|
@@ -195,13 +196,26 @@ function dashboardHtml(tierName) {
|
|
|
195
196
|
.repo-model { color: #a371f7; }
|
|
196
197
|
.repo-none { color: #484f58; font-style: italic; }
|
|
197
198
|
.updated { font-size: 11px; color: #484f58; margin-top: 16px; text-align: right; }
|
|
199
|
+
.model-pill { background: #6e40c9; color: #fff; font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 10px; text-transform: uppercase; letter-spacing: .5px; }
|
|
200
|
+
.card.cost h2 { color: #a371f7; }
|
|
201
|
+
.cost-usd { font-size: 22px; font-weight: 700; color: #3fb950; }
|
|
202
|
+
.cost-sub { font-size: 12px; color: #8b949e; margin-top: 4px; }
|
|
203
|
+
.repo-link { cursor: pointer; }
|
|
204
|
+
.repo-link:hover td { color: #58a6ff; }
|
|
205
|
+
.repo-detail { position: fixed; inset: 0; background: rgba(0,0,0,.6); display: none; align-items: center; justify-content: center; z-index: 50; }
|
|
206
|
+
.repo-detail.open { display: flex; }
|
|
207
|
+
.repo-detail-box { background: #161b22; border: 1px solid #30363d; border-radius: 10px; padding: 24px; width: 560px; max-width: 92vw; max-height: 86vh; overflow-y: auto; }
|
|
208
|
+
.repo-detail-box h2 { font-size: 14px; color: #f0f6fc; margin-bottom: 14px; display: flex; justify-content: space-between; align-items: center; }
|
|
209
|
+
.repo-close { cursor: pointer; color: #8b949e; font-size: 20px; line-height: 1; border: none; background: none; padding: 0 4px; }
|
|
210
|
+
.repo-close:hover { color: #f0f6fc; }
|
|
211
|
+
.repo-path { font-size: 11px; color: #484f58; word-break: break-all; margin: -8px 0 12px; }
|
|
198
212
|
</style>
|
|
199
213
|
</head>
|
|
200
214
|
<body>
|
|
201
215
|
|
|
202
216
|
<div class="offline-banner" id="offline-banner">Dashboard data unavailable — waiting for a pi session to write snapshot...</div>
|
|
203
217
|
|
|
204
|
-
<h1><span>mega-compact</span><span class="tier">${tierName}</span></h1>
|
|
218
|
+
<h1><span>mega-compact</span><span class="tier">${tierName}</span><span class="model-pill" id="hdr-model">—</span></h1>
|
|
205
219
|
|
|
206
220
|
<nav class="tabs">
|
|
207
221
|
<button class="tab active" data-tab="current">Current repo</button>
|
|
@@ -270,6 +284,17 @@ function dashboardHtml(tierName) {
|
|
|
270
284
|
<span class="label">Anchor</span><span class="value" id="cf-anchor">—</span>
|
|
271
285
|
</div>
|
|
272
286
|
</div>
|
|
287
|
+
<div class="card cost">
|
|
288
|
+
<h2>💰 Model & Cost Savings</h2>
|
|
289
|
+
<div class="cost-usd" id="cost-usd">≈ $0.00 saved</div>
|
|
290
|
+
<div class="cost-sub" id="cost-windows">0 context-windows extended</div>
|
|
291
|
+
<div class="stat-grid" style="margin-top:12px">
|
|
292
|
+
<span class="label" title="The model pi is currently using — its pricing drives the cost figure.">Model</span><span class="value" id="md-name">—</span>
|
|
293
|
+
<span class="label" title="The provider serving the model.">Provider</span><span class="value" id="md-provider">—</span>
|
|
294
|
+
<span class="label" title="USD per input token, from the model's pricing.">Input Rate</span><span class="value" id="md-input">—</span>
|
|
295
|
+
<span class="label" title="USD per output token, from the model's pricing.">Output Rate</span><span class="value" id="md-output">—</span>
|
|
296
|
+
</div>
|
|
297
|
+
</div>
|
|
273
298
|
<div class="card">
|
|
274
299
|
<h2>Crew / Agents</h2>
|
|
275
300
|
<div class="stat-grid">
|
|
@@ -297,9 +322,40 @@ function dashboardHtml(tierName) {
|
|
|
297
322
|
<div class="events-wrap" id="events"><div class="empty">connecting…</div></div>
|
|
298
323
|
</div>
|
|
299
324
|
|
|
325
|
+
<h2 style="margin-top:24px;font-size:13px;color:#8b949e;text-transform:uppercase;letter-spacing:.5px">All Repositories</h2>
|
|
326
|
+
<table class="repos">
|
|
327
|
+
<thead>
|
|
328
|
+
<tr>
|
|
329
|
+
<th>Repo</th><th>Model</th>
|
|
330
|
+
<th style="text-align:right">Checkpoints</th>
|
|
331
|
+
<th style="text-align:right">Tokens Saved</th>
|
|
332
|
+
<th style="text-align:right">Retained</th>
|
|
333
|
+
<th style="text-align:right">Last Compacted</th>
|
|
334
|
+
</tr>
|
|
335
|
+
</thead>
|
|
336
|
+
<tbody id="cur-rows"><tr><td colspan="6" class="repo-none">loading…</td></tr></tbody>
|
|
337
|
+
</table>
|
|
338
|
+
<div class="updated" id="cur-updated"></div>
|
|
339
|
+
|
|
300
340
|
<div class="updated" id="updated"></div>
|
|
301
341
|
</div><!-- /panel-current -->
|
|
302
342
|
|
|
343
|
+
<!-- Per-repo detail modal -->
|
|
344
|
+
<div class="repo-detail" id="repo-detail">
|
|
345
|
+
<div class="repo-detail-box">
|
|
346
|
+
<h2><span id="rd-name">Repo</span><button class="repo-close" id="rd-close" title="Close">×</button></h2>
|
|
347
|
+
<div class="repo-path" id="rd-path"></div>
|
|
348
|
+
<div class="stat-grid">
|
|
349
|
+
<span class="label">Model</span><span class="value" id="rd-model">—</span>
|
|
350
|
+
<span class="label">Checkpoints</span><span class="value" id="rd-cp">0</span>
|
|
351
|
+
<span class="label">Tokens Saved</span><span class="value" id="rd-saved">0</span>
|
|
352
|
+
<span class="label">Compressed-Original</span><span class="value" id="rd-bytes">0 B</span>
|
|
353
|
+
<span class="label">Last Compacted</span><span class="value" id="rd-when">—</span>
|
|
354
|
+
<span class="label">Provider</span><span class="value" id="rd-provider">—</span>
|
|
355
|
+
</div>
|
|
356
|
+
</div>
|
|
357
|
+
</div>
|
|
358
|
+
|
|
303
359
|
<!-- All repos (machine-wide registry from index.sqlite) -->
|
|
304
360
|
<div class="tab-panel" id="panel-all">
|
|
305
361
|
<table class="repos">
|
|
@@ -406,6 +462,24 @@ function dashboardHtml(tierName) {
|
|
|
406
462
|
document.getElementById('cf-auto').textContent = d.config.auto ? 'enabled' : 'disabled';
|
|
407
463
|
document.getElementById('cf-anchor').textContent = d.config.anchorUserMessages;
|
|
408
464
|
|
|
465
|
+
// --- Active model + cost savings (same calc as /mega-status) ---------------
|
|
466
|
+
var model = d.model;
|
|
467
|
+
document.getElementById('hdr-model').textContent = model && model.name ? model.name : '—';
|
|
468
|
+
document.getElementById('md-name').textContent = model && model.name ? model.name : '—';
|
|
469
|
+
document.getElementById('md-provider').textContent = model && model.providerName ? model.providerName : (model && model.provider ? model.provider : '—');
|
|
470
|
+
document.getElementById('md-input').textContent = model && model.inputRate ? '$' + (model.inputRate).toFixed(6) : '—';
|
|
471
|
+
document.getElementById('md-output').textContent = model && model.outputRate ? '$' + (model.outputRate).toFixed(6) : '—';
|
|
472
|
+
if (model && model.inputRate && repo.tokensSaved > 0) {
|
|
473
|
+
var usd = (repo.tokensSaved * model.inputRate);
|
|
474
|
+
var win = d.context.contextWindow || 0;
|
|
475
|
+
var windows = win > 0 ? (repo.tokensSaved / win).toFixed(1) : '0';
|
|
476
|
+
document.getElementById('cost-usd').textContent = '≈ $' + usd.toFixed(4) + ' saved';
|
|
477
|
+
document.getElementById('cost-windows').textContent = windows + ' context-windows extended';
|
|
478
|
+
} else {
|
|
479
|
+
document.getElementById('cost-usd').textContent = '≈ $0.00 saved';
|
|
480
|
+
document.getElementById('cost-windows').textContent = '0 context-windows extended';
|
|
481
|
+
}
|
|
482
|
+
|
|
409
483
|
document.getElementById('updated').textContent = 'Updated ' + new Date(d.updatedAt).toLocaleTimeString();
|
|
410
484
|
}
|
|
411
485
|
|
|
@@ -469,16 +543,16 @@ function dashboardHtml(tierName) {
|
|
|
469
543
|
document.getElementById('sm-saved').textContent = (s.totalTokensSaved || 0).toLocaleString();
|
|
470
544
|
document.getElementById('sm-bytes').textContent = fmtBytesTop(s.totalCompressedOriginalBytes);
|
|
471
545
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
546
|
+
// Shared clickable-row renderer for both the in-current table and the
|
|
547
|
+
// All-repos tab — each row opens the per-repo detail modal.
|
|
548
|
+
function rowsHtml() {
|
|
549
|
+
if (!repos.length) return '<tr><td colspan="6" class="repo-none">No repositories registered yet.</td></tr>';
|
|
550
|
+
return repos.map(function(r) {
|
|
477
551
|
var model = r.modelName
|
|
478
552
|
? '<span class="repo-model">' + sanitize(r.modelName) + '</span>'
|
|
479
553
|
: '<span class="repo-none">—</span>';
|
|
480
554
|
var when = r.lastCompactedAt ? new Date(r.lastCompactedAt).toLocaleString() : '—';
|
|
481
|
-
return '<tr>' +
|
|
555
|
+
return '<tr class="repo-link" data-repo="' + sanitize(r.repoRoot) + '">' +
|
|
482
556
|
'<td title="' + sanitize(r.repoRoot) + '">' + sanitize(r.displayName || r.repoRoot) + '</td>' +
|
|
483
557
|
'<td>' + model + '</td>' +
|
|
484
558
|
'<td class="num">' + (r.checkpointCount || 0).toLocaleString() + '</td>' +
|
|
@@ -488,12 +562,48 @@ function dashboardHtml(tierName) {
|
|
|
488
562
|
'</tr>';
|
|
489
563
|
}).join('');
|
|
490
564
|
}
|
|
565
|
+
document.getElementById('cur-rows').innerHTML = rowsHtml();
|
|
566
|
+
document.getElementById('all-rows').innerHTML = rowsHtml();
|
|
567
|
+
bindRepoRows();
|
|
568
|
+
|
|
491
569
|
var stamp = d.updatedAt ? 'Updated ' + new Date(d.updatedAt).toLocaleTimeString() : '';
|
|
570
|
+
document.getElementById('cur-updated').textContent = stamp;
|
|
492
571
|
document.getElementById('all-updated').textContent = stamp;
|
|
493
572
|
document.getElementById('sm-updated').textContent = stamp;
|
|
494
573
|
}
|
|
574
|
+
|
|
575
|
+
// Per-repo detail modal ---------------------------------------------------
|
|
576
|
+
var detailEl = document.getElementById('repo-detail');
|
|
577
|
+
var indexCache = { repos: [] };
|
|
578
|
+
function openRepoDetail(root) {
|
|
579
|
+
var r = null;
|
|
580
|
+
for (var i = 0; i < indexCache.repos.length; i++) {
|
|
581
|
+
if (indexCache.repos[i].repoRoot === root) { r = indexCache.repos[i]; break; }
|
|
582
|
+
}
|
|
583
|
+
if (!r) return;
|
|
584
|
+
document.getElementById('rd-name').textContent = r.displayName || r.repoRoot;
|
|
585
|
+
document.getElementById('rd-path').textContent = r.repoRoot;
|
|
586
|
+
document.getElementById('rd-model').textContent = r.modelName || '—';
|
|
587
|
+
document.getElementById('rd-provider').textContent = r.providerName || (r.provider || '—');
|
|
588
|
+
document.getElementById('rd-cp').textContent = (r.checkpointCount || 0).toLocaleString();
|
|
589
|
+
document.getElementById('rd-saved').textContent = (r.tokensSaved || 0).toLocaleString();
|
|
590
|
+
document.getElementById('rd-bytes').textContent = fmtBytesTop(r.compressedOriginalBytes);
|
|
591
|
+
document.getElementById('rd-when').textContent = r.lastCompactedAt ? new Date(r.lastCompactedAt).toLocaleString() : '—';
|
|
592
|
+
detailEl.classList.add('open');
|
|
593
|
+
}
|
|
594
|
+
document.getElementById('rd-close').addEventListener('click', function() { detailEl.classList.remove('open'); });
|
|
595
|
+
detailEl.addEventListener('click', function(e) { if (e.target === detailEl) detailEl.classList.remove('open'); });
|
|
596
|
+
function bindRepoRows() {
|
|
597
|
+
var rows = document.querySelectorAll('.repo-link');
|
|
598
|
+
for (var i = 0; i < rows.length; i++) {
|
|
599
|
+
rows[i].addEventListener('click', function() { openRepoDetail(this.getAttribute('data-repo')); });
|
|
600
|
+
}
|
|
601
|
+
}
|
|
495
602
|
function pollIndex() {
|
|
496
|
-
fetch('/api/index').then(function(r) { return r.json(); }).then(
|
|
603
|
+
fetch('/api/index').then(function(r) { return r.json(); }).then(function(d) {
|
|
604
|
+
indexCache = d && d.repos ? d : indexCache;
|
|
605
|
+
renderIndex(d);
|
|
606
|
+
}).catch(function() {});
|
|
497
607
|
}
|
|
498
608
|
pollIndex();
|
|
499
609
|
setInterval(pollIndex, 5000);
|
|
@@ -148,6 +148,19 @@ interface Snapshot {
|
|
|
148
148
|
dedupCollapsed: number;
|
|
149
149
|
storageDedupRate: number;
|
|
150
150
|
};
|
|
151
|
+
integrity: {
|
|
152
|
+
regionsRetained: number;
|
|
153
|
+
compressedOriginalBytes: number;
|
|
154
|
+
duplicatesCollapsed: number;
|
|
155
|
+
bytesPermanentlyDeleted: number;
|
|
156
|
+
};
|
|
157
|
+
model?: {
|
|
158
|
+
name: string;
|
|
159
|
+
provider: string;
|
|
160
|
+
providerName: string;
|
|
161
|
+
inputRate: number;
|
|
162
|
+
outputRate: number;
|
|
163
|
+
};
|
|
151
164
|
}
|
|
152
165
|
|
|
153
166
|
// ---------------------------------------------------------------------------
|
|
@@ -171,6 +184,7 @@ function readSnapshot(snapshotPath: string) {
|
|
|
171
184
|
crew: { activeAgents: 0, currentTurn: 0 },
|
|
172
185
|
repo: { checkpointCount: 0, totalTokenEstimate: 0, originalTokens: 0, tokensSaved: 0, sessionCount: 0, dedupAttempts: 0, dedupCollapsed: 0, storageDedupRate: 0 },
|
|
173
186
|
integrity: { regionsRetained: 0, compressedOriginalBytes: 0, duplicatesCollapsed: 0, bytesPermanentlyDeleted: 0 },
|
|
187
|
+
model: undefined,
|
|
174
188
|
} as Snapshot;
|
|
175
189
|
}
|
|
176
190
|
}
|
|
@@ -268,13 +282,26 @@ function dashboardHtml(tierName: string): string {
|
|
|
268
282
|
.repo-model { color: #a371f7; }
|
|
269
283
|
.repo-none { color: #484f58; font-style: italic; }
|
|
270
284
|
.updated { font-size: 11px; color: #484f58; margin-top: 16px; text-align: right; }
|
|
285
|
+
.model-pill { background: #6e40c9; color: #fff; font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 10px; text-transform: uppercase; letter-spacing: .5px; }
|
|
286
|
+
.card.cost h2 { color: #a371f7; }
|
|
287
|
+
.cost-usd { font-size: 22px; font-weight: 700; color: #3fb950; }
|
|
288
|
+
.cost-sub { font-size: 12px; color: #8b949e; margin-top: 4px; }
|
|
289
|
+
.repo-link { cursor: pointer; }
|
|
290
|
+
.repo-link:hover td { color: #58a6ff; }
|
|
291
|
+
.repo-detail { position: fixed; inset: 0; background: rgba(0,0,0,.6); display: none; align-items: center; justify-content: center; z-index: 50; }
|
|
292
|
+
.repo-detail.open { display: flex; }
|
|
293
|
+
.repo-detail-box { background: #161b22; border: 1px solid #30363d; border-radius: 10px; padding: 24px; width: 560px; max-width: 92vw; max-height: 86vh; overflow-y: auto; }
|
|
294
|
+
.repo-detail-box h2 { font-size: 14px; color: #f0f6fc; margin-bottom: 14px; display: flex; justify-content: space-between; align-items: center; }
|
|
295
|
+
.repo-close { cursor: pointer; color: #8b949e; font-size: 20px; line-height: 1; border: none; background: none; padding: 0 4px; }
|
|
296
|
+
.repo-close:hover { color: #f0f6fc; }
|
|
297
|
+
.repo-path { font-size: 11px; color: #484f58; word-break: break-all; margin: -8px 0 12px; }
|
|
271
298
|
</style>
|
|
272
299
|
</head>
|
|
273
300
|
<body>
|
|
274
301
|
|
|
275
302
|
<div class="offline-banner" id="offline-banner">Dashboard data unavailable — waiting for a pi session to write snapshot...</div>
|
|
276
303
|
|
|
277
|
-
<h1><span>mega-compact</span><span class="tier">${tierName}</span></h1>
|
|
304
|
+
<h1><span>mega-compact</span><span class="tier">${tierName}</span><span class="model-pill" id="hdr-model">—</span></h1>
|
|
278
305
|
|
|
279
306
|
<nav class="tabs">
|
|
280
307
|
<button class="tab active" data-tab="current">Current repo</button>
|
|
@@ -343,6 +370,17 @@ function dashboardHtml(tierName: string): string {
|
|
|
343
370
|
<span class="label">Anchor</span><span class="value" id="cf-anchor">—</span>
|
|
344
371
|
</div>
|
|
345
372
|
</div>
|
|
373
|
+
<div class="card cost">
|
|
374
|
+
<h2>💰 Model & Cost Savings</h2>
|
|
375
|
+
<div class="cost-usd" id="cost-usd">≈ $0.00 saved</div>
|
|
376
|
+
<div class="cost-sub" id="cost-windows">0 context-windows extended</div>
|
|
377
|
+
<div class="stat-grid" style="margin-top:12px">
|
|
378
|
+
<span class="label" title="The model pi is currently using — its pricing drives the cost figure.">Model</span><span class="value" id="md-name">—</span>
|
|
379
|
+
<span class="label" title="The provider serving the model.">Provider</span><span class="value" id="md-provider">—</span>
|
|
380
|
+
<span class="label" title="USD per input token, from the model's pricing.">Input Rate</span><span class="value" id="md-input">—</span>
|
|
381
|
+
<span class="label" title="USD per output token, from the model's pricing.">Output Rate</span><span class="value" id="md-output">—</span>
|
|
382
|
+
</div>
|
|
383
|
+
</div>
|
|
346
384
|
<div class="card">
|
|
347
385
|
<h2>Crew / Agents</h2>
|
|
348
386
|
<div class="stat-grid">
|
|
@@ -370,9 +408,40 @@ function dashboardHtml(tierName: string): string {
|
|
|
370
408
|
<div class="events-wrap" id="events"><div class="empty">connecting…</div></div>
|
|
371
409
|
</div>
|
|
372
410
|
|
|
411
|
+
<h2 style="margin-top:24px;font-size:13px;color:#8b949e;text-transform:uppercase;letter-spacing:.5px">All Repositories</h2>
|
|
412
|
+
<table class="repos">
|
|
413
|
+
<thead>
|
|
414
|
+
<tr>
|
|
415
|
+
<th>Repo</th><th>Model</th>
|
|
416
|
+
<th style="text-align:right">Checkpoints</th>
|
|
417
|
+
<th style="text-align:right">Tokens Saved</th>
|
|
418
|
+
<th style="text-align:right">Retained</th>
|
|
419
|
+
<th style="text-align:right">Last Compacted</th>
|
|
420
|
+
</tr>
|
|
421
|
+
</thead>
|
|
422
|
+
<tbody id="cur-rows"><tr><td colspan="6" class="repo-none">loading…</td></tr></tbody>
|
|
423
|
+
</table>
|
|
424
|
+
<div class="updated" id="cur-updated"></div>
|
|
425
|
+
|
|
373
426
|
<div class="updated" id="updated"></div>
|
|
374
427
|
</div><!-- /panel-current -->
|
|
375
428
|
|
|
429
|
+
<!-- Per-repo detail modal -->
|
|
430
|
+
<div class="repo-detail" id="repo-detail">
|
|
431
|
+
<div class="repo-detail-box">
|
|
432
|
+
<h2><span id="rd-name">Repo</span><button class="repo-close" id="rd-close" title="Close">×</button></h2>
|
|
433
|
+
<div class="repo-path" id="rd-path"></div>
|
|
434
|
+
<div class="stat-grid">
|
|
435
|
+
<span class="label">Model</span><span class="value" id="rd-model">—</span>
|
|
436
|
+
<span class="label">Checkpoints</span><span class="value" id="rd-cp">0</span>
|
|
437
|
+
<span class="label">Tokens Saved</span><span class="value" id="rd-saved">0</span>
|
|
438
|
+
<span class="label">Compressed-Original</span><span class="value" id="rd-bytes">0 B</span>
|
|
439
|
+
<span class="label">Last Compacted</span><span class="value" id="rd-when">—</span>
|
|
440
|
+
<span class="label">Provider</span><span class="value" id="rd-provider">—</span>
|
|
441
|
+
</div>
|
|
442
|
+
</div>
|
|
443
|
+
</div>
|
|
444
|
+
|
|
376
445
|
<!-- All repos (machine-wide registry from index.sqlite) -->
|
|
377
446
|
<div class="tab-panel" id="panel-all">
|
|
378
447
|
<table class="repos">
|
|
@@ -479,6 +548,24 @@ function dashboardHtml(tierName: string): string {
|
|
|
479
548
|
document.getElementById('cf-auto').textContent = d.config.auto ? 'enabled' : 'disabled';
|
|
480
549
|
document.getElementById('cf-anchor').textContent = d.config.anchorUserMessages;
|
|
481
550
|
|
|
551
|
+
// --- Active model + cost savings (same calc as /mega-status) ---------------
|
|
552
|
+
var model = d.model;
|
|
553
|
+
document.getElementById('hdr-model').textContent = model && model.name ? model.name : '—';
|
|
554
|
+
document.getElementById('md-name').textContent = model && model.name ? model.name : '—';
|
|
555
|
+
document.getElementById('md-provider').textContent = model && model.providerName ? model.providerName : (model && model.provider ? model.provider : '—');
|
|
556
|
+
document.getElementById('md-input').textContent = model && model.inputRate ? '$' + (model.inputRate).toFixed(6) : '—';
|
|
557
|
+
document.getElementById('md-output').textContent = model && model.outputRate ? '$' + (model.outputRate).toFixed(6) : '—';
|
|
558
|
+
if (model && model.inputRate && repo.tokensSaved > 0) {
|
|
559
|
+
var usd = (repo.tokensSaved * model.inputRate);
|
|
560
|
+
var win = d.context.contextWindow || 0;
|
|
561
|
+
var windows = win > 0 ? (repo.tokensSaved / win).toFixed(1) : '0';
|
|
562
|
+
document.getElementById('cost-usd').textContent = '≈ $' + usd.toFixed(4) + ' saved';
|
|
563
|
+
document.getElementById('cost-windows').textContent = windows + ' context-windows extended';
|
|
564
|
+
} else {
|
|
565
|
+
document.getElementById('cost-usd').textContent = '≈ $0.00 saved';
|
|
566
|
+
document.getElementById('cost-windows').textContent = '0 context-windows extended';
|
|
567
|
+
}
|
|
568
|
+
|
|
482
569
|
document.getElementById('updated').textContent = 'Updated ' + new Date(d.updatedAt).toLocaleTimeString();
|
|
483
570
|
}
|
|
484
571
|
|
|
@@ -542,16 +629,16 @@ function dashboardHtml(tierName: string): string {
|
|
|
542
629
|
document.getElementById('sm-saved').textContent = (s.totalTokensSaved || 0).toLocaleString();
|
|
543
630
|
document.getElementById('sm-bytes').textContent = fmtBytesTop(s.totalCompressedOriginalBytes);
|
|
544
631
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
632
|
+
// Shared clickable-row renderer for both the in-current table and the
|
|
633
|
+
// All-repos tab — each row opens the per-repo detail modal.
|
|
634
|
+
function rowsHtml() {
|
|
635
|
+
if (!repos.length) return '<tr><td colspan="6" class="repo-none">No repositories registered yet.</td></tr>';
|
|
636
|
+
return repos.map(function(r) {
|
|
550
637
|
var model = r.modelName
|
|
551
638
|
? '<span class="repo-model">' + sanitize(r.modelName) + '</span>'
|
|
552
639
|
: '<span class="repo-none">—</span>';
|
|
553
640
|
var when = r.lastCompactedAt ? new Date(r.lastCompactedAt).toLocaleString() : '—';
|
|
554
|
-
return '<tr>' +
|
|
641
|
+
return '<tr class="repo-link" data-repo="' + sanitize(r.repoRoot) + '">' +
|
|
555
642
|
'<td title="' + sanitize(r.repoRoot) + '">' + sanitize(r.displayName || r.repoRoot) + '</td>' +
|
|
556
643
|
'<td>' + model + '</td>' +
|
|
557
644
|
'<td class="num">' + (r.checkpointCount || 0).toLocaleString() + '</td>' +
|
|
@@ -561,12 +648,48 @@ function dashboardHtml(tierName: string): string {
|
|
|
561
648
|
'</tr>';
|
|
562
649
|
}).join('');
|
|
563
650
|
}
|
|
651
|
+
document.getElementById('cur-rows').innerHTML = rowsHtml();
|
|
652
|
+
document.getElementById('all-rows').innerHTML = rowsHtml();
|
|
653
|
+
bindRepoRows();
|
|
654
|
+
|
|
564
655
|
var stamp = d.updatedAt ? 'Updated ' + new Date(d.updatedAt).toLocaleTimeString() : '';
|
|
656
|
+
document.getElementById('cur-updated').textContent = stamp;
|
|
565
657
|
document.getElementById('all-updated').textContent = stamp;
|
|
566
658
|
document.getElementById('sm-updated').textContent = stamp;
|
|
567
659
|
}
|
|
660
|
+
|
|
661
|
+
// Per-repo detail modal ---------------------------------------------------
|
|
662
|
+
var detailEl = document.getElementById('repo-detail');
|
|
663
|
+
var indexCache = { repos: [] };
|
|
664
|
+
function openRepoDetail(root) {
|
|
665
|
+
var r = null;
|
|
666
|
+
for (var i = 0; i < indexCache.repos.length; i++) {
|
|
667
|
+
if (indexCache.repos[i].repoRoot === root) { r = indexCache.repos[i]; break; }
|
|
668
|
+
}
|
|
669
|
+
if (!r) return;
|
|
670
|
+
document.getElementById('rd-name').textContent = r.displayName || r.repoRoot;
|
|
671
|
+
document.getElementById('rd-path').textContent = r.repoRoot;
|
|
672
|
+
document.getElementById('rd-model').textContent = r.modelName || '—';
|
|
673
|
+
document.getElementById('rd-provider').textContent = r.providerName || (r.provider || '—');
|
|
674
|
+
document.getElementById('rd-cp').textContent = (r.checkpointCount || 0).toLocaleString();
|
|
675
|
+
document.getElementById('rd-saved').textContent = (r.tokensSaved || 0).toLocaleString();
|
|
676
|
+
document.getElementById('rd-bytes').textContent = fmtBytesTop(r.compressedOriginalBytes);
|
|
677
|
+
document.getElementById('rd-when').textContent = r.lastCompactedAt ? new Date(r.lastCompactedAt).toLocaleString() : '—';
|
|
678
|
+
detailEl.classList.add('open');
|
|
679
|
+
}
|
|
680
|
+
document.getElementById('rd-close').addEventListener('click', function() { detailEl.classList.remove('open'); });
|
|
681
|
+
detailEl.addEventListener('click', function(e) { if (e.target === detailEl) detailEl.classList.remove('open'); });
|
|
682
|
+
function bindRepoRows() {
|
|
683
|
+
var rows = document.querySelectorAll('.repo-link');
|
|
684
|
+
for (var i = 0; i < rows.length; i++) {
|
|
685
|
+
rows[i].addEventListener('click', function() { openRepoDetail(this.getAttribute('data-repo')); });
|
|
686
|
+
}
|
|
687
|
+
}
|
|
568
688
|
function pollIndex() {
|
|
569
|
-
fetch('/api/index').then(function(r) { return r.json(); }).then(
|
|
689
|
+
fetch('/api/index').then(function(r) { return r.json(); }).then(function(d) {
|
|
690
|
+
indexCache = d && d.repos ? d : indexCache;
|
|
691
|
+
renderIndex(d);
|
|
692
|
+
}).catch(function() {});
|
|
570
693
|
}
|
|
571
694
|
pollIndex();
|
|
572
695
|
setInterval(pollIndex, 5000);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-mega-compact",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.19",
|
|
4
4
|
"description": "Layered, local, vector-backed context compressor for pi — supersede/collapse/cluster compaction with deduped inline recall.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "BSD-2-Clause",
|