fix: disable Local Train buttons when TIP_LOCAL_TRAIN_COMMAND not configured

- Add ids to Local Train buttons (sl-local-btn-tip, sl-local-btn-blog)
- Add _slLocalReady flag updated after status load
- _updateLocalTrainButtons() enables/disables buttons based on local.ready
- startSelflearningTrain() guards local provider with early check + helpful message
- Status banner shows checkmarks for RunPod/HF/Local config state
This commit is contained in:
Rene Fichtmueller 2026-04-25 23:19:03 +02:00
parent 15a456a0ce
commit 7935453073

View File

@ -1691,7 +1691,7 @@
<div style="display:flex;gap:0.5rem;flex-wrap:wrap">
<button onclick="startSelflearningTrain('tip_llm','runpod',true)" style="background:#0f766e;color:#fff;border:none;padding:6px 10px;border-radius:6px;cursor:pointer;font-size:0.75rem;font-weight:700">RunPod Seed</button>
<button onclick="startSelflearningTrain('tip_llm','runpod',false)" style="background:#b45309;color:#fff;border:none;padding:6px 10px;border-radius:6px;cursor:pointer;font-size:0.75rem;font-weight:700">RunPod Full</button>
<button onclick="startSelflearningTrain('tip_llm','local',true)" style="background:var(--surface2);color:var(--text);border:1px solid var(--border);padding:6px 10px;border-radius:6px;cursor:pointer;font-size:0.75rem;font-weight:700">Local Train</button>
<button id="sl-local-btn-tip" onclick="startSelflearningTrain('tip_llm','local',true)" style="background:var(--surface2);color:var(--text-dim);border:1px solid var(--border);padding:6px 10px;border-radius:6px;cursor:not-allowed;font-size:0.75rem;font-weight:700;opacity:0.5" disabled title="Lokales Training nicht konfiguriert — TIP_LOCAL_TRAIN_COMMAND fehlt">Local Train</button>
</div>
</div>
<div class="card">
@ -1704,7 +1704,7 @@
<div style="display:flex;gap:0.5rem;flex-wrap:wrap">
<button onclick="startSelflearningTrain('blog_llm','runpod',true)" style="background:#0f766e;color:#fff;border:none;padding:6px 10px;border-radius:6px;cursor:pointer;font-size:0.75rem;font-weight:700">RunPod Seed</button>
<button onclick="startSelflearningTrain('blog_llm','runpod',false)" style="background:#b45309;color:#fff;border:none;padding:6px 10px;border-radius:6px;cursor:pointer;font-size:0.75rem;font-weight:700">RunPod Full</button>
<button onclick="startSelflearningTrain('blog_llm','local',true)" style="background:var(--surface2);color:var(--text);border:1px solid var(--border);padding:6px 10px;border-radius:6px;cursor:pointer;font-size:0.75rem;font-weight:700">Local Train</button>
<button id="sl-local-btn-blog" onclick="startSelflearningTrain('blog_llm','local',true)" style="background:var(--surface2);color:var(--text-dim);border:1px solid var(--border);padding:6px 10px;border-radius:6px;cursor:not-allowed;font-size:0.75rem;font-weight:700;opacity:0.5" disabled title="Lokales Training nicht konfiguriert — TIP_LOCAL_TRAIN_COMMAND fehlt">Local Train</button>
</div>
</div>
</div>
@ -6602,14 +6602,16 @@ async function loadSelflearning() {
var manifest = d.manifest || null;
renderSelflearningLane('tip_llm', manifest && manifest.lanes && manifest.lanes.tip_llm, d.lanes && d.lanes.tip_llm);
renderSelflearningLane('blog_llm', manifest && manifest.lanes && manifest.lanes.blog_llm, d.lanes && d.lanes.blog_llm);
var localReady = !!(d.local && d.local.ready);
_updateLocalTrainButtons(localReady);
if (banner) {
var parts = [
'RunPod Endpoint: ' + (d.runpod && d.runpod.endpoint_configured ? 'ok' : 'fehlt'),
'RunPod API: ' + (d.runpod && d.runpod.api_key_configured ? 'ok' : 'fehlt'),
'HF Token: ' + (d.huggingface && d.huggingface.token_configured ? 'ok' : 'fehlt'),
'Local: ' + (d.local && d.local.ready ? 'konfiguriert' : 'noch kein TIP_LOCAL_TRAIN_COMMAND')
'RunPod Endpoint: ' + (d.runpod && d.runpod.endpoint_configured ? 'ok' : 'fehlt'),
'RunPod API: ' + (d.runpod && d.runpod.api_key_configured ? 'ok' : 'fehlt'),
'HF Token: ' + (d.huggingface && d.huggingface.token_configured ? 'ok' : 'fehlt'),
'Local: ' + (localReady ? '✓ konfiguriert' : '✗ kein TIP_LOCAL_TRAIN_COMMAND')
];
banner.innerHTML = '<strong>Status:</strong> ' + parts.map(esc).join(' · ')
banner.innerHTML = '<strong>Status:</strong> ' + parts.join(' &nbsp;·&nbsp; ')
+ (manifest ? '<br><span style="font-size:0.72rem">Manifest: ' + esc(manifest.version || '-') + ' · ' + esc(manifest.generated_at || '-') + '</span>' : '<br><span style="font-size:0.72rem">Noch kein Manifest vorhanden.</span>');
}
} catch(e) {
@ -6648,9 +6650,44 @@ async function publishSelflearningHF() {
}
}
var _slLocalReady = false;
function _updateLocalTrainButtons(ready) {
_slLocalReady = ready;
['tip', 'blog'].forEach(function(lane) {
var btn = el('sl-local-btn-' + lane);
if (!btn) return;
if (ready) {
btn.disabled = false;
btn.style.cursor = 'pointer';
btn.style.opacity = '1';
btn.style.color = 'var(--text)';
btn.title = 'Lokales Training starten';
} else {
btn.disabled = true;
btn.style.cursor = 'not-allowed';
btn.style.opacity = '0.45';
btn.style.color = 'var(--text-dim)';
btn.title = 'Nicht konfiguriert — setze TIP_LOCAL_TRAIN_COMMAND in ecosystem.config.js';
}
});
}
async function startSelflearningTrain(lane, provider, seedOnly) {
if (provider === 'local' && !_slLocalReady) {
setSelflearningLog(
'Lokales Training ist nicht konfiguriert.\n\n' +
'Setze TIP_LOCAL_TRAIN_COMMAND in /opt/tip/ecosystem.config.js:\n' +
' TIP_LOCAL_TRAIN_COMMAND: \'/opt/tip/scripts/local-train.sh\'\n\n' +
'Das Script wird aufgerufen als:\n' +
' /opt/tip/scripts/local-train.sh tip_llm\n' +
' /opt/tip/scripts/local-train.sh blog_llm'
);
showToast('Local Train nicht aktiv', 'TIP_LOCAL_TRAIN_COMMAND ist nicht konfiguriert.', true);
return;
}
var label = lane + ' / ' + provider + (seedOnly ? ' / seed' : ' / full');
setSelflearningLog('Training Start: ' + label);
setSelflearningLog('Training Start: ' + label + ' …');
try {
var d = await api('/api/selflearning/train', {
method: 'POST',