Fix HF dataset import internal error and training SQLite readiness.
Wrap AssistentImportHfDataset in try/catch, batch inserts in a transaction, clearer HF rows errors for gated datasets, EnsureTrainingReady with actionable message, and friendlier training UI errors instead of generic internal error. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+33
-15
@@ -50,7 +50,7 @@ export function attachTraining(SA) {
|
||||
setAgentHeardStats(state.agentLinked);
|
||||
} catch (e) {
|
||||
const msg = String(e.message || e);
|
||||
setTrainStatus(isSqliteError(msg) ? `${msg} — ${sqliteHint()}` : msg);
|
||||
setTrainStatus(formatTrainError(msg));
|
||||
console.warn('loadAgentHeardSettings', e);
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ export function attachTraining(SA) {
|
||||
state.agentSettings = data?.settings || settings;
|
||||
setTrainStatus('Настройки «услышанного» сохранены');
|
||||
} catch (e) {
|
||||
setTrainStatus(String(e.message || e));
|
||||
setTrainStatus(formatTrainError(e.message || e));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ export function attachTraining(SA) {
|
||||
setTrainStatus(`Подключено: +${data?.linked_now ?? 0}, всего ${data?.total_linked ?? '—'}`);
|
||||
await refreshSamples();
|
||||
} catch (e) {
|
||||
setTrainStatus(String(e.message || e));
|
||||
setTrainStatus(formatTrainError(e.message || e));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,25 @@ export function attachTraining(SA) {
|
||||
|
||||
function isSqliteError(msg) {
|
||||
const s = String(msg || '').toLowerCase();
|
||||
return s.includes('sqlite') || s.includes('sqlconnection');
|
||||
return s.includes('sqlite')
|
||||
|| s.includes('sqlconnection')
|
||||
|| s.includes('train_samples')
|
||||
|| s.includes('training database unavailable');
|
||||
}
|
||||
|
||||
function isGenericServerError(msg) {
|
||||
return /internal error occurred/i.test(String(msg || ''));
|
||||
}
|
||||
|
||||
function formatTrainError(msg) {
|
||||
const s = String(msg || '');
|
||||
if (isSqliteError(s)) {
|
||||
return `${s} — ${sqliteHint()}`;
|
||||
}
|
||||
if (isGenericServerError(s)) {
|
||||
return `${s} — часто SQLite/импорт HF: gpu-rent seed-extensions, restart SwarmUI, HF token для gated.`;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
function sqliteHint() {
|
||||
@@ -167,7 +185,7 @@ export function attachTraining(SA) {
|
||||
const data = await SA.request('AssistentListTrainSamples', { status, persona, limit: 300 });
|
||||
if (data?.error) {
|
||||
const msg = data.error;
|
||||
setTrainStatus(isSqliteError(msg) ? `${msg} — ${sqliteHint()}` : msg);
|
||||
setTrainStatus(formatTrainError(msg));
|
||||
const stats = $('sa_train_stats');
|
||||
if (stats) stats.textContent = 'Датасет недоступен (SQLite)';
|
||||
state.samples = [];
|
||||
@@ -196,7 +214,7 @@ export function attachTraining(SA) {
|
||||
}
|
||||
renderSamples();
|
||||
} catch (e) {
|
||||
setTrainStatus(String(e.message || e));
|
||||
setTrainStatus(formatTrainError(e.message || e));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,7 +459,7 @@ export function attachTraining(SA) {
|
||||
renderHfList();
|
||||
setTrainStatus(`Найдено: ${state.hfResults.length}`);
|
||||
} catch (e) {
|
||||
setTrainStatus(String(e.message || e));
|
||||
setTrainStatus(formatTrainError(e.message || e));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,7 +540,7 @@ export function attachTraining(SA) {
|
||||
$('sa_train_samples')?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||
} catch (e) {
|
||||
const err = String(e.message || e);
|
||||
const show = isSqliteError(err) ? `${err} — ${sqliteHint()}` : err;
|
||||
const show = formatTrainError(err);
|
||||
setTrainStatus(show);
|
||||
if (hfSt) hfSt.textContent = show;
|
||||
} finally {
|
||||
@@ -578,7 +596,7 @@ export function attachTraining(SA) {
|
||||
setTrainStatus(`Готово: ${data.name}`);
|
||||
SA.app?.refreshModels?.();
|
||||
} catch (e) {
|
||||
setTrainStatus(String(e.message || e));
|
||||
setTrainStatus(formatTrainError(e.message || e));
|
||||
} finally {
|
||||
btn?.removeAttribute('disabled');
|
||||
}
|
||||
@@ -712,7 +730,7 @@ export function attachTraining(SA) {
|
||||
setTrainingTab('train');
|
||||
setTrainStatus('QLoRA запущена — прогресс ниже');
|
||||
} catch (e) {
|
||||
setTrainStatus(String(e.message || e));
|
||||
setTrainStatus(formatTrainError(e.message || e));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -722,7 +740,7 @@ export function attachTraining(SA) {
|
||||
setTrainingLock(false);
|
||||
setTrainStatus('Отменено');
|
||||
} catch (e) {
|
||||
setTrainStatus(String(e.message || e));
|
||||
setTrainStatus(formatTrainError(e.message || e));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -760,7 +778,7 @@ export function attachTraining(SA) {
|
||||
});
|
||||
setTrainStatus('Раннер сохранён');
|
||||
} catch (e) {
|
||||
setTrainStatus(String(e.message || e));
|
||||
setTrainStatus(formatTrainError(e.message || e));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -805,7 +823,7 @@ export function attachTraining(SA) {
|
||||
const data = await SA.request('AssistentImportDataset', { format: 'auto', content: text });
|
||||
setTrainStatus(`Импорт: ${data.imported}`);
|
||||
await refreshSamples();
|
||||
} catch (err) { setTrainStatus(String(err.message || err)); }
|
||||
} catch (err) { setTrainStatus(formatTrainError(err.message || err)); }
|
||||
e.target.value = '';
|
||||
});
|
||||
$('sa_btn_train_export')?.addEventListener('click', async () => {
|
||||
@@ -842,7 +860,7 @@ export function attachTraining(SA) {
|
||||
setAgentHeardStats(state.agentLinked);
|
||||
setTrainStatus('Пример подключён к агенту');
|
||||
await refreshSamples();
|
||||
} catch (err) { setTrainStatus(String(err.message || err)); }
|
||||
} catch (err) { setTrainStatus(formatTrainError(err.message || err)); }
|
||||
} else if (e.target.closest('[data-unlink]')) {
|
||||
try {
|
||||
const data = await SA.request('AssistentUnlinkTrainSampleFromAgent', { id });
|
||||
@@ -850,7 +868,7 @@ export function attachTraining(SA) {
|
||||
setAgentHeardStats(state.agentLinked);
|
||||
setTrainStatus('Пример отключён от агента');
|
||||
await refreshSamples();
|
||||
} catch (err) { setTrainStatus(String(err.message || err)); }
|
||||
} catch (err) { setTrainStatus(formatTrainError(err.message || err)); }
|
||||
} else if (e.target.closest('[data-del]')) {
|
||||
if (window.confirm('Удалить пример?')) {
|
||||
await SA.request('AssistentDeleteTrainSample', { id });
|
||||
|
||||
Reference in New Issue
Block a user