diff --git a/ml/monitor.html b/ml/monitor.html
index fb51c7e..7443107 100644
--- a/ml/monitor.html
+++ b/ml/monitor.html
@@ -144,6 +144,7 @@
.ctlrow { display: flex; gap: 10px; margin-top: 14px; align-items: center; flex-wrap: wrap; }
.ctlrow .hint { font-size: 12px; color: var(--dim2); }
.term { background: #070a10; border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; height: 260px; overflow: auto; font: 12px/1.55 var(--mono); color: #c9d4e3; white-space: pre-wrap; word-break: break-all; }
+ .explore { background: #0b0f16; border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; max-height: 560px; overflow: auto; font: 12px/1.7 var(--mono); color: #c9d4e3; white-space: pre-wrap; }
.term .e { color: var(--bad); } .term .c { color: var(--accent); } .term .g { color: var(--ok); }
.modal { position: fixed; inset: 0; background: #05080ed9; backdrop-filter: blur(7px); display: none; align-items: flex-start; justify-content: center; z-index: 40; padding: 5vh 16px 24px; overflow: auto; }
.modal.show { display: flex; }
@@ -213,6 +214,7 @@
+
@@ -834,6 +836,7 @@ $('logy').onclick = () => { logyOn = !logyOn; $('logy').classList.toggle('on', l
for (const id of PREF_IDS) { $(id).onchange = prefSave; $(id).oninput = prefSave; }
$('run').onchange = () => { userPicked = true; cur = null; poll(); };
$('scenario').onchange = () => { api.scenario($('scenario').value); cur = null; userPicked = false; conOff = 0; $('run').innerHTML = ''; poll(); };
+api('/api/explore').then(d => { const el = $('explore'); el.textContent = (d && d.md) ? d.md : '(demo 模式:无探索日志)'; }).catch(() => { const el = $('explore'); el.textContent = '(无法读取 docs/探索日志.md)'; });
$('auto').onclick = () => { const on = !$('auto').classList.contains('on'); $('auto').classList.toggle('on', on); clearInterval(timer); if (on) timer = setInterval(poll, 1000); };
timer = setInterval(poll, 1000); poll();
diff --git a/ml/monitor.py b/ml/monitor.py
index 328beb0..469054a 100644
--- a/ml/monitor.py
+++ b/ml/monitor.py
@@ -608,6 +608,11 @@ class H(BaseHTTPRequestHandler):
if u.path == '/api/status': return self.send(200, json.dumps(status()), 'application/json')
if u.path == '/api/job': return self.send(200, json.dumps(JOB.state()), 'application/json')
if u.path == '/api/console': return self.send(200, json.dumps(console(int(q.get('offset', ['0'])[0]))), 'application/json')
+ if u.path == '/api/explore': # 2026-10-20:闭环探索日志(docs/探索日志.md)回写控制台
+ try:
+ with open(os.path.join(ROOT, 'docs', '探索日志.md'), encoding='utf-8') as f: md = f.read()
+ except Exception: md = ''
+ return self.send(200, json.dumps({'md': md}), 'application/json')
self.send(404, 'not found', 'text/plain')
except Exception as e:
self.send(500, json.dumps({'error': str(e)}), 'application/json')