release: freeze Nexus One AI 1.0.0-rc1

This commit is contained in:
Jino Jose committed 2026-08-17 11:05:19 +05:30
1 parent 63acefd890
commit 4f1419ca93
152 files changed
+9445 -828

No files matched your search

+113 -13
View File
@@ -55,6 +55,8 @@
.badge-status.failed { background:#FEE2E2; color:#B91C1C; }
.badge-status.pending { background:rgba(234,179,8,.15); color:#92400E; }
.badge-status.cancelled { background:#F3F4F6; color:#6B7280; }
.badge-status.approved { background:rgba(34,197,94,.15); color:#15803D; }
.badge-status.rejected { background:#FEE2E2; color:#B91C1C; }
/* ── Log viewer ───────────────────────────────────────────── */
.log-wrap { background:#0F1117; border-radius:8px; padding:14px 16px; font-family:monospace; font-size:11px; line-height:1.6; color:#A3E635; max-height:220px; overflow-y:auto; margin-top:14px; display:none; white-space:pre-wrap; word-break:break-all; }
@@ -77,6 +79,15 @@
/* ── Toolbar ──────────────────────────────────────────────── */
.tr-toolbar { display:flex; align-items:center; gap:10px; margin-bottom:16px; flex-wrap:wrap; }
.creator-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:14px; }
.creator-grid .full { grid-column:1/-1; }
.creator-actions { display:flex; gap:10px; align-items:center; flex-wrap:wrap; }
.sample-card { border:1px solid var(--bdr); border-radius:10px; padding:16px; margin-top:12px; background:rgba(255,255,255,.02); }
.sample-head { display:flex; justify-content:space-between; align-items:center; gap:12px; margin-bottom:12px; }
.sample-fields { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.sample-fields textarea { min-height:110px; resize:vertical; }
.source-preview { margin-top:10px; font-size:11px; color:var(--lt); max-height:70px; overflow:auto; white-space:pre-wrap; }
@media(max-width:720px){ .creator-grid,.sample-fields { grid-template-columns:1fr; } }
</style>
</head>
<body data-role="admin">
@@ -104,40 +115,35 @@
</div>
</div>
<div class="nav-dropdown">
<button class="nav-drop-btn active">Admin ▾</button>
<button class="nav-drop-btn">Admin ▾</button>
<div class="nav-drop-menu nav-drop-menu-wide">
<span class="nav-drop-cat">DOCS /</span>
<a href="security.html">Security & Privacy</a>
<a href="admin.html">Admin Guide</a>
<span class="nav-drop-cat">MONITOR /</span>
<a href="dashboard.html">Dashboard</a>
<a href="analytics.html">Usage Analytics</a>
<a href="audit.html">Governance & Audit</a>
<a href="health.html">Health Center</a>
<a href="feedback.html">Feedback &amp; Ratings</a>
<span class="nav-drop-cat">MANAGE /</span>
<a href="users.html">Users</a>
<a href="teams.html">Teams</a>
<a href="models-admin.html">Model Catalog</a>
<a href="training.html" class="active">Training</a>
<a href="knowledge.html">Knowledge Base</a>
<span class="nav-drop-cat">TOOLS /</span>
<a href="apikeys.html">API Keys</a>
<a href="benchmark.html">Benchmarking</a>
<a href="model-compare.html">Model Compare</a>
<a href="model-compare.html">Response Comparison</a>
<a href="api-playground.html">API Playground</a>
<a href="guardrails.html">Guardrails</a>
<a href="rag-quality.html">RAG Quality</a>
<a href="router.html">Model Router</a>
<a href="connectors.html">MCP & Enterprise Connectors</a>
<span class="nav-drop-cat">SYSTEM /</span>
<a href="console.html">Console</a>
<a href="settings.html">Settings</a>
</div>
</div>
<div class="nav-dropdown">
<button class="nav-drop-btn">AI Tools ▾</button>
<button class="nav-drop-btn active">AI Tools ▾</button>
<div class="nav-drop-menu">
<span class="nav-drop-cat">MODEL BUILD /</span>
<a href="dataset-creation.html">Dataset Creation</a>
<a href="training.html" class="active">Model Training</a>
<span class="nav-drop-cat">INTELLIGENCE /</span>
<a href="documents.html">Document Intelligence</a>
<a href="chat-multi.html">AI Workspace</a>
@@ -310,6 +316,7 @@ const MOCK_JOBS = [
let datasetsCache = [];
let jobRefreshTimer = null;
let lossCharts = {};
let generationRefreshTimer = null;
// ── Helpers ──────────────────────────────────────────────────────────────────
@@ -337,6 +344,99 @@ function statusBadge(s) {
return `<span class="badge-status ${s}">${s}</span>`;
}
function escapeHtml(value) {
return String(value ?? '').replace(/[&<>'"]/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;',"'":'&#39;','"':'&quot;'}[c]));
}
async function startDatasetCreation() {
const name = document.getElementById('dc-name').value.trim();
const model = document.getElementById('dc-model').value;
const file = document.getElementById('dc-file').files[0];
if (!name || !model || !file) return toast('Dataset name, local model, and source document are required', true);
const button = document.getElementById('dc-start');
button.disabled = true;
const fd = new FormData();
fd.append('name', name); fd.append('model', model); fd.append('file', file);
fd.append('format', document.getElementById('dc-format').value);
fd.append('target_count', document.getElementById('dc-count').value);
try {
const res = await fetch(`${_API}/training/dataset-generation`, {method:'POST', credentials:'include', body:fd});
const data = await res.json();
if (!res.ok) throw new Error(data.detail || 'Could not start generation');
toast('Dataset generation started');
document.getElementById('dc-status').textContent = 'Generation is running locally. You can leave this page and return.';
loadGenerationJobs();
} catch (e) { toast(e.message, true); }
finally { button.disabled = false; }
}
async function loadGenerationJobs() {
const tbody = document.getElementById('dc-jobs');
try {
const res = await fetch(`${_API}/training/dataset-generation`, {credentials:'include'});
const data = await res.json();
if (!res.ok) throw new Error(data.detail || 'Could not load generation jobs');
const jobs = data.jobs || [];
tbody.innerHTML = jobs.length ? jobs.map(job => `<tr>
<td><strong>${escapeHtml(job.name)}</strong></td><td>${escapeHtml(job.source_name)}</td>
<td>${escapeHtml(job.model)}</td><td>${job.generated_count}/${job.target_count}</td>
<td>${statusBadge(job.status)}${job.error_msg ? `<div class="lf-hint">${escapeHtml(job.error_msg)}</div>` : ''}</td>
<td>${job.generated_count ? `<button class="tr-btn ghost" onclick="reviewGeneration(${job.id},'${escapeHtml(job.name)}')">Review</button>` : ''}</td>
</tr>`).join('') : '<tr><td colspan="6" class="tr-empty">No generation jobs yet.</td></tr>';
const running = jobs.some(job => ['pending','running'].includes(job.status));
if (running && !generationRefreshTimer) generationRefreshTimer = setInterval(loadGenerationJobs, 5000);
if (!running && generationRefreshTimer) { clearInterval(generationRefreshTimer); generationRefreshTimer = null; }
} catch (e) { tbody.innerHTML = `<tr><td colspan="6" class="tr-empty">${escapeHtml(e.message)}</td></tr>`; }
}
async function reviewGeneration(jobId, name) {
const review = document.getElementById('dc-review');
const res = await fetch(`${_API}/training/dataset-generation/${jobId}/samples`, {credentials:'include'});
const data = await res.json();
if (!res.ok) return toast(data.detail || 'Could not load samples', true);
const samples = data.samples || [];
review.innerHTML = `<div class="tr-toolbar" style="margin-top:22px"><strong>Review: ${escapeHtml(name)}</strong>
<button class="tr-btn ghost" onclick="setAllSamples(${jobId},'approved')">Approve all</button>
<button class="tr-btn primary" onclick="publishGeneration(${jobId})">Publish approved to Dataset Manager</button></div>` +
(samples.length ? samples.map(s => `<div class="sample-card" id="sample-${s.id}">
<div class="sample-head"><strong>Sample ${s.id}</strong>${statusBadge(s.status)}</div>
<div class="sample-fields"><div><label class="lf-label">Instruction</label><textarea class="lf-input" id="si-${s.id}">${escapeHtml(s.instruction)}</textarea></div>
<div><label class="lf-label">Output</label><textarea class="lf-input" id="so-${s.id}">${escapeHtml(s.output)}</textarea></div></div>
<details class="source-preview"><summary>Grounding source</summary>${escapeHtml(s.source_text)}</details>
<div class="creator-actions" style="margin-top:12px"><button class="tr-btn ghost" onclick="saveSample(${s.id},'approved')">Approve &amp; Save</button>
<button class="tr-btn danger" onclick="saveSample(${s.id},'rejected')">Reject</button></div></div>`).join('') : '<div class="tr-empty">No samples generated.</div>');
review.dataset.jobId = jobId; review.dataset.jobName = name;
}
async function saveSample(id, status) {
const body = {instruction:document.getElementById(`si-${id}`).value, output:document.getElementById(`so-${id}`).value, status};
const res = await fetch(`${_API}/training/dataset-generation/samples/${id}`, {method:'PATCH', credentials:'include', headers:{'Content-Type':'application/json'}, body:JSON.stringify(body)});
const data = await res.json().catch(()=>({}));
if (!res.ok) return toast(data.detail || 'Could not save sample', true);
toast(status === 'approved' ? 'Sample approved' : 'Sample rejected');
reviewGeneration(document.getElementById('dc-review').dataset.jobId, document.getElementById('dc-review').dataset.jobName);
}
async function setAllSamples(jobId, status) {
const cards = [...document.querySelectorAll('.sample-card')];
for (const card of cards) {
const id = Number(card.id.replace('sample-',''));
const body = {instruction:document.getElementById(`si-${id}`).value, output:document.getElementById(`so-${id}`).value, status};
const res = await fetch(`${_API}/training/dataset-generation/samples/${id}`, {method:'PATCH', credentials:'include', headers:{'Content-Type':'application/json'}, body:JSON.stringify(body)});
if (!res.ok) return toast('Could not update every sample', true);
}
toast('All samples approved');
reviewGeneration(jobId, document.getElementById('dc-review').dataset.jobName);
}
async function publishGeneration(jobId) {
const res = await fetch(`${_API}/training/dataset-generation/${jobId}/publish`, {method:'POST', credentials:'include'});
const data = await res.json().catch(()=>({}));
if (!res.ok) return toast(data.detail || 'Could not publish dataset', true);
toast(`Published ${data.filename} with ${data.row_count} rows`);
loadDatasets();
}
// ── Drag and drop ─────────────────────────────────────────────────────────────
const zone = document.getElementById('upload-zone');
@@ -725,7 +825,7 @@ loadDatasets();
loadModels();
loadJobs();
</script>
<script src="auth.js"></script>
<script src="branding.js?v=3"></script>
<script src="auth.js?v=20260721-consolidated"></script>
<script src="branding.js?v=20260721-consolidated"></script>
</body>
</html>