clementine-agent 1.18.134 → 1.18.135

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.
@@ -19771,10 +19771,15 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
19771
19771
  <div class="tab-pane" id="tab-intelligence-learning">
19772
19772
  <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;gap:12px;flex-wrap:wrap">
19773
19773
  <div style="font-size:13px;color:var(--text-secondary);max-width:680px">
19774
- Self-improvement runs nightly at 1 AM. The autonomous loop also auto-fixes failing crons (3+ consecutive errors) and verifies each fix over the next 3 runs &mdash; reverting automatically if it doesn't help.
19774
+ Karpathy-style autoresearch loop. Hypothesizes improvements to SOUL, prompts, crons; evaluates each with a blended score (LLM &times; 0.7 + objective &times; 0.3). Fires nightly at <strong id="si-schedule-hour">3 AM</strong> (override via SELF_IMPROVE_HOUR env). The auto-fix consumer also handles failing crons (3+ consecutive errors) and verifies each fix over the next 3 runs &mdash; reverting automatically if it doesn't help.
19775
19775
  </div>
19776
19776
  <button class="btn-sm btn-primary" onclick="siRunCycle()" id="si-run-btn">Run Now</button>
19777
19777
  </div>
19778
+ <!-- 1.18.135 — last-diagnostic banner. Surfaces the loop's
19779
+ own self-report ("Plateau: no novel improvement area remaining"
19780
+ etc.) so the user knows WHY recent runs were quiet without
19781
+ digging into state.json. -->
19782
+ <div id="si-diagnostic-banner" style="display:none;margin-bottom:12px;padding:10px 14px;border-radius:6px;font-size:12px"></div>
19778
19783
  <div class="grid-2" id="si-status-cards">
19779
19784
  <div class="skel-block"><div class="skel-row med"></div><div class="skel-row short"></div></div>
19780
19785
  <div class="skel-block"><div class="skel-row med"></div><div class="skel-row short"></div></div>
@@ -40193,17 +40198,61 @@ async function refreshSelfImprove() {
40193
40198
  }
40194
40199
  }
40195
40200
 
40201
+ // 1.18.135 — diagnostic banner. Shows the loop's own last self-report
40202
+ // (plateau, cooldown, infra error). Color-coded so the user can tell
40203
+ // at a glance whether the silence is intentional ("plateau, no fresh
40204
+ // signal") vs broken ("infra error, in 24h cooldown").
40205
+ const diagEl = document.getElementById('si-diagnostic-banner');
40206
+ if (diagEl) {
40207
+ const diag = state && state.lastDiagnostic ? String(state.lastDiagnostic) : '';
40208
+ const infra = state && state.infraError ? state.infraError : null;
40209
+ if (infra) {
40210
+ diagEl.style.display = '';
40211
+ diagEl.style.background = 'rgba(239,68,68,0.08)';
40212
+ diagEl.style.border = '1px solid var(--red)';
40213
+ diagEl.style.color = 'var(--text-primary)';
40214
+ diagEl.innerHTML = '<strong style="color:var(--red)">⚠ Infrastructure error</strong> &middot; ' + esc(infra.diagnostic || infra.category || 'unknown') + ' &middot; in 24h cooldown until ' + (infra.cooldownUntil ? new Date(infra.cooldownUntil).toLocaleString() : 'next probe');
40215
+ } else if (diag) {
40216
+ diagEl.style.display = '';
40217
+ const isPlateau = /plateau/i.test(diag);
40218
+ diagEl.style.background = isPlateau ? 'rgba(245,158,11,0.08)' : 'var(--bg-tertiary)';
40219
+ diagEl.style.border = isPlateau ? '1px solid var(--yellow)' : '1px solid var(--border)';
40220
+ diagEl.style.color = 'var(--text-secondary)';
40221
+ diagEl.innerHTML = (isPlateau ? '<strong style="color:var(--yellow)">⏸ Last run note:</strong> ' : '<strong>Last run note:</strong> ') + esc(diag);
40222
+ } else {
40223
+ diagEl.style.display = 'none';
40224
+ }
40225
+ }
40226
+
40196
40227
  // Status cards
40197
40228
  const cards = document.getElementById('si-status-cards');
40198
40229
  if (cards && state) {
40199
40230
  const m = state.baselineMetrics || {};
40231
+ // 1.18.135 — show the blended objective signal (cronSuccessRate ×
40232
+ // feedbackPositiveRatio) explicitly so the user sees the floor that
40233
+ // every LLM-rated proposal is now multiplied against (1.18.134).
40234
+ const objectiveScore = (m.cronSuccessRate || 0) * (m.feedbackPositiveRatio || 0);
40235
+ // Compute next scheduled run time. Defaults to 3am unless the env var
40236
+ // SELF_IMPROVE_HOUR was set on the daemon — we don't have visibility
40237
+ // into env from the dashboard, so we always show the default.
40238
+ const nextRunAt = (() => {
40239
+ const next = new Date();
40240
+ next.setHours(3, 0, 0, 0);
40241
+ if (next.getTime() <= Date.now()) next.setDate(next.getDate() + 1);
40242
+ return next;
40243
+ })();
40244
+ const nextRunMs = nextRunAt.getTime() - Date.now();
40245
+ const nextRunHrs = Math.max(0, Math.floor(nextRunMs / 3600000));
40246
+ const nextRunLabel = nextRunHrs >= 24 ? Math.floor(nextRunHrs / 24) + 'd' : nextRunHrs + 'h';
40200
40247
  cards.innerHTML =
40201
40248
  '<div class="stat-card"><div class="stat-value">' + (state.status || 'idle') + '</div><div class="stat-label">Status</div></div>' +
40202
40249
  '<div class="stat-card"><div class="stat-value">' + (state.totalExperiments || 0) + '</div><div class="stat-label">Total Experiments</div></div>' +
40203
40250
  '<div class="stat-card"><div class="stat-value">' + (pending.length || 0) + '</div><div class="stat-label">Pending Approvals</div></div>' +
40204
40251
  '<div class="stat-card"><div class="stat-value">' + (state.lastRunAt ? new Date(state.lastRunAt).toLocaleDateString() : 'Never') + '</div><div class="stat-label">Last Run</div></div>' +
40252
+ '<div class="stat-card" title="Next nightly trigger (3am default)"><div class="stat-value">in ' + nextRunLabel + '</div><div class="stat-label">Next Run</div></div>' +
40205
40253
  '<div class="stat-card"><div class="stat-value">' + ((m.feedbackPositiveRatio || 0) * 100).toFixed(0) + '%</div><div class="stat-label">Feedback Positive</div></div>' +
40206
- '<div class="stat-card"><div class="stat-value">' + ((m.cronSuccessRate || 0) * 100).toFixed(0) + '%</div><div class="stat-label">Cron Success</div></div>';
40254
+ '<div class="stat-card"><div class="stat-value">' + ((m.cronSuccessRate || 0) * 100).toFixed(0) + '%</div><div class="stat-label">Cron Success</div></div>' +
40255
+ '<div class="stat-card" title="cronSuccessRate × feedbackPositiveRatio. Blended into every proposal score at 30% weight (override via SELF_IMPROVE_OBJECTIVE_WEIGHT)."><div class="stat-value">' + (objectiveScore * 10).toFixed(1) + '/10</div><div class="stat-label">Objective Floor</div></div>';
40207
40256
  } else if (cards) {
40208
40257
  cards.innerHTML = '<div class="stat-card"><div class="stat-value">idle</div><div class="stat-label">Status</div></div>' +
40209
40258
  '<div class="stat-card"><div class="stat-value">0</div><div class="stat-label">Total Experiments</div></div>';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clementine-agent",
3
- "version": "1.18.134",
3
+ "version": "1.18.135",
4
4
  "description": "Clementine — Personal AI Assistant (TypeScript)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",