trimprompt 1.0.26 → 1.0.28

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/index.html CHANGED
@@ -287,6 +287,174 @@
287
287
  background: var(--indigo);
288
288
  }
289
289
 
290
+ .feature-tag {
291
+ display: inline-block;
292
+ padding: 2px 8px;
293
+ border-radius: 4px;
294
+ font-size: 0.7rem;
295
+ font-weight: 600;
296
+ margin-right: 3px;
297
+ white-space: nowrap;
298
+ }
299
+
300
+ .csa-row {
301
+ display: flex;
302
+ align-items: center;
303
+ gap: 16px;
304
+ padding: 16px 0;
305
+ border-bottom: 1px solid var(--border);
306
+ }
307
+
308
+ .csa-row:last-child { border-bottom: none; }
309
+
310
+ .csa-toggle {
311
+ position: relative;
312
+ width: 44px;
313
+ height: 24px;
314
+ flex-shrink: 0;
315
+ }
316
+
317
+ .csa-toggle input { opacity: 0; width: 0; height: 0; }
318
+
319
+ .csa-toggle .slider {
320
+ position: absolute;
321
+ inset: 0;
322
+ background: rgba(255,255,255,0.12);
323
+ border-radius: 12px;
324
+ cursor: pointer;
325
+ transition: background 0.2s;
326
+ }
327
+
328
+ .csa-toggle .slider::after {
329
+ content: "";
330
+ position: absolute;
331
+ width: 18px;
332
+ height: 18px;
333
+ left: 3px;
334
+ top: 3px;
335
+ background: #fff;
336
+ border-radius: 50%;
337
+ transition: transform 0.2s;
338
+ }
339
+
340
+ .csa-toggle input:checked + .slider {
341
+ background: var(--emerald);
342
+ }
343
+
344
+ .csa-toggle input:checked + .slider::after {
345
+ transform: translateX(20px);
346
+ }
347
+
348
+ .csa-info { flex: 1; min-width: 0; }
349
+
350
+ .csa-info h4 {
351
+ font-family: 'Outfit', sans-serif;
352
+ font-weight: 700;
353
+ font-size: 0.95rem;
354
+ margin-bottom: 3px;
355
+ }
356
+
357
+ .csa-info p {
358
+ font-size: 0.78rem;
359
+ color: var(--text-muted);
360
+ margin-bottom: 6px;
361
+ }
362
+
363
+ .csa-badges {
364
+ display: flex;
365
+ gap: 5px;
366
+ flex-wrap: wrap;
367
+ }
368
+
369
+ .csa-badge {
370
+ font-size: 0.68rem;
371
+ font-weight: 500;
372
+ padding: 2px 8px;
373
+ border-radius: 4px;
374
+ background: rgba(255,255,255,0.06);
375
+ color: var(--text-muted);
376
+ border: 1px solid rgba(255,255,255,0.08);
377
+ }
378
+
379
+ .csa-stat {
380
+ text-align: right;
381
+ flex-shrink: 0;
382
+ min-width: 90px;
383
+ }
384
+
385
+ .csa-stat .csa-val {
386
+ font-family: 'Outfit', sans-serif;
387
+ font-weight: 700;
388
+ font-size: 1.1rem;
389
+ }
390
+
391
+ .csa-stat .csa-sub {
392
+ font-size: 0.7rem;
393
+ color: var(--text-muted);
394
+ }
395
+
396
+ .csa-category {
397
+ font-family: 'Outfit', sans-serif;
398
+ font-weight: 700;
399
+ font-size: 0.8rem;
400
+ text-transform: uppercase;
401
+ letter-spacing: 0.08em;
402
+ color: var(--text-muted);
403
+ padding: 18px 0 6px;
404
+ border-bottom: 1px solid var(--border);
405
+ }
406
+
407
+ .csa-category:first-child { padding-top: 4px; }
408
+
409
+ .csa-summary {
410
+ display: grid;
411
+ grid-template-columns: repeat(4, 1fr);
412
+ gap: 16px;
413
+ margin-top: 16px;
414
+ }
415
+
416
+ .csa-summary-card {
417
+ background: rgba(255,255,255,0.03);
418
+ border: 1px solid var(--border);
419
+ border-radius: 12px;
420
+ padding: 16px;
421
+ text-align: center;
422
+ }
423
+
424
+ .csa-summary-card .csa-sum-label {
425
+ font-family: 'Outfit', sans-serif;
426
+ font-size: 0.7rem;
427
+ font-weight: 700;
428
+ text-transform: uppercase;
429
+ letter-spacing: 0.06em;
430
+ color: var(--text-muted);
431
+ margin-bottom: 6px;
432
+ }
433
+
434
+ .csa-summary-card .csa-sum-val {
435
+ font-family: 'Outfit', sans-serif;
436
+ font-weight: 800;
437
+ font-size: 1.6rem;
438
+ }
439
+
440
+ .csa-status {
441
+ display: inline-block;
442
+ font-size: 0.65rem;
443
+ font-weight: 600;
444
+ padding: 2px 7px;
445
+ border-radius: 4px;
446
+ margin-left: 8px;
447
+ vertical-align: middle;
448
+ }
449
+
450
+ .csa-status.active { background: rgba(16,185,129,0.12); color: #10B981; }
451
+ .csa-status.off { background: rgba(250,199,117,0.12); color: #FAC775; }
452
+ .csa-status.soon { background: rgba(148,163,184,0.10); color: #64748B; }
453
+
454
+ .csa-row.is-soon { opacity: 0.5; }
455
+ .csa-row.is-soon .csa-toggle { pointer-events: none; }
456
+ .csa-row.is-off .csa-toggle input:not(:checked) + .slider { background: rgba(250,199,117,0.25); }
457
+
290
458
  /* Inspect Modal */
291
459
  .modal-overlay {
292
460
  position: fixed;
@@ -500,6 +668,21 @@
500
668
  </div>
501
669
  </div>
502
670
 
671
+ <!-- CSA Feature Controls -->
672
+ <div class="history-section" id="csa-section">
673
+ <div class="history-header" style="cursor:pointer;user-select:none;" onclick="toggleCsa()">
674
+ <h2 style="display:flex;align-items:center;gap:10px;">
675
+ <span id="csa-chevron" style="display:inline-block;transition:transform 0.2s;transform:rotate(0deg);font-size:0.8rem;">&#9654;</span>
676
+ CSA Feature Controls
677
+ <span id="csa-count-badge" style="font-size:0.75rem;font-weight:500;color:var(--text-muted);font-family:'Inter',sans-serif;"></span>
678
+ </h2>
679
+ </div>
680
+ <div id="csa-body" style="display:none;">
681
+ <div id="csa-list"></div>
682
+ <div class="csa-summary" id="csa-summary"></div>
683
+ </div>
684
+ </div>
685
+
503
686
  <div class="history-section">
504
687
  <div class="history-header" style="display: flex; align-items: center; gap: 16px;">
505
688
  <h2 style="margin: 0;">Command Execution History</h2>
@@ -514,6 +697,7 @@
514
697
  <tr>
515
698
  <th>Timestamp</th>
516
699
  <th>Command</th>
700
+ <th>Features</th>
517
701
  <th>Raw Tokens</th>
518
702
  <th>Compressed</th>
519
703
  <th>Savings</th>
@@ -523,7 +707,7 @@
523
707
  </thead>
524
708
  <tbody id="history-table-body">
525
709
  <tr>
526
- <td colspan="7" style="text-align: center; color: var(--text-muted);">Loading logs...</td>
710
+ <td colspan="8" style="text-align: center; color: var(--text-muted);">Loading logs...</td>
527
711
  </tr>
528
712
  </tbody>
529
713
  </table>
@@ -557,6 +741,230 @@
557
741
  let savingsChart = null;
558
742
  let currentFilter = 'ai';
559
743
 
744
+ const FEATURE_META = {
745
+ filter: { label: 'Filter', color: '#6366F1', bg: 'rgba(99,102,241,0.12)' },
746
+ redact: { label: 'Redact', color: '#EF4444', bg: 'rgba(239,68,68,0.12)' },
747
+ lock: { label: 'Lock File', color: '#FAC775', bg: 'rgba(250,199,117,0.12)' },
748
+ binary: { label: 'Binary', color: '#F09595', bg: 'rgba(240,149,149,0.12)' },
749
+ skeleton: { label: 'Skeleton', color: '#AFA9EC', bg: 'rgba(175,169,236,0.12)' },
750
+ whitespace: { label: 'Whitespace', color: '#94A3B8', bg: 'rgba(148,163,184,0.12)' },
751
+ cache: { label: 'Cache Hit', color: '#10B981', bg: 'rgba(16,185,129,0.12)' },
752
+ truncate: { label: 'Truncate', color: '#3B82F6', bg: 'rgba(59,130,246,0.12)' },
753
+ conv_compress: { label: 'Proxy', color: '#7F77DD', bg: 'rgba(127,119,221,0.15)' },
754
+ resp_optimize: { label: 'Proxy', color: '#7F77DD', bg: 'rgba(127,119,221,0.15)' },
755
+ };
756
+
757
+ function featureTagHtml(features) {
758
+ if (!features || features.length === 0) return '<span style="color:#475569;font-size:11px;">—</span>';
759
+ return features.map(f => {
760
+ const m = FEATURE_META[f] || { label: f, color: '#94A3B8', bg: 'rgba(148,163,184,0.12)' };
761
+ return `<span class="feature-tag" style="color:${m.color};background:${m.bg};">${m.label}</span>`;
762
+ }).join('');
763
+ }
764
+
765
+ // status: 'active' = working, 'off' = in code but off by default, 'soon' = not implemented yet
766
+ const CSA_FEATURES = [
767
+ { category: 'C — Compression (CLI Output)', features: [
768
+ { key: 'filter', title: '27 Command filters', desc: 'git, cat, ls, find, grep, docker, kubectl, pytest, jest, cargo, go, pip, npm, ruff', badges: ['Claude','Cursor','Copilot','Gemini','Antigravity'], statSub: 'on matched commands', status: 'active' },
769
+ { key: 'ansi_strip', title: 'ANSI strip', desc: 'Remove color codes, cursor sequences from all output', badges: ['Claude','Cursor','Copilot','Gemini','Antigravity'], statSub: 'on colored output', status: 'active' },
770
+ { key: 'whitespace', title: 'Whitespace collapse', desc: 'Trailing spaces + 3+ blank lines → 1. Lossless', badges: ['Claude','Cursor','Copilot','Gemini','Antigravity'], statSub: 'on verbose output', status: 'active' },
771
+ { key: 'lock', title: 'Lock file detection', desc: 'package-lock.json, yarn.lock, Cargo.lock, go.sum → summary line', badges: ['Claude','Cursor','Copilot','Gemini','Antigravity'], statSub: 'on lock files', status: 'active' },
772
+ { key: 'binary', title: 'Binary/minified detection', desc: '.png, .min.js, .wasm, .pdf, 40+ extensions → placeholder', badges: ['Claude','Cursor','Copilot','Gemini','Antigravity'], statSub: 'on binaries', status: 'active' },
773
+ { key: 'json_crusher', title: 'SmartCrusher (JSON arrays → tables)', desc: 'Arrays of objects compressed to tabular format. Removes resolved/integrity fields', badges: ['Claude','Cursor','Copilot','Gemini','Antigravity'], statSub: 'on JSON arrays', status: 'active' },
774
+ { key: 'skeleton', title: 'Code skeleton (imports + signatures only)', desc: 'Files over 100 lines → show structure only, collapse bodies', badges: ['Claude','Cursor','Copilot','Gemini','Antigravity'], statSub: 'on large files', status: 'active' },
775
+ { key: 'ccr', title: 'CCR — Reversible compression', desc: 'Store original in cache, send compressed. Agent can retrieve full via trim retrieve', badges: ['Claude','Cursor','Copilot','Gemini','Antigravity'], statSub: 'deeper compression', status: 'off' },
776
+ ]},
777
+ { category: 'S — Security', features: [
778
+ { key: 'redact', title: 'Secret redaction (20 patterns)', desc: 'AWS keys, API tokens, JWTs, DB strings auto-blocked', badges: ['Claude','Cursor','Copilot','Gemini','Antigravity'], statKey: 'secrets', statSub: 'secrets blocked', status: 'active' },
779
+ ]},
780
+ // --- P — Proxy section hidden for now (interceptor not functional yet). Re-enable by uncommenting. ---
781
+ // { category: 'P — Proxy (Universal AI API Compression)', features: [
782
+ // { key: 'conv_compress', title: 'Conversation history compression', desc: 'Score old messages by importance, drop low-value ones. Via trim proxy', badges: ['Claude Code CLI','Codex CLI','Aider','Copilot CLI','SDK / curl'], statSub: 'on conversation', status: 'active' },
783
+ // { key: 'resp_optimize', title: 'Response length optimization', desc: 'Set optimal max_tokens per request based on task complexity. Via trim proxy', badges: ['Claude Code CLI','Codex CLI','Aider','Copilot CLI','SDK / curl'], statSub: 'on output', status: 'active' },
784
+ // ], hasProxyToggle: true },
785
+ ];
786
+
787
+ let proxyRunning = false;
788
+ // Cache last-rendered proxy HTML so the periodic full rebuild of the CSA list
789
+ // can repaint these async-filled areas instantly instead of flashing empty.
790
+ let lastProxyToggleHtml = '';
791
+ let lastProxySavingsHtml = '';
792
+
793
+ async function updateProxyToggle() {
794
+ const area = document.getElementById('proxy-toggle-area');
795
+ if (!area) return;
796
+ try {
797
+ const resp = await fetch('/api/proxy/status');
798
+ const status = await resp.json();
799
+ proxyRunning = status.running;
800
+ const color = proxyRunning ? 'var(--emerald)' : '#64748B';
801
+ const label = proxyRunning ? `Running on port ${status.port}` : 'Stopped';
802
+ const html = `
803
+ <span style="display:inline-flex;align-items:center;gap:8px;font-family:'Inter',sans-serif;font-size:12px;font-weight:500;text-transform:none;letter-spacing:0;">
804
+ <span style="color:${color};">${label}</span>
805
+ <label class="csa-toggle" style="transform:scale(0.85);">
806
+ <input type="checkbox" ${proxyRunning ? 'checked' : ''} onchange="toggleProxy(this.checked)">
807
+ <span class="slider"></span>
808
+ </label>
809
+ </span>`;
810
+ // Only touch the DOM when the markup actually changed, to avoid flicker.
811
+ if (html !== lastProxyToggleHtml) {
812
+ lastProxyToggleHtml = html;
813
+ area.innerHTML = html;
814
+ }
815
+ } catch { }
816
+ }
817
+
818
+ async function updateProxySavings() {
819
+ const card = document.getElementById('proxy-savings-card');
820
+ if (!card) return;
821
+ try {
822
+ const model = document.getElementById('model-select').value;
823
+ const resp = await fetch('/api/stats/proxy-summary?model=' + encodeURIComponent(model));
824
+ const s = await resp.json();
825
+ const cell = (label, val, color) =>
826
+ `<div style="flex:1;text-align:center;padding:10px 6px;">
827
+ <div style="font-size:18px;font-weight:700;color:${color};font-family:'Inter',sans-serif;">${val}</div>
828
+ <div style="font-size:10px;color:#64748B;text-transform:uppercase;letter-spacing:0.5px;margin-top:2px;">${label}</div>
829
+ </div>`;
830
+ const html = `
831
+ <div style="display:flex;gap:8px;margin:10px 0 14px;background:rgba(127,119,221,0.06);border:1px solid rgba(127,119,221,0.18);border-radius:10px;">
832
+ ${cell('Requests', (s.requests || 0).toLocaleString(), '#7F77DD')}
833
+ ${cell('Tokens Saved', (s.total_tokens_saved || 0).toLocaleString(), '#10B981')}
834
+ ${cell('Saved', '$' + (s.money_saved_usd || 0).toFixed(2), '#10B981')}
835
+ ${cell('Reduction', (s.savings_percentage || 0) + '%', 'var(--indigo)')}
836
+ </div>`;
837
+ // Only touch the DOM when the markup actually changed, to avoid flicker.
838
+ if (html !== lastProxySavingsHtml) {
839
+ lastProxySavingsHtml = html;
840
+ card.innerHTML = html;
841
+ }
842
+ } catch { }
843
+ }
844
+
845
+ async function toggleProxy(enable) {
846
+ try {
847
+ if (enable) {
848
+ await fetch('/api/proxy/start', { method: 'POST' });
849
+ } else {
850
+ await fetch('/api/proxy/stop', { method: 'POST' });
851
+ }
852
+ setTimeout(updateProxyToggle, 500);
853
+ } catch {}
854
+ }
855
+
856
+ let csaOpen = false;
857
+ function toggleCsa() {
858
+ csaOpen = !csaOpen;
859
+ document.getElementById('csa-body').style.display = csaOpen ? '' : 'none';
860
+ document.getElementById('csa-chevron').style.transform = csaOpen ? 'rotate(90deg)' : 'rotate(0deg)';
861
+ }
862
+
863
+ let csaToggles = {};
864
+
865
+ async function loadCsaToggles() {
866
+ try {
867
+ const resp = await fetch('/api/config/features');
868
+ const data = await resp.json();
869
+ csaToggles = data;
870
+ } catch { csaToggles = {}; }
871
+ }
872
+
873
+ async function saveCsaToggle(key, enabled) {
874
+ csaToggles[key] = enabled;
875
+ try { await fetch('/api/config/features', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(csaToggles) }); } catch {}
876
+ }
877
+
878
+ function renderCsaSection(logs) {
879
+ const pricePerM = PRICING_TABLE[document.getElementById('model-select').value] || 3.00;
880
+ const totalRaw = logs.reduce((s, l) => s + l.estimated_raw_tokens, 0);
881
+ const totalComp = logs.reduce((s, l) => s + l.estimated_compressed_tokens, 0);
882
+ const totalSaved = logs.reduce((s, l) => s + l.tokens_saved, 0);
883
+ const totalSecrets = logs.reduce((s, l) => s + (l.secrets_found || 0), 0);
884
+ const savedUsd = (totalSaved * pricePerM) / 1000000;
885
+ const reductionPct = totalRaw > 0 ? ((totalSaved / totalRaw) * 100).toFixed(1) : '0.0';
886
+
887
+ const featureCounts = {};
888
+ const featureSavings = {};
889
+ logs.forEach(l => {
890
+ (l.features || []).forEach(f => {
891
+ featureCounts[f] = (featureCounts[f] || 0) + 1;
892
+ featureSavings[f] = (featureSavings[f] || 0) + l.tokens_saved;
893
+ });
894
+ });
895
+
896
+ const list = document.getElementById('csa-list');
897
+ let html = '';
898
+
899
+ CSA_FEATURES.forEach(cat => {
900
+ html += `<div class="csa-category">${cat.category}</div>`;
901
+ cat.features.forEach(f => {
902
+ const isSoon = f.status === 'soon';
903
+ const isOff = f.status === 'off';
904
+ const defaultOn = f.status === 'active';
905
+ const checked = isSoon ? false : (csaToggles[f.key] !== undefined ? csaToggles[f.key] : defaultOn);
906
+ const count = featureCounts[f.key] || 0;
907
+ const statusLabels = { active: 'Active', off: 'Off by default', soon: 'Coming soon' };
908
+ let statVal, statColor;
909
+ if (f.statKey === 'secrets') {
910
+ statVal = totalSecrets.toLocaleString();
911
+ statColor = '#EF4444';
912
+ } else if (isSoon) {
913
+ statVal = '—';
914
+ statColor = '#64748B';
915
+ } else {
916
+ const featureSavedTokens = featureSavings[f.key] || 0;
917
+ const featureSaved = (featureSavedTokens * pricePerM) / 1000000;
918
+ statVal = '$' + featureSaved.toFixed(2);
919
+ statColor = '#10B981';
920
+ }
921
+ const rowClass = isSoon ? 'csa-row is-soon' : isOff ? 'csa-row is-off' : 'csa-row';
922
+ html += `<div class="${rowClass}">
923
+ <label class="csa-toggle">
924
+ <input type="checkbox" ${checked ? 'checked' : ''} ${isSoon ? 'disabled' : ''} onchange="saveCsaToggle('${f.key}', this.checked)">
925
+ <span class="slider"></span>
926
+ </label>
927
+ <div class="csa-info">
928
+ <h4>${f.title}<span class="csa-status ${f.status}">${statusLabels[f.status]}</span></h4>
929
+ <p>${f.desc}</p>
930
+ <div class="csa-badges">${f.badges.map(b => `<span class="csa-badge">${b}</span>`).join('')}</div>
931
+ </div>
932
+ <div class="csa-stat">
933
+ <div class="csa-val" style="color:${statColor};">${statVal}</div>
934
+ <div class="csa-sub">${f.statSub}</div>
935
+ </div>
936
+ </div>`;
937
+ });
938
+ });
939
+ list.innerHTML = html;
940
+
941
+ const activeCount = CSA_FEATURES.reduce((s, c) => s + c.features.filter(f => f.status === 'active').length, 0);
942
+ const totalCount = CSA_FEATURES.reduce((s, c) => s + c.features.length, 0);
943
+ document.getElementById('csa-count-badge').textContent = `${activeCount}/${totalCount} active`;
944
+
945
+ // Proxy toggle + dedicated savings card
946
+ updateProxyToggle();
947
+ updateProxySavings();
948
+
949
+ document.getElementById('csa-summary').innerHTML = `
950
+ <div class="csa-summary-card">
951
+ <div class="csa-sum-label">Tokens Saved</div>
952
+ <div class="csa-sum-val" style="color:var(--emerald);">${totalSaved.toLocaleString()}</div>
953
+ </div>
954
+ <div class="csa-summary-card">
955
+ <div class="csa-sum-label">Total Saved</div>
956
+ <div class="csa-sum-val" style="color:var(--emerald);">$${savedUsd.toFixed(2)}</div>
957
+ </div>
958
+ <div class="csa-summary-card">
959
+ <div class="csa-sum-label">Reduction</div>
960
+ <div class="csa-sum-val" style="color:var(--indigo);">${reductionPct}%</div>
961
+ </div>
962
+ <div class="csa-summary-card">
963
+ <div class="csa-sum-label">Secrets Blocked</div>
964
+ <div class="csa-sum-val" style="color:var(--red);">${totalSecrets.toLocaleString()}</div>
965
+ </div>`;
966
+ }
967
+
560
968
  function isAiCommand(log) {
561
969
  // New logs have ai_detected field explicitly
562
970
  if (log.ai_detected === true) return true;
@@ -776,6 +1184,9 @@
776
1184
  // Chart + summary always use AI-only logs
777
1185
  renderChart(aiLogs, resolvedModel);
778
1186
 
1187
+ // CSA Feature Controls
1188
+ renderCsaSection(logs);
1189
+
779
1190
  // Security banner — aggregate across all logs
780
1191
  let totalSecrets = 0;
781
1192
  const allSecretTypes = {};
@@ -800,29 +1211,32 @@
800
1211
  secBanner.style.display = 'none';
801
1212
  }
802
1213
 
803
- const displayLogs = currentFilter === 'ai' ? aiLogs : logs;
1214
+ const displayLogs = (currentFilter === 'ai' ? aiLogs : logs)
1215
+ .filter(l => l.tokens_saved > 0);
804
1216
 
805
1217
  const tbody = document.getElementById('history-table-body');
806
1218
  if (displayLogs.length === 0) {
807
1219
  const msg = currentFilter === 'ai'
808
1220
  ? 'No AI agent commands detected yet. Commands from Claude Code, Cursor, Copilot etc. will appear here.'
809
1221
  : 'No logs recorded yet. Run commands with TrimPrompt to see stats!';
810
- tbody.innerHTML = `<tr><td colspan="7" style="text-align: center; color: var(--text-muted);">${msg}</td></tr>`;
1222
+ tbody.innerHTML = `<tr><td colspan="8" style="text-align: center; color: var(--text-muted);">${msg}</td></tr>`;
811
1223
  return;
812
1224
  }
813
1225
 
1226
+ const INITIAL_LIMIT = 100;
1227
+ const reversed = displayLogs.reverse();
814
1228
  tbody.innerHTML = '';
815
- displayLogs.reverse().forEach(log => {
1229
+
1230
+ function renderRow(log) {
816
1231
  const tr = document.createElement('tr');
817
1232
  const time = new Date(log.timestamp).toLocaleTimeString();
818
-
819
- const savingsPct = log.raw_chars > 0
1233
+ const savingsPct = log.raw_chars > 0
820
1234
  ? ((log.estimated_raw_tokens - log.estimated_compressed_tokens) / log.estimated_raw_tokens * 100).toFixed(1)
821
1235
  : '0.0';
822
-
823
1236
  tr.innerHTML = `
824
1237
  <td>${time}</td>
825
1238
  <td style="font-weight: 500;">${log.command}${log.secrets_found ? ' <span style="color:#F09595;font-size:11px;" title="' + log.secrets_found + ' secrets redacted">&#x1f6e1;' + log.secrets_found + '</span>' : ''}</td>
1239
+ <td>${featureTagHtml(log.features)}</td>
826
1240
  <td>${log.estimated_raw_tokens.toLocaleString()}</td>
827
1241
  <td>${log.estimated_compressed_tokens.toLocaleString()}</td>
828
1242
  <td style="color: var(--emerald); font-weight: 600;">${savingsPct}%</td>
@@ -835,8 +1249,27 @@
835
1249
  <button class="btn-inspect" data-id="${log.id}" data-cmd="${log.command}" data-sec="${log.secrets_found || 0}" data-types="${(log.secret_types || []).join(',')}" onclick="inspectFromBtn(this)">Inspect</button>
836
1250
  </td>
837
1251
  `;
838
- tbody.appendChild(tr);
839
- });
1252
+ return tr;
1253
+ }
1254
+
1255
+ reversed.slice(0, INITIAL_LIMIT).forEach(log => tbody.appendChild(renderRow(log)));
1256
+
1257
+ if (reversed.length > INITIAL_LIMIT) {
1258
+ const moreTr = document.createElement('tr');
1259
+ moreTr.id = 'show-more-row';
1260
+ moreTr.innerHTML = `<td colspan="8" style="text-align:center;padding:12px;">
1261
+ <button onclick="document.getElementById('show-more-row').remove();document.querySelectorAll('.hidden-log-row').forEach(r=>r.style.display='')" style="background:rgba(127,119,221,0.15);color:#7F77DD;border:none;padding:8px 24px;border-radius:8px;cursor:pointer;font-size:13px;font-weight:500;">
1262
+ Show ${reversed.length - INITIAL_LIMIT} more entries
1263
+ </button>
1264
+ </td>`;
1265
+ tbody.appendChild(moreTr);
1266
+ reversed.slice(INITIAL_LIMIT).forEach(log => {
1267
+ const tr = renderRow(log);
1268
+ tr.className = 'hidden-log-row';
1269
+ tr.style.display = 'none';
1270
+ tbody.appendChild(tr);
1271
+ });
1272
+ }
840
1273
  } catch (err) {
841
1274
  console.error('Failed to fetch history logs', err);
842
1275
  }
@@ -1000,8 +1433,8 @@
1000
1433
  } catch {}
1001
1434
  }
1002
1435
 
1003
- // Initial load: detect model first, then load stats
1004
- autoDetectModel().then(() => {
1436
+ // Initial load: detect model + load CSA toggles, then load stats
1437
+ Promise.all([autoDetectModel(), loadCsaToggles()]).then(() => {
1005
1438
  loadStats();
1006
1439
  loadHistory();
1007
1440
  });
package/mcp.js CHANGED
@@ -1 +1 @@
1
- 'use strict';function a0_0x411a(){const _0x9def2d=['result','5tCIIrJ','defineProperty','__esModule','write','mcp-tool-call','mcp\x20tool\x20(id:\x20','inherit','8MwXThl','getOwnPropertyDescriptor','hasOwnProperty','default','./tracker','trim','create','1345326FPczOv','pipe','tracker','content','runMcpProxy','createInterface','[TrimPrompt]\x20MCP\x20Server\x20Spawn\x20Error:\x20','347246quSeqJ','type','4003097ujcZuK','message','2894eFJJMo','9345950hDvEtQ','getOwnPropertyNames','stdin','child_process','configurable','string','compressOutput','__setModuleDefault','error','__importStar','getConfig','stdout','jsonrpc','writable','2.0','__createBinding','line','stringify','close','prototype','55532OIyKqf','length','call','4545333pXhruN','isArray','text','39fgqqlM','redaction_enabled','spawn'];a0_0x411a=function(){return _0x9def2d;};return a0_0x411a();}function a0_0x47fe(_0x3d2c16,_0x440d07){_0x3d2c16=_0x3d2c16-0x1e1;const _0x411a22=a0_0x411a();let _0x47fe4a=_0x411a22[_0x3d2c16];return _0x47fe4a;}const a0_0xed1943=a0_0x47fe;(function(_0xd6be5e,_0x1ea798){const _0x379184=a0_0x47fe,_0x160e71=_0xd6be5e();while(!![]){try{const _0x22ac92=parseInt(_0x379184(0x203))/0x1+-parseInt(_0x379184(0x1ff))/0x2+-parseInt(_0x379184(0x1e6))/0x3*(parseInt(_0x379184(0x218))/0x4)+-parseInt(_0x379184(0x1ea))/0x5*(parseInt(_0x379184(0x1f8))/0x6)+parseInt(_0x379184(0x201))/0x7*(-parseInt(_0x379184(0x1f1))/0x8)+parseInt(_0x379184(0x1e3))/0x9+parseInt(_0x379184(0x204))/0xa;if(_0x22ac92===_0x1ea798)break;else _0x160e71['push'](_0x160e71['shift']());}catch(_0x51b32b){_0x160e71['push'](_0x160e71['shift']());}}}(a0_0x411a,0x475ec));var __createBinding=this&&this[a0_0xed1943(0x213)]||(Object[a0_0xed1943(0x1f7)]?function(_0x25fc36,_0x303df1,_0x466eb5,_0x31570){const _0x1a290f=a0_0xed1943;if(_0x31570===undefined)_0x31570=_0x466eb5;var _0x4b3c9f=Object[_0x1a290f(0x1f2)](_0x303df1,_0x466eb5);(!_0x4b3c9f||('get'in _0x4b3c9f?!_0x303df1[_0x1a290f(0x1ec)]:_0x4b3c9f[_0x1a290f(0x211)]||_0x4b3c9f[_0x1a290f(0x208)]))&&(_0x4b3c9f={'enumerable':!![],'get':function(){return _0x303df1[_0x466eb5];}}),Object['defineProperty'](_0x25fc36,_0x31570,_0x4b3c9f);}:function(_0x5ae31c,_0x59c321,_0x1851bf,_0x2b8073){if(_0x2b8073===undefined)_0x2b8073=_0x1851bf;_0x5ae31c[_0x2b8073]=_0x59c321[_0x1851bf];}),__setModuleDefault=this&&this[a0_0xed1943(0x20b)]||(Object['create']?function(_0x15a6ba,_0x2f607d){const _0x2aa2bf=a0_0xed1943;Object[_0x2aa2bf(0x1eb)](_0x15a6ba,_0x2aa2bf(0x1f4),{'enumerable':!![],'value':_0x2f607d});}:function(_0xff119d,_0x35f6b7){_0xff119d['default']=_0x35f6b7;}),__importStar=this&&this[a0_0xed1943(0x20d)]||(function(){var _0x1a3f18=function(_0x466d04){const _0x50cb6f=a0_0x47fe;return _0x1a3f18=Object[_0x50cb6f(0x205)]||function(_0x56da74){const _0x3064b1=_0x50cb6f;var _0x43a204=[];for(var _0x5af62b in _0x56da74)if(Object[_0x3064b1(0x217)][_0x3064b1(0x1f3)][_0x3064b1(0x1e2)](_0x56da74,_0x5af62b))_0x43a204[_0x43a204['length']]=_0x5af62b;return _0x43a204;},_0x1a3f18(_0x466d04);};return function(_0x3fb47b){const _0x5176d8=a0_0x47fe;if(_0x3fb47b&&_0x3fb47b['__esModule'])return _0x3fb47b;var _0x5c202d={};if(_0x3fb47b!=null){for(var _0x2b2e7d=_0x1a3f18(_0x3fb47b),_0x289e00=0x0;_0x289e00<_0x2b2e7d[_0x5176d8(0x1e1)];_0x289e00++)if(_0x2b2e7d[_0x289e00]!==_0x5176d8(0x1f4))__createBinding(_0x5c202d,_0x3fb47b,_0x2b2e7d[_0x289e00]);}return __setModuleDefault(_0x5c202d,_0x3fb47b),_0x5c202d;};}());Object['defineProperty'](exports,a0_0xed1943(0x1ec),{'value':!![]}),exports[a0_0xed1943(0x1fc)]=runMcpProxy;const child_process_1=require(a0_0xed1943(0x207)),readline=__importStar(require('readline')),filters_1=require('./filters'),tracker_1=require(a0_0xed1943(0x1f5));function runMcpProxy(_0x2f2c9f,_0x3ed8ca){const _0x5bcd97=a0_0xed1943,_0x13be94=(0x0,child_process_1[_0x5bcd97(0x1e8)])(_0x2f2c9f,_0x3ed8ca,{'stdio':['pipe',_0x5bcd97(0x1f9),_0x5bcd97(0x1f0)]});process[_0x5bcd97(0x206)][_0x5bcd97(0x1f9)](_0x13be94[_0x5bcd97(0x206)]);const _0x273b60=readline[_0x5bcd97(0x1fd)]({'input':_0x13be94[_0x5bcd97(0x20f)],'terminal':![]});_0x273b60['on'](_0x5bcd97(0x214),_0x4069f1=>{const _0x4ba912=_0x5bcd97;try{const _0x27ea76=JSON['parse'](_0x4069f1);if(_0x27ea76&&_0x27ea76[_0x4ba912(0x210)]===_0x4ba912(0x212)&&_0x27ea76['id']!==undefined&&_0x27ea76['result']&&Array[_0x4ba912(0x1e4)](_0x27ea76[_0x4ba912(0x1e9)][_0x4ba912(0x1fb)])){let _0x45fde9=![];for(const _0x3abed8 of _0x27ea76['result'][_0x4ba912(0x1fb)]){if(_0x3abed8[_0x4ba912(0x200)]==='text'&&typeof _0x3abed8[_0x4ba912(0x1e5)]===_0x4ba912(0x209)&&_0x3abed8[_0x4ba912(0x1e5)][_0x4ba912(0x1f6)]()[_0x4ba912(0x1e1)]>0x0){const _0x1456a6=_0x3abed8[_0x4ba912(0x1e5)],_0x20a02e=(0x0,filters_1[_0x4ba912(0x20a)])(_0x4ba912(0x1ee),_0x1456a6,'',tracker_1[_0x4ba912(0x1fa)][_0x4ba912(0x20e)]()[_0x4ba912(0x1e7)]);tracker_1[_0x4ba912(0x1fa)]['logExecution'](_0x4ba912(0x1ef)+_0x27ea76['id']+')',_0x1456a6,_0x20a02e,0x0),_0x3abed8[_0x4ba912(0x1e5)]=_0x20a02e,_0x45fde9=!![];}}_0x45fde9?process[_0x4ba912(0x20f)]['write'](JSON[_0x4ba912(0x215)](_0x27ea76)+'\x0a'):process[_0x4ba912(0x20f)][_0x4ba912(0x1ed)](_0x4069f1+'\x0a');}else process[_0x4ba912(0x20f)][_0x4ba912(0x1ed)](_0x4069f1+'\x0a');}catch{process[_0x4ba912(0x20f)][_0x4ba912(0x1ed)](_0x4069f1+'\x0a');}}),_0x13be94['on'](_0x5bcd97(0x216),_0x2696b1=>{process['exit'](_0x2696b1||0x0);}),_0x13be94['on'](_0x5bcd97(0x20c),_0x5ad816=>{const _0x2cd4bf=_0x5bcd97;console['error'](_0x2cd4bf(0x1fe)+_0x5ad816[_0x2cd4bf(0x202)]),process['exit'](0x1);});}
1
+ 'use strict';function a0_0x30a8(){const _0xb5e878=['end','defineProperty','340JIjEvA','redaction_enabled','resp_optimize','exit','isArray','line','features_enabled','message','pipe','length','complexity','compressOutput','2457730hByJwM','max_tokens','trimmedCount','compressConversation','432MVHwBh','proxy:resp-optimize','getOwnPropertyDescriptor','string','\x20trimmed,\x20~','prototype','getConfig','write','error','params','logExecution','stdout','parse','1WniODX','374eRwXxS','result','close','inherit','runMcpProxy','stdin','readline','8454530SSHNLy','spawn','34296QLowki','configurable','hasOwnProperty','create','292326iCNHPw','160227NkRfbD','conv_compress','savedTokens','\x20tokens\x20saved)','createInterface','max_tokens:\x20','2.0','messages','__setModuleDefault','getOwnPropertyNames','content','child_process','text','tracker','mcp\x20tool\x20(id:\x20','__esModule','jsonrpc','./tracker','proxy:conv-compress','default','type','\x20messages\x20(','6858498JxtEWZ','./filters','__importStar','630200JFEHDC','stringify','\x20messages'];a0_0x30a8=function(){return _0xb5e878;};return a0_0x30a8();}const a0_0x4f0680=a0_0x2299;(function(_0x262b03,_0x560e33){const _0x37dd16=a0_0x2299,_0x2c53ae=_0x262b03();while(!![]){try{const _0x3a47cb=-parseInt(_0x37dd16(0x1ee))/0x1*(parseInt(_0x37dd16(0x1fc))/0x2)+parseInt(_0x37dd16(0x1f8))/0x3*(-parseInt(_0x37dd16(0x1d1))/0x4)+parseInt(_0x37dd16(0x1dd))/0x5+-parseInt(_0x37dd16(0x213))/0x6+parseInt(_0x37dd16(0x1f6))/0x7+-parseInt(_0x37dd16(0x1e1))/0x8*(parseInt(_0x37dd16(0x1fd))/0x9)+parseInt(_0x37dd16(0x216))/0xa*(parseInt(_0x37dd16(0x1ef))/0xb);if(_0x3a47cb===_0x560e33)break;else _0x2c53ae['push'](_0x2c53ae['shift']());}catch(_0x2ae35d){_0x2c53ae['push'](_0x2c53ae['shift']());}}}(a0_0x30a8,0x974a8));var __createBinding=this&&this['__createBinding']||(Object[a0_0x4f0680(0x1fb)]?function(_0x544190,_0x377f45,_0xdbe6c4,_0x1c75bb){const _0x2f2c10=a0_0x4f0680;if(_0x1c75bb===undefined)_0x1c75bb=_0xdbe6c4;var _0x20003a=Object[_0x2f2c10(0x1e3)](_0x377f45,_0xdbe6c4);(!_0x20003a||('get'in _0x20003a?!_0x377f45['__esModule']:_0x20003a['writable']||_0x20003a[_0x2f2c10(0x1f9)]))&&(_0x20003a={'enumerable':!![],'get':function(){return _0x377f45[_0xdbe6c4];}}),Object[_0x2f2c10(0x1d0)](_0x544190,_0x1c75bb,_0x20003a);}:function(_0x3089c3,_0x165f67,_0x4d64c6,_0x512bff){if(_0x512bff===undefined)_0x512bff=_0x4d64c6;_0x3089c3[_0x512bff]=_0x165f67[_0x4d64c6];}),__setModuleDefault=this&&this[a0_0x4f0680(0x205)]||(Object['create']?function(_0x522b0a,_0x3354cd){const _0x56e0e2=a0_0x4f0680;Object[_0x56e0e2(0x1d0)](_0x522b0a,_0x56e0e2(0x210),{'enumerable':!![],'value':_0x3354cd});}:function(_0x4cfd5f,_0x4f8a97){const _0x5a7107=a0_0x4f0680;_0x4cfd5f[_0x5a7107(0x210)]=_0x4f8a97;}),__importStar=this&&this[a0_0x4f0680(0x215)]||(function(){var _0x5f3e36=function(_0x1e954b){const _0x858176=a0_0x2299;return _0x5f3e36=Object[_0x858176(0x206)]||function(_0x3b50d8){const _0x2bfed8=_0x858176;var _0x1e8040=[];for(var _0xb2831e in _0x3b50d8)if(Object[_0x2bfed8(0x1e6)][_0x2bfed8(0x1fa)]['call'](_0x3b50d8,_0xb2831e))_0x1e8040[_0x1e8040[_0x2bfed8(0x1da)]]=_0xb2831e;return _0x1e8040;},_0x5f3e36(_0x1e954b);};return function(_0x1814b6){const _0x3b0861=a0_0x2299;if(_0x1814b6&&_0x1814b6[_0x3b0861(0x20c)])return _0x1814b6;var _0x4b8f0e={};if(_0x1814b6!=null){for(var _0x125d1c=_0x5f3e36(_0x1814b6),_0x10eda9=0x0;_0x10eda9<_0x125d1c[_0x3b0861(0x1da)];_0x10eda9++)if(_0x125d1c[_0x10eda9]!==_0x3b0861(0x210))__createBinding(_0x4b8f0e,_0x1814b6,_0x125d1c[_0x10eda9]);}return __setModuleDefault(_0x4b8f0e,_0x1814b6),_0x4b8f0e;};}());function a0_0x2299(_0x44fcfe,_0x578deb){_0x44fcfe=_0x44fcfe-0x1cf;const _0x30a86d=a0_0x30a8();let _0x2299a4=_0x30a86d[_0x44fcfe];return _0x2299a4;}Object[a0_0x4f0680(0x1d0)](exports,a0_0x4f0680(0x20c),{'value':!![]}),exports[a0_0x4f0680(0x1f3)]=runMcpProxy;const child_process_1=require(a0_0x4f0680(0x208)),readline=__importStar(require(a0_0x4f0680(0x1f5))),filters_1=require(a0_0x4f0680(0x214)),tracker_1=require(a0_0x4f0680(0x20e)),proxy_conv_1=require('./proxy-conv'),proxy_resp_1=require('./proxy-resp');function runMcpProxy(_0x57350f,_0x217b15){const _0x1e0b3e=a0_0x4f0680,_0x53d625=(0x0,child_process_1[_0x1e0b3e(0x1f7)])(_0x57350f,_0x217b15,{'stdio':[_0x1e0b3e(0x1d9),'pipe',_0x1e0b3e(0x1f2)]}),_0x40f766=tracker_1[_0x1e0b3e(0x20a)][_0x1e0b3e(0x1e7)](),_0x38dc9c=_0x40f766[_0x1e0b3e(0x1d7)]||{},_0x456493=_0x38dc9c[_0x1e0b3e(0x1fe)]!==![],_0x431585=_0x38dc9c[_0x1e0b3e(0x1d3)]!==![],_0x16090e=readline[_0x1e0b3e(0x201)]({'input':process['stdin'],'terminal':![]});_0x16090e['on'](_0x1e0b3e(0x1d6),_0x4caa93=>{const _0x348fb0=_0x1e0b3e;try{const _0xe2dd40=JSON[_0x348fb0(0x1ed)](_0x4caa93);if(_0xe2dd40&&_0xe2dd40[_0x348fb0(0x20d)]===_0x348fb0(0x203)&&_0xe2dd40['method']&&_0xe2dd40[_0x348fb0(0x1ea)]){const _0x2e64e7=_0xe2dd40[_0x348fb0(0x1ea)];if(Array[_0x348fb0(0x1d5)](_0x2e64e7[_0x348fb0(0x204)])&&_0x2e64e7[_0x348fb0(0x204)][_0x348fb0(0x1da)]>0x0){if(_0x456493){const _0x1458a9=(0x0,proxy_conv_1[_0x348fb0(0x1e0)])(_0x2e64e7['messages']);(_0x1458a9['trimmedCount']>0x0||_0x1458a9['savedTokens']>0x0)&&(_0x2e64e7['messages']=_0x1458a9['messages'],tracker_1[_0x348fb0(0x20a)][_0x348fb0(0x1eb)](_0x348fb0(0x20f),_0x1458a9['trimmedCount']+_0x1458a9[_0x348fb0(0x204)][_0x348fb0(0x1da)]+_0x348fb0(0x218),_0x1458a9['messages']['length']+_0x348fb0(0x212)+_0x1458a9[_0x348fb0(0x1df)]+_0x348fb0(0x1e5)+_0x1458a9[_0x348fb0(0x1ff)]+_0x348fb0(0x200),0x0,undefined,[_0x348fb0(0x1fe)]));}if(_0x431585){const _0x178f9e=(0x0,proxy_resp_1['optimizeMaxTokens'])(_0x2e64e7[_0x348fb0(0x204)],_0x2e64e7[_0x348fb0(0x1de)]);if(_0x178f9e){const _0x49a621=_0x2e64e7['max_tokens']||_0x348fb0(0x210);_0x2e64e7[_0x348fb0(0x1de)]=_0x178f9e[_0x348fb0(0x1de)],tracker_1[_0x348fb0(0x20a)][_0x348fb0(0x1eb)](_0x348fb0(0x1e2),_0x348fb0(0x202)+_0x49a621,_0x348fb0(0x202)+_0x178f9e['max_tokens']+'\x20('+_0x178f9e[_0x348fb0(0x1db)]+')',0x0,undefined,[_0x348fb0(0x1d3)]);}}}_0x53d625['stdin'][_0x348fb0(0x1e8)](JSON[_0x348fb0(0x217)](_0xe2dd40)+'\x0a');}else _0x53d625[_0x348fb0(0x1f4)]['write'](_0x4caa93+'\x0a');}catch{_0x53d625[_0x348fb0(0x1f4)][_0x348fb0(0x1e8)](_0x4caa93+'\x0a');}}),_0x16090e['on'](_0x1e0b3e(0x1f1),()=>{const _0x26e1b9=_0x1e0b3e;try{_0x53d625['stdin'][_0x26e1b9(0x1cf)]();}catch{}});const _0x5ee505=readline[_0x1e0b3e(0x201)]({'input':_0x53d625['stdout'],'terminal':![]});_0x5ee505['on']('line',_0x143e6e=>{const _0x48c5f3=_0x1e0b3e;try{const _0x2f15a2=JSON[_0x48c5f3(0x1ed)](_0x143e6e);if(_0x2f15a2&&_0x2f15a2['jsonrpc']===_0x48c5f3(0x203)&&_0x2f15a2['id']!==undefined&&_0x2f15a2[_0x48c5f3(0x1f0)]&&Array[_0x48c5f3(0x1d5)](_0x2f15a2[_0x48c5f3(0x1f0)][_0x48c5f3(0x207)])){let _0x2fc2f6=![];for(const _0x5f4514 of _0x2f15a2[_0x48c5f3(0x1f0)]['content']){if(_0x5f4514[_0x48c5f3(0x211)]===_0x48c5f3(0x209)&&typeof _0x5f4514[_0x48c5f3(0x209)]===_0x48c5f3(0x1e4)&&_0x5f4514[_0x48c5f3(0x209)]['trim']()[_0x48c5f3(0x1da)]>0x0){const _0x2ae734=_0x5f4514[_0x48c5f3(0x209)],_0x298c50=(0x0,filters_1[_0x48c5f3(0x1dc)])('mcp-tool-call',_0x2ae734,'',tracker_1[_0x48c5f3(0x20a)]['getConfig']()[_0x48c5f3(0x1d2)]);tracker_1[_0x48c5f3(0x20a)][_0x48c5f3(0x1eb)](_0x48c5f3(0x20b)+_0x2f15a2['id']+')',_0x2ae734,_0x298c50,0x0),_0x5f4514['text']=_0x298c50,_0x2fc2f6=!![];}}_0x2fc2f6?process[_0x48c5f3(0x1ec)][_0x48c5f3(0x1e8)](JSON[_0x48c5f3(0x217)](_0x2f15a2)+'\x0a'):process[_0x48c5f3(0x1ec)]['write'](_0x143e6e+'\x0a');}else process[_0x48c5f3(0x1ec)]['write'](_0x143e6e+'\x0a');}catch{process[_0x48c5f3(0x1ec)][_0x48c5f3(0x1e8)](_0x143e6e+'\x0a');}}),_0x53d625['on']('close',_0x922be9=>{const _0xdb033a=_0x1e0b3e;process[_0xdb033a(0x1d4)](_0x922be9||0x0);}),_0x53d625['on'](_0x1e0b3e(0x1e9),_0x384593=>{const _0x4d3355=_0x1e0b3e;console[_0x4d3355(0x1e9)]('[TrimPrompt]\x20MCP\x20Server\x20Spawn\x20Error:\x20'+_0x384593[_0x4d3355(0x1d8)]),process[_0x4d3355(0x1d4)](0x1);});}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trimprompt",
3
- "version": "1.0.26",
3
+ "version": "1.0.28",
4
4
  "description": "TrimPrompt — Save 80% on LLM tokens. Zero-config CLI proxy for AI coding agents",
5
5
  "keywords": [
6
6
  "llm",
package/proxy-conv.js ADDED
@@ -0,0 +1 @@
1
+ 'use strict';const a0_0x30a306=a0_0x4093;(function(_0x4b43d6,_0x1dfdd1){const _0x4339f5=a0_0x4093,_0x4ebc47=_0x4b43d6();while(!![]){try{const _0x39c738=-parseInt(_0x4339f5(0x7e))/0x1+parseInt(_0x4339f5(0x7b))/0x2+parseInt(_0x4339f5(0x7a))/0x3+-parseInt(_0x4339f5(0x7c))/0x4+parseInt(_0x4339f5(0x75))/0x5*(parseInt(_0x4339f5(0x83))/0x6)+-parseInt(_0x4339f5(0x78))/0x7+parseInt(_0x4339f5(0x84))/0x8*(parseInt(_0x4339f5(0x82))/0x9);if(_0x39c738===_0x1dfdd1)break;else _0x4ebc47['push'](_0x4ebc47['shift']());}catch(_0x499024){_0x4ebc47['push'](_0x4ebc47['shift']());}}}(a0_0x5ae2,0x9d8c0));Object[a0_0x30a306(0x95)](exports,a0_0x30a306(0x91),{'value':!![]}),exports[a0_0x30a306(0x77)]=compressConversation;const ROLE_WEIGHT={'system':0x1,'user':0.8,'assistant':0.5,'tool':0.3};function estimateTokens(_0x15a3d2){const _0x393d57=a0_0x30a306;return Math['ceil'](_0x15a3d2[_0x393d57(0x90)]/0x4);}function blockText(_0x3aa2b8){const _0x4182c=a0_0x30a306;if(!_0x3aa2b8||typeof _0x3aa2b8!==_0x4182c(0x8b))return'';if(_0x3aa2b8[_0x4182c(0x8f)]==='text'&&typeof _0x3aa2b8['text']===_0x4182c(0x8d))return _0x3aa2b8['text'];if(_0x3aa2b8[_0x4182c(0x8f)]==='tool_result'){if(typeof _0x3aa2b8[_0x4182c(0x9a)]===_0x4182c(0x8d))return _0x3aa2b8['content'];if(Array[_0x4182c(0x81)](_0x3aa2b8[_0x4182c(0x9a)]))return _0x3aa2b8[_0x4182c(0x9a)][_0x4182c(0x87)](blockText)[_0x4182c(0x94)](Boolean)['join']('\x0a');}return'';}function messageText(_0x56e72a){const _0x302697=a0_0x30a306;if(typeof _0x56e72a['content']==='string')return _0x56e72a[_0x302697(0x9a)];if(Array[_0x302697(0x81)](_0x56e72a[_0x302697(0x9a)]))return _0x56e72a['content'][_0x302697(0x87)](blockText)[_0x302697(0x94)](Boolean)[_0x302697(0x99)]('\x0a');return'';}function a0_0x4093(_0x3c0fb4,_0x9bfc6e){_0x3c0fb4=_0x3c0fb4-0x74;const _0x5ae270=a0_0x5ae2();let _0x4093e8=_0x5ae270[_0x3c0fb4];return _0x4093e8;}function summarizeText(_0x52675b){const _0x4e1463=a0_0x30a306,_0xfbae33=estimateTokens(_0x52675b),_0x23300f=_0x52675b[_0x4e1463(0x8e)]('\x0a');if(_0xfbae33>0x7d0){if(_0x23300f[_0x4e1463(0x90)]>0xa){const _0x21f847=_0x23300f[_0x4e1463(0x85)](0x0,0x5)['join']('\x0a'),_0x8f6275=_0x23300f[_0x4e1463(0x85)](-0x5)[_0x4e1463(0x99)]('\x0a');return _0x21f847+'\x0a[...\x20'+(_0x23300f[_0x4e1463(0x90)]-0xa)+_0x4e1463(0x9b)+_0x8f6275;}return _0x52675b[_0x4e1463(0x85)](0x0,0x7d0)+(_0x4e1463(0x98)+(_0x52675b[_0x4e1463(0x90)]-0x7d0)+_0x4e1463(0x7f));}if(_0xfbae33>0x1f4){if(_0x23300f[_0x4e1463(0x90)]>0xa)return _0x23300f['slice'](0x0,0xa)[_0x4e1463(0x99)]('\x0a')+('\x0a[...\x20'+(_0x23300f['length']-0xa)+'\x20lines\x20trimmed\x20...]');return _0x52675b[_0x4e1463(0x85)](0x0,0x320)+('\x0a[...\x20'+(_0x52675b[_0x4e1463(0x90)]-0x320)+_0x4e1463(0x8a));}return _0x52675b;}function summarizeBlock(_0x2ded32){const _0x3a0260=a0_0x30a306;if(!_0x2ded32||typeof _0x2ded32!==_0x3a0260(0x8b))return _0x2ded32;if(_0x2ded32[_0x3a0260(0x8f)]===_0x3a0260(0x97)&&typeof _0x2ded32[_0x3a0260(0x97)]===_0x3a0260(0x8d))return{..._0x2ded32,'text':summarizeText(_0x2ded32['text'])};if(_0x2ded32[_0x3a0260(0x8f)]===_0x3a0260(0x74)){if(typeof _0x2ded32['content']===_0x3a0260(0x8d))return{..._0x2ded32,'content':summarizeText(_0x2ded32['content'])};if(Array[_0x3a0260(0x81)](_0x2ded32[_0x3a0260(0x9a)])){const _0x232bfa=largestBlockIndex(_0x2ded32['content']);if(_0x232bfa>=0x0){const _0xef3c3a=_0x2ded32[_0x3a0260(0x9a)][_0x3a0260(0x87)]((_0x30b026,_0x4ec19d)=>_0x4ec19d===_0x232bfa?summarizeBlock(_0x30b026):_0x30b026);return{..._0x2ded32,'content':_0xef3c3a};}}}return _0x2ded32;}function largestBlockIndex(_0x4de5e0){const _0x2749da=a0_0x30a306;let _0x3715a6=-0x1,_0x304975=-0x1;return _0x4de5e0[_0x2749da(0x92)]((_0x3f24e0,_0x5dbf4b)=>{const _0x461ce6=_0x2749da,_0x459e89=blockText(_0x3f24e0)[_0x461ce6(0x90)];_0x459e89>_0x304975&&(_0x304975=_0x459e89,_0x3715a6=_0x5dbf4b);}),_0x304975>0x0?_0x3715a6:-0x1;}function a0_0x5ae2(){const _0x2568cc=['\x20lines\x20trimmed\x20by\x20TrimPrompt\x20...]\x0a','tool_result','35kuqJie','originalIndex','compressConversation','8829870ZwPYze','role','783198UziNIg','1464002chTpbH','5061912VkDyLF','score','430061XKOukJ','\x20chars\x20trimmed\x20by\x20TrimPrompt\x20...]','indexOf','isArray','2924109LqTVfw','287046wknagk','56TyRvtm','slice','tokens','map','system','msg','\x20chars\x20trimmed\x20...]','object','push','string','split','type','length','__esModule','forEach','sort','filter','defineProperty','reduce','text','\x0a[...\x20','join','content'];a0_0x5ae2=function(){return _0x2568cc;};return a0_0x5ae2();}function scoreMessage(_0x4cca1b,_0x541f83,_0x696922){const _0x5b49bf=a0_0x30a306,_0x3d2072=ROLE_WEIGHT[_0x4cca1b[_0x5b49bf(0x79)]]||0.4,_0xf6fbcc=(_0x541f83+0x1)/_0x696922,_0x4ee547=messageText(_0x4cca1b),_0xff0d29=estimateTokens(_0x4ee547),_0x2b1a22=_0xff0d29>0x7d0?0.6:_0xff0d29>0x1f4?0.8:0x1;return _0x3d2072*(0.3+0.7*_0xf6fbcc)*_0x2b1a22;}function summarizeMessage(_0x1f8546){const _0x3468a3=a0_0x30a306,_0x448a6d=estimateTokens(messageText(_0x1f8546));if(_0x448a6d<=0x1f4)return _0x1f8546;if(typeof _0x1f8546['content']===_0x3468a3(0x8d))return{..._0x1f8546,'content':summarizeText(_0x1f8546[_0x3468a3(0x9a)])};if(Array[_0x3468a3(0x81)](_0x1f8546[_0x3468a3(0x9a)])){const _0x1cc8fa=largestBlockIndex(_0x1f8546[_0x3468a3(0x9a)]);if(_0x1cc8fa>=0x0){const _0x3ef269=_0x1f8546[_0x3468a3(0x9a)]['map']((_0x578d1c,_0x1fb8f2)=>_0x1fb8f2===_0x1cc8fa?summarizeBlock(_0x578d1c):_0x578d1c);return{..._0x1f8546,'content':_0x3ef269};}}return _0x1f8546;}function compressConversation(_0x483dae,_0x1d0b1d){const _0x215763=a0_0x30a306,_0x41e5f2={'messages':_0x483dae,'trimmedCount':0x0,'savedTokens':0x0};if(!_0x483dae||!Array[_0x215763(0x81)](_0x483dae)||_0x483dae[_0x215763(0x90)]<=0x6)return _0x41e5f2;try{return _compressConversation(_0x483dae,_0x1d0b1d);}catch{return _0x41e5f2;}}function _compressConversation(_0xc1c473,_0x7724f6){const _0xa65af5=a0_0x30a306,_0x38f519=_0x7724f6||0x13880,_0x3c2514=0x4,_0x83ec25=_0xc1c473['filter'](_0x1a95bd=>_0x1a95bd['role']==='system'),_0x267a19=_0xc1c473['filter'](_0x162e09=>_0x162e09['role']!==_0xa65af5(0x88)),_0xf79a7b=_0x267a19[_0xa65af5(0x85)](-_0x3c2514),_0x334333=_0x267a19[_0xa65af5(0x85)](0x0,-_0x3c2514),_0x28ed62=_0x334333['map']((_0x1a953c,_0x419fe0)=>({'msg':_0x1a953c,'score':scoreMessage(_0x1a953c,_0x419fe0,_0x334333['length']),'tokens':estimateTokens(messageText(_0x1a953c))})),_0x3d8859=_0x28ed62[_0xa65af5(0x96)]((_0x5210e5,_0x533a3f)=>_0x5210e5+_0x533a3f[_0xa65af5(0x86)],0x0),_0x2394c5=_0xf79a7b[_0xa65af5(0x96)]((_0x130b60,_0x409162)=>_0x130b60+estimateTokens(messageText(_0x409162)),0x0),_0xb3b485=_0x83ec25[_0xa65af5(0x96)]((_0x499cf3,_0x252046)=>_0x499cf3+estimateTokens(messageText(_0x252046)),0x0),_0x4167be=_0x38f519-_0x2394c5-_0xb3b485;if(_0x3d8859<=_0x4167be){let _0x1ee596=0x0;const _0x3f85e2=_0x28ed62[_0xa65af5(0x87)](_0x2c78d2=>{const _0x2210b5=_0xa65af5;if(_0x2c78d2[_0x2210b5(0x86)]>0x1f4){const _0x1867b0=summarizeMessage(_0x2c78d2[_0x2210b5(0x89)]),_0x31df81=estimateTokens(messageText(_0x1867b0));if(_0x31df81<_0x2c78d2[_0x2210b5(0x86)])return _0x1ee596+=_0x2c78d2['tokens']-_0x31df81,_0x1867b0;}return _0x2c78d2[_0x2210b5(0x89)];});return{'messages':[..._0x83ec25,..._0x3f85e2,..._0xf79a7b],'trimmedCount':0x0,'savedTokens':_0x1ee596};}_0x28ed62['sort']((_0x553133,_0x1da6b3)=>_0x1da6b3[_0xa65af5(0x7d)]-_0x553133[_0xa65af5(0x7d)]);let _0x36df55=0x0,_0x23942d=0x0,_0x532989=0x0;const _0x1898ed=[];for(const _0x4d000e of _0x28ed62){if(_0x36df55+_0x4d000e[_0xa65af5(0x86)]<=_0x4167be){if(_0x4d000e[_0xa65af5(0x86)]>0x3e8){const _0x309af1=summarizeMessage(_0x4d000e[_0xa65af5(0x89)]),_0x288592=estimateTokens(messageText(_0x309af1));_0x532989+=_0x4d000e[_0xa65af5(0x86)]-_0x288592,_0x36df55+=_0x288592,_0x1898ed[_0xa65af5(0x8c)]({'msg':_0x309af1,'originalIndex':_0x334333[_0xa65af5(0x80)](_0x4d000e[_0xa65af5(0x89)])});}else _0x36df55+=_0x4d000e[_0xa65af5(0x86)],_0x1898ed['push']({'msg':_0x4d000e[_0xa65af5(0x89)],'originalIndex':_0x334333[_0xa65af5(0x80)](_0x4d000e[_0xa65af5(0x89)])});}else _0x23942d++,_0x532989+=_0x4d000e[_0xa65af5(0x86)];}_0x1898ed[_0xa65af5(0x93)]((_0x515fcc,_0x214069)=>_0x515fcc['originalIndex']-_0x214069[_0xa65af5(0x76)]);const _0x55ed43=[..._0x83ec25,..._0x1898ed[_0xa65af5(0x87)](_0x138a94=>_0x138a94[_0xa65af5(0x89)]),..._0xf79a7b];return{'messages':_0x55ed43,'trimmedCount':_0x23942d,'savedTokens':_0x532989};}