fffiloni commited on
Commit
965cd9a
·
verified ·
1 Parent(s): e2ec4a6

Upload 7 files

Browse files
web/static/app.css CHANGED
@@ -2779,3 +2779,16 @@ strong,p,h1,h2,h3,h4,span,a,button,div,li{overflow-wrap:break-word;word-break:no
2779
  gap:.2rem;
2780
  text-align:center;
2781
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2779
  gap:.2rem;
2780
  text-align:center;
2781
  }
2782
+
2783
+ .timeline-skeleton{
2784
+ grid-column:1/-1;
2785
+ border:1px dashed #cbd5e1;
2786
+ background:#f8fafc;
2787
+ color:#64748b;
2788
+ border-radius:14px;
2789
+ padding:14px 16px;
2790
+ font-size:13px;
2791
+ text-align:center;
2792
+ }
2793
+
2794
+ /* v190.10 — Active Run timeline hotfix */
web/static/app.js CHANGED
@@ -544,7 +544,8 @@ function resetRunDetails(){
544
  // legacy anchor: renderTimeline(DEFAULT_TIMELINE,'idle')
545
  renderActiveRunEmptyState();
546
  } function prepareNewBuild(){if(state.poll){clearInterval(state.poll);state.poll=null}state.runId=null;state.activeRunProgress=null;state.selectedRunDetail=null;state.documentCache={};state.latencyCache={};state.activeLinks={};state.pollErrors=0;clearSavedRun();document.querySelectorAll('.run-row').forEach(r=>r.classList.remove('selected'));setBuildModeNew();resetRunDetails();setText('progressPercent','0%');const cap=$('progressCaptionLabel');if(cap)cap.textContent='Overall progress';const sem=$('progressSemantics');if(sem){sem.hidden=true;sem.innerHTML=''}const fill=$('progressFill');if(fill)fill.style.width='0%';setText('currentStep','Ready');setText('lastEvent','Choose a model card and launch a build.');setText('elapsed','—');if(typeof elapsedClock!=='undefined')elapsedClock.isRunning=false;setText('lastPolled','—');setText('hardwarePlan',hardwarePlanLabel());renderMetrics({});showMessage('New build mode ready.','info')}
547
- function setActiveRun(result){if(state.poll){clearInterval(state.poll);state.poll=null}resetRunDetails();state.documentCache={};state.latencyCache={};state.runId=result.run_id;state.spaceLinksUnlockedFor=null;if(Array.isArray(state.runsCache)&&typeof sortRunsNewestFirst==='function'){state.runsCache=sortRunsNewestFirst([{...result,run_id:result.run_id,status:result.status||'running',created_at:result.created_at||new Date().toISOString()},...state.runsCache.filter(r=>r.run_id!==result.run_id)]);renderRunsFromCache();}if(result.bucket_source)state.bucketSource=result.bucket_source;setText('detailRunId',result.run_id);setText('detailJobStatus',result.status||'RUNNING');setText('detailGateStatus',result.kind||'running');setText('detailSpace',result.target_space||'');setText('detailHardware',result.selected_hardware||result.preferred_space_hardware||'—');renderActiveRunMeta({summary:result,state:result,launch:result});renderProgress({run_id:result.run_id,status:result.status||'running',progress:1,current_step_label:'Launching build Job…',events:[{step:'launch',status:'started',message:'Build Job launched; waiting for first worker event.'}],summary:result,state:result});setText('homeRunDetailStatus',result.status||'Running');setBuildModeInspecting(result.run_id);setQuickLinks({...result.links,bucket_source:result.bucket_source,run_id:result.run_id,job_id:result.job_id,job_owner:state.user?.username,target_space_url:result.target_space_url},result);saveActiveRun();markPendingActiveFields();startPolling(result.run_id)}
 
548
  function startPolling(runId,options={}){
549
  if(!runId)return;
550
  const sameRun=state.runId===runId;
@@ -926,7 +927,7 @@ async function refreshRunReportPreview(runId){
926
  console.warn('report refresh failed',e);
927
  }
928
  }
929
- async function refreshProgress(){if(!state.runId||state.progressPollInFlight)return;state.progressPollInFlight=true;try{const now=Date.now();const includeLogs=!state.lastJobLogPoll||now-state.lastJobLogPoll>8000;if(includeLogs)state.lastJobLogPoll=now;const requestedRunId=state.runId;const p=await apiGet(`/api/runs/${encodeURIComponent(requestedRunId)}/progress?bucket_name=${encodeURIComponent(state.bucketName)}${includeLogs?'&include_job_logs=1':''}`);if(requestedRunId!==state.runId)return;if((p.run_id||p.summary?.run_id)&&state.runId&&(p.run_id||p.summary?.run_id)!==state.runId)return;state.activeRunProgress=p;state.pollErrors=0;if(p.bucket_source)state.bucketSource=p.bucket_source;renderProgress(p);renderEvents(p.events||[]);renderMetrics(p);if(typeof upsertRunExplorerFromProgress==='function')upsertRunExplorerFromProgress(p);if(typeof renderActiveRunActions==='function')renderActiveRunActions({...p.summary,bucket_source:p.bucket_source},p);if(typeof renderRunDocuments==='function')renderRunDocuments({...p,summary:{...p.summary,bucket_source:p.bucket_source}});if(typeof renderAgentRecovery==='function')renderAgentRecovery(p);if(typeof renderBlockers==='function')renderBlockers(p);if(p.view){setText('detailRunId',p.view.run_id||p.run_id);setText('selectedModelId',p.view.header?.model||p.summary?.model_id||'—')}else{setText('detailRunId',p.run_id||state.runId)}renderActiveRunMeta(p);if(p.state){setText('detailSpace',p.state.target_space||p.summary?.target_space||'—');const mode=runImplementationMode(p.summary||{},p);setText('detailImplementationMode',mode?implementationModeLabel(mode):'—');const modeEl=$('detailImplementationMode');if(modeEl&&mode)modeEl.title=implementationModeDescription(mode);setText('detailHardware',p.state.selected_hardware||p.summary?.selected_hardware||'—')}setText('detailJobStatus',p.status||p.state?.status||p.view?.header?.raw_status||'running');setText('detailGateStatus',p.inference_gate?.status||p.summary?.gate_status||'—');setText('detailTraces',Array.isArray(p.events)?String(p.events.length)+' events':'—');setText('homeRunDetailStatus',badgeLabel(p.status||p.state?.status||p.view?.header?.status||'running'));setQuickLinks({...p.links,...p.view?.links,bucket_source:p.bucket_source,run_id:p.run_id},{...p,events:p.events||[]});saveActiveRun();const status=String(p.view?.header?.status||p.status||p.state?.status||'').toLowerCase();if(TERMINAL_STATUSES.has(status)&&state.poll){clearInterval(state.poll);state.poll=null;if(state.lastReportRefreshRunId!==state.runId){state.lastReportRefreshRunId=state.runId;setTimeout(()=>refreshRunReportPreview(state.runId),120);setTimeout(()=>loadRuns(true),160)}setOperation(`Run finished with status: ${badgeLabel(status)}`,status.includes('success')||status.includes('succeed')?'success':status.includes('failed')||status.includes('blocker')?'error':'warning')}markPendingActiveFields();if(now-(state.lastRunsRefreshFromPoll||0)>15000){state.lastRunsRefreshFromPoll=now;loadRuns(false)}}catch(e){state.pollErrors+=1;console.warn(e);setOperation(`Progress polling failed ${state.pollErrors} time${state.pollErrors===1?'':'s'}. Retrying automatically…`,'warning')}finally{state.progressPollInFlight=false}} function numberFromEvents(events=[],keys=[]){
930
  const rows=Array.isArray(events)?events:[];
931
  for(let i=rows.length-1;i>=0;i--){
932
  const event=rows[i]||{};
 
544
  // legacy anchor: renderTimeline(DEFAULT_TIMELINE,'idle')
545
  renderActiveRunEmptyState();
546
  } function prepareNewBuild(){if(state.poll){clearInterval(state.poll);state.poll=null}state.runId=null;state.activeRunProgress=null;state.selectedRunDetail=null;state.documentCache={};state.latencyCache={};state.activeLinks={};state.pollErrors=0;clearSavedRun();document.querySelectorAll('.run-row').forEach(r=>r.classList.remove('selected'));setBuildModeNew();resetRunDetails();setText('progressPercent','0%');const cap=$('progressCaptionLabel');if(cap)cap.textContent='Overall progress';const sem=$('progressSemantics');if(sem){sem.hidden=true;sem.innerHTML=''}const fill=$('progressFill');if(fill)fill.style.width='0%';setText('currentStep','Ready');setText('lastEvent','Choose a model card and launch a build.');setText('elapsed','—');if(typeof elapsedClock!=='undefined')elapsedClock.isRunning=false;setText('lastPolled','—');setText('hardwarePlan',hardwarePlanLabel());renderMetrics({});showMessage('New build mode ready.','info')}
547
+ function renderQuietLaunchState(result={}){setText('progressTitle','Starting build Job…');setText('progressStatus','Running');const statusEl=$('progressStatus');if(statusEl)statusEl.className='badge '+statusClass('running');setText('progressPercent','1%');const fill=$('progressFill');if(fill)fill.style.width='1%';setText('lastEvent','Build Job launched; waiting for the first canonical run snapshot.');setText('elapsed','—');setText('lastPolled','');const timeline=$('timeline');if(timeline){timeline.innerHTML='<div class="timeline-skeleton">Waiting for first run snapshot…</div>';timeline.classList.remove('timeline-canonical');timeline.style.gridTemplateColumns=''}const note=$('timelineTraceNote');if(note){note.hidden=true;note.innerHTML=''}const details=$('timelinePhaseDetails');if(details){details.hidden=true;details.innerHTML='';details.className='timeline-phase-details'}}
548
+ function setActiveRun(result){if(state.poll){clearInterval(state.poll);state.poll=null}resetRunDetails();state.documentCache={};state.latencyCache={};state.runId=result.run_id;state.spaceLinksUnlockedFor=null;if(Array.isArray(state.runsCache)&&typeof sortRunsNewestFirst==='function'){state.runsCache=sortRunsNewestFirst([{...result,run_id:result.run_id,status:result.status||'running',created_at:result.created_at||new Date().toISOString()},...state.runsCache.filter(r=>r.run_id!==result.run_id)]);renderRunsFromCache();if(typeof renderRunStats==='function')renderRunStats();}if(result.bucket_source)state.bucketSource=result.bucket_source;setText('detailRunId',result.run_id);setText('detailJobStatus',result.status||'RUNNING');setText('detailGateStatus',result.kind||'running');setText('detailSpace',result.target_space||'—');setText('detailHardware',result.selected_hardware||result.preferred_space_hardware||'—');renderActiveRunMeta({summary:result,state:result,launch:result});renderQuietLaunchState(result);setText('homeRunDetailStatus',result.status||'Running');setBuildModeInspecting(result.run_id);setQuickLinks({...result.links,bucket_source:result.bucket_source,run_id:result.run_id,job_id:result.job_id,job_owner:state.user?.username,target_space_url:result.target_space_url},result);saveActiveRun();markPendingActiveFields();startPolling(result.run_id)}
549
  function startPolling(runId,options={}){
550
  if(!runId)return;
551
  const sameRun=state.runId===runId;
 
927
  console.warn('report refresh failed',e);
928
  }
929
  }
930
+ async function refreshProgress(){if(!state.runId||state.progressPollInFlight)return;state.progressPollInFlight=true;try{const now=Date.now();const includeLogs=!state.lastJobLogPoll||now-state.lastJobLogPoll>8000;if(includeLogs)state.lastJobLogPoll=now;const requestedRunId=state.runId;const p=await apiGet(`/api/runs/${encodeURIComponent(requestedRunId)}/progress?bucket_name=${encodeURIComponent(state.bucketName)}${includeLogs?'&include_job_logs=1':''}`);if(requestedRunId!==state.runId)return;if((p.run_id||p.summary?.run_id)&&state.runId&&(p.run_id||p.summary?.run_id)!==state.runId)return;state.activeRunProgress=p;state.pollErrors=0;if(p.bucket_source)state.bucketSource=p.bucket_source;if(typeof renderRunViewSnapshot==='function')renderRunViewSnapshot(p);else renderProgress(p);renderEvents(p.events||[]);renderMetrics(p);if(typeof upsertRunExplorerFromProgress==='function')upsertRunExplorerFromProgress(p);if(typeof renderRunStats==='function')renderRunStats();if(typeof renderActiveRunActions==='function')renderActiveRunActions({...p.summary,bucket_source:p.bucket_source},p);if(typeof renderRunDocuments==='function')renderRunDocuments({...p,summary:{...p.summary,bucket_source:p.bucket_source}});if(typeof renderAgentRecovery==='function')renderAgentRecovery(p);if(typeof renderBlockers==='function')renderBlockers(p);if(p.view){setText('detailRunId',p.view.run_id||p.run_id);setText('selectedModelId',p.view.header?.model||p.summary?.model_id||'—')}else{setText('detailRunId',p.run_id||state.runId)}renderActiveRunMeta(p);if(p.state){setText('detailSpace',p.state.target_space||p.summary?.target_space||'—');const mode=runImplementationMode(p.summary||{},p);setText('detailImplementationMode',mode?implementationModeLabel(mode):'—');const modeEl=$('detailImplementationMode');if(modeEl&&mode)modeEl.title=implementationModeDescription(mode);setText('detailHardware',p.state.selected_hardware||p.summary?.selected_hardware||'—')}setText('detailJobStatus',p.status||p.state?.status||p.view?.header?.raw_status||'running');setText('detailGateStatus',p.inference_gate?.status||p.summary?.gate_status||'—');setText('detailTraces',Array.isArray(p.events)?String(p.events.length)+' events':'—');setText('homeRunDetailStatus',badgeLabel(p.status||p.state?.status||p.view?.header?.status||'running'));setQuickLinks({...p.links,...p.view?.links,bucket_source:p.bucket_source,run_id:p.run_id},{...p,events:p.events||[]});saveActiveRun();const modelProgress=p.view?.timeline_model?.progress||{};const terminalSnapshot=modelProgress.terminal===true||p.view?.status_model?.is_terminal===true;const status=String(p.view?.header?.status||p.status||p.state?.status||'').toLowerCase();if((terminalSnapshot||TERMINAL_STATUSES.has(status))&&state.poll){clearInterval(state.poll);state.poll=null;if(state.lastReportRefreshRunId!==state.runId){state.lastReportRefreshRunId=state.runId;setTimeout(()=>refreshRunReportPreview(state.runId),120);setTimeout(()=>loadRuns(true),160)}{const visual=String(modelProgress.visual_status||'').toLowerCase();const type=visual==='success'?'success':visual==='error'?'error':(status.includes('success')||status.includes('succeed')?'success':status.includes('failed')||status.includes('blocker')?'error':'warning');setOperation(`Run finished with status: ${badgeLabel(modelProgress.verdict||status)}`,type)}}markPendingActiveFields();if(now-(state.lastRunsRefreshFromPoll||0)>15000){state.lastRunsRefreshFromPoll=now;loadRuns(false)}}catch(e){state.pollErrors+=1;console.warn(e);setOperation(`Progress polling failed ${state.pollErrors} time${state.pollErrors===1?'':'s'}. Retrying automatically…`,'warning')}finally{state.progressPollInFlight=false}} function numberFromEvents(events=[],keys=[]){
931
  const rows=Array.isArray(events)?events:[];
932
  for(let i=rows.length-1;i>=0;i--){
933
  const event=rows[i]||{};
web/static/progress.js CHANGED
@@ -508,9 +508,14 @@ function renderTimelineModelDetails(model={},activePhase=null){
508
  if(!phase||!(phase.id||phase.label)){root.hidden=true;root.innerHTML='';return;}
509
  const status=String(phase.status||'pending').toLowerCase();
510
  const tone=timelineStatus(status).replace(/^status-/,'');
 
 
 
 
 
 
511
  let rows=timelinePhaseDetailRows(phase);
512
  let summary=phase.summary||'';
513
- const isRecovery=String(phase.id||'')==='recovery';
514
  if(String(phase.id||'')==='recovery'){
515
  // Recovery has its own dedicated Agent recovery panel below the timeline.
516
  // Keep the phase details as a compact pointer instead of duplicating
 
508
  if(!phase||!(phase.id||phase.label)){root.hidden=true;root.innerHTML='';return;}
509
  const status=String(phase.status||'pending').toLowerCase();
510
  const tone=timelineStatus(status).replace(/^status-/,'');
511
+ const warnings=Array.isArray(model.warnings)?model.warnings:[];
512
+ const details=Array.isArray(phase.details)?phase.details:[];
513
+ const phaseId=String(phase.id||'');
514
+ const isRecovery=String(phase.id||'')==='recovery';
515
+ const actionable=status.includes('fail')||status.includes('error')||status.includes('warn')||status.includes('manual')||isRecovery||warnings.length>0||details.some(d=>{const st=String(d?.status||'').toLowerCase();return st.includes('fail')||st.includes('warn')||st.includes('manual')||st==='info';});
516
+ if(!actionable){root.hidden=true;root.innerHTML='';root.className='timeline-phase-details';return;}
517
  let rows=timelinePhaseDetailRows(phase);
518
  let summary=phase.summary||'';
 
519
  if(String(phase.id||'')==='recovery'){
520
  // Recovery has its own dedicated Agent recovery panel below the timeline.
521
  // Keep the phase details as a compact pointer instead of duplicating
web/static/runs.js CHANGED
@@ -420,6 +420,7 @@ function upsertRunExplorerFromProgress(p={}){
420
  else state.runsCache.unshift(summary);
421
  state.runsLastLoaded=Date.now();
422
  renderRunsFromCache();
 
423
  }
424
  function renderRunSelectionPreview(runId){
425
  const cached=cachedRunById(runId);
@@ -476,6 +477,7 @@ function renderRunViewSnapshot(snapshot={}){
476
  if(typeof renderAgentRecovery==='function')renderAgentRecovery(snapshot);
477
  if(typeof renderBlockers==='function')renderBlockers(snapshot);
478
  if(typeof setQuickLinks==='function')setQuickLinks({...snapshot.links,...snapshot.view?.links,bucket_source:snapshot.bucket_source,run_id:runId},snapshot);
 
479
  }finally{
480
  requestAnimationFrame(()=>document.body.classList.remove('rendering-run-snapshot'));
481
  }
 
420
  else state.runsCache.unshift(summary);
421
  state.runsLastLoaded=Date.now();
422
  renderRunsFromCache();
423
+ if(typeof renderRunStats==='function')renderRunStats(state.runsCache||[]);
424
  }
425
  function renderRunSelectionPreview(runId){
426
  const cached=cachedRunById(runId);
 
477
  if(typeof renderAgentRecovery==='function')renderAgentRecovery(snapshot);
478
  if(typeof renderBlockers==='function')renderBlockers(snapshot);
479
  if(typeof setQuickLinks==='function')setQuickLinks({...snapshot.links,...snapshot.view?.links,bucket_source:snapshot.bucket_source,run_id:runId},snapshot);
480
+ if(typeof upsertRunExplorerFromProgress==='function')upsertRunExplorerFromProgress(snapshot);
481
  }finally{
482
  requestAnimationFrame(()=>document.body.classList.remove('rendering-run-snapshot'));
483
  }