Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Upload 7 files
Browse files- web/static/app.css +164 -24
- web/static/app.js +33 -16
web/static/app.css
CHANGED
|
@@ -2094,30 +2094,170 @@ strong,p,h1,h2,h3,h4,span,a,button,div,li{overflow-wrap:break-word;word-break:no
|
|
| 2094 |
.eval-enable-button[hidden]{display:none!important;}
|
| 2095 |
.eval-enable-button{white-space:nowrap;}
|
| 2096 |
|
| 2097 |
-
/*
|
| 2098 |
.compact-storage{gap:12px!important;}
|
| 2099 |
.compact-storage .bucket-status-card{margin-bottom:0!important;}
|
| 2100 |
-
.eval-archive-
|
| 2101 |
-
|
| 2102 |
-
|
| 2103 |
-
|
| 2104 |
-
|
| 2105 |
-
|
| 2106 |
-
|
| 2107 |
-
|
| 2108 |
-
|
| 2109 |
-
|
| 2110 |
-
|
| 2111 |
-
}
|
| 2112 |
-
.eval-archive-
|
| 2113 |
-
.eval-archive-
|
| 2114 |
-
.eval-archive-
|
| 2115 |
-
.eval-archive-
|
| 2116 |
-
.eval-archive-
|
| 2117 |
-
.eval-archive-copy p{margin:0;color:var(--muted);font-size:.72rem;line-height:1.25;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
|
| 2118 |
-
.eval-archive-card.on .eval-archive-copy p{color:#047857;}
|
| 2119 |
-
.eval-archive-actions{display:flex;align-items:center;justify-content:flex-end;gap:7px;flex-wrap:wrap;}
|
| 2120 |
-
.eval-archive-actions button{min-height:34px;padding:8px 10px!important;border-radius:12px!important;white-space:nowrap;}
|
| 2121 |
.eval-archive-actions .danger{color:#be123c!important;background:rgba(255,241,242,.82)!important;border-color:rgba(244,63,94,.2)!important;}
|
| 2122 |
-
.eval-feedback{display:block!important;width:auto!important;max-width:100%;padding:0!important;border:0!important;background:transparent!important;border-radius:0!important;font-size:.
|
| 2123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2094 |
.eval-enable-button[hidden]{display:none!important;}
|
| 2095 |
.eval-enable-button{white-space:nowrap;}
|
| 2096 |
|
| 2097 |
+
/* v183: Eval Archive moved to the observability column under Run Stats */
|
| 2098 |
.compact-storage{gap:12px!important;}
|
| 2099 |
.compact-storage .bucket-status-card{margin-bottom:0!important;}
|
| 2100 |
+
.eval-archive-panel{
|
| 2101 |
+
margin-top:14px;
|
| 2102 |
+
padding:14px;
|
| 2103 |
+
border-radius:20px;
|
| 2104 |
+
background:linear-gradient(180deg,rgba(255,255,255,.92),rgba(248,250,252,.76));
|
| 2105 |
+
border:1px solid rgba(226,232,240,.78);
|
| 2106 |
+
box-shadow:0 16px 36px rgba(15,23,42,.035),0 1px 0 rgba(255,255,255,.92) inset;
|
| 2107 |
+
}
|
| 2108 |
+
.eval-archive-panel[hidden]{display:none!important;}
|
| 2109 |
+
.eval-archive-panel.on{background:linear-gradient(180deg,rgba(240,253,244,.82),rgba(255,255,255,.86));border-color:rgba(34,197,94,.2)}
|
| 2110 |
+
.eval-archive-panel.off{background:linear-gradient(180deg,rgba(248,250,252,.88),rgba(255,255,255,.86));}
|
| 2111 |
+
.eval-archive-title-row{align-items:flex-start;margin-bottom:8px!important;}
|
| 2112 |
+
.eval-archive-title-row h4{margin:2px 0 0;font-size:.98rem;line-height:1.15;letter-spacing:-.02em;color:var(--ink);}
|
| 2113 |
+
.eval-archive-summary{margin:0 0 12px;color:var(--muted);font-size:.78rem;line-height:1.35;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;}
|
| 2114 |
+
.eval-archive-panel.on .eval-archive-summary{color:#047857;}
|
| 2115 |
+
.eval-archive-actions{display:flex;align-items:center;justify-content:flex-start;gap:8px;flex-wrap:wrap;}
|
| 2116 |
+
.eval-archive-actions button{min-height:34px;padding:8px 11px!important;border-radius:12px!important;white-space:nowrap;}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2117 |
.eval-archive-actions .danger{color:#be123c!important;background:rgba(255,241,242,.82)!important;border-color:rgba(244,63,94,.2)!important;}
|
| 2118 |
+
.eval-feedback{display:block!important;width:auto!important;max-width:100%;padding:0!important;border:0!important;background:transparent!important;border-radius:0!important;font-size:.78rem!important;font-weight:650!important;line-height:1.35!important;letter-spacing:0!important;}
|
| 2119 |
+
.eval-feedback.off{color:#64748b!important;background:transparent!important;border:0!important;opacity:1!important}
|
| 2120 |
+
@media(max-width:760px){.eval-archive-actions{justify-content:flex-start}}
|
| 2121 |
+
|
| 2122 |
+
/* v184: compact premium Model pre-scan states */
|
| 2123 |
+
.model-prescan-card.required{
|
| 2124 |
+
border-color:rgba(148,163,184,.28)!important;
|
| 2125 |
+
background:radial-gradient(circle at 12% 0%,rgba(59,130,246,.075),transparent 36%),linear-gradient(180deg,rgba(255,255,255,.99),rgba(248,250,252,.94))!important;
|
| 2126 |
+
box-shadow:0 14px 34px rgba(15,23,42,.055),0 1px 0 rgba(255,255,255,.9) inset!important;
|
| 2127 |
+
}
|
| 2128 |
+
.model-prescan-card.required .model-prescan-head strong{font-size:16px!important;letter-spacing:-.03em!important}
|
| 2129 |
+
.model-prescan-card.required>p{font-size:12.75px!important;line-height:1.42!important;max-width:50ch!important}
|
| 2130 |
+
.model-prescan-card.required #scanModel{
|
| 2131 |
+
border-color:rgba(37,99,235,.22)!important;
|
| 2132 |
+
background:linear-gradient(180deg,#fff,#f8fafc)!important;
|
| 2133 |
+
box-shadow:0 8px 18px rgba(15,23,42,.06)!important;
|
| 2134 |
+
}
|
| 2135 |
+
.model-prescan-card.success{
|
| 2136 |
+
border-color:rgba(34,197,94,.20)!important;
|
| 2137 |
+
background:radial-gradient(circle at 98% 0%,rgba(34,197,94,.08),transparent 34%),linear-gradient(180deg,rgba(255,255,255,.99),rgba(248,250,252,.93))!important;
|
| 2138 |
+
}
|
| 2139 |
+
.model-prescan-card.success .model-prescan-head strong{font-size:15px!important}
|
| 2140 |
+
.model-prescan-card.success>p{font-size:12.5px!important;line-height:1.36!important;margin-top:-2px!important}
|
| 2141 |
+
.model-prescan-card.success .model-prescan-signals{gap:8px!important}
|
| 2142 |
+
.prescan-compact-grid{
|
| 2143 |
+
display:grid!important;
|
| 2144 |
+
grid-template-columns:repeat(3,minmax(0,1fr))!important;
|
| 2145 |
+
gap:7px!important;
|
| 2146 |
+
}
|
| 2147 |
+
.prescan-chip{
|
| 2148 |
+
display:grid!important;
|
| 2149 |
+
grid-template-columns:auto 1fr!important;
|
| 2150 |
+
grid-template-areas:"icon label" "icon value"!important;
|
| 2151 |
+
column-gap:7px!important;
|
| 2152 |
+
align-items:center!important;
|
| 2153 |
+
min-width:0!important;
|
| 2154 |
+
padding:8px 9px!important;
|
| 2155 |
+
border-radius:14px!important;
|
| 2156 |
+
border:1px solid rgba(226,232,240,.82)!important;
|
| 2157 |
+
background:rgba(255,255,255,.82)!important;
|
| 2158 |
+
}
|
| 2159 |
+
.prescan-chip i{
|
| 2160 |
+
grid-area:icon!important;
|
| 2161 |
+
width:23px!important;
|
| 2162 |
+
height:23px!important;
|
| 2163 |
+
display:inline-flex!important;
|
| 2164 |
+
align-items:center!important;
|
| 2165 |
+
justify-content:center!important;
|
| 2166 |
+
border-radius:999px!important;
|
| 2167 |
+
background:rgba(248,250,252,.96)!important;
|
| 2168 |
+
color:#475569!important;
|
| 2169 |
+
font-style:normal!important;
|
| 2170 |
+
font-size:12px!important;
|
| 2171 |
+
font-weight:900!important;
|
| 2172 |
+
}
|
| 2173 |
+
.prescan-chip em{
|
| 2174 |
+
grid-area:label!important;
|
| 2175 |
+
font-size:8.5px!important;
|
| 2176 |
+
line-height:1!important;
|
| 2177 |
+
letter-spacing:.13em!important;
|
| 2178 |
+
text-transform:uppercase!important;
|
| 2179 |
+
color:#64748b!important;
|
| 2180 |
+
font-style:normal!important;
|
| 2181 |
+
font-weight:850!important;
|
| 2182 |
+
}
|
| 2183 |
+
.prescan-chip strong{
|
| 2184 |
+
grid-area:value!important;
|
| 2185 |
+
min-width:0!important;
|
| 2186 |
+
overflow:hidden!important;
|
| 2187 |
+
text-overflow:ellipsis!important;
|
| 2188 |
+
white-space:nowrap!important;
|
| 2189 |
+
color:#0f172a!important;
|
| 2190 |
+
font-size:11.5px!important;
|
| 2191 |
+
line-height:1.15!important;
|
| 2192 |
+
}
|
| 2193 |
+
.prescan-chip.good{border-color:rgba(34,197,94,.18)!important;background:rgba(240,253,244,.56)!important}
|
| 2194 |
+
.prescan-chip.good i{background:rgba(220,252,231,.95)!important;color:#047857!important}
|
| 2195 |
+
.prescan-pill-row{display:flex!important;flex-wrap:wrap!important;gap:6px!important;min-width:0!important}
|
| 2196 |
+
.prescan-pill{
|
| 2197 |
+
display:inline-flex!important;
|
| 2198 |
+
align-items:center!important;
|
| 2199 |
+
gap:5px!important;
|
| 2200 |
+
max-width:100%!important;
|
| 2201 |
+
padding:5px 8px!important;
|
| 2202 |
+
border-radius:999px!important;
|
| 2203 |
+
border:1px solid rgba(226,232,240,.86)!important;
|
| 2204 |
+
background:rgba(255,255,255,.76)!important;
|
| 2205 |
+
color:#334155!important;
|
| 2206 |
+
font-size:10.75px!important;
|
| 2207 |
+
line-height:1.2!important;
|
| 2208 |
+
white-space:nowrap!important;
|
| 2209 |
+
overflow:hidden!important;
|
| 2210 |
+
text-overflow:ellipsis!important;
|
| 2211 |
+
}
|
| 2212 |
+
.prescan-pill.good{border-color:rgba(34,197,94,.18)!important;background:rgba(240,253,244,.68)!important}
|
| 2213 |
+
.prescan-pill.risk{border-color:rgba(245,158,11,.25)!important;background:rgba(255,251,235,.72)!important}
|
| 2214 |
+
.prescan-pill .prescan-icon{font-weight:900!important;opacity:.8!important}
|
| 2215 |
+
.prescan-recommendation-line{
|
| 2216 |
+
display:flex!important;
|
| 2217 |
+
align-items:center!important;
|
| 2218 |
+
gap:7px!important;
|
| 2219 |
+
padding:7px 9px!important;
|
| 2220 |
+
border-radius:13px!important;
|
| 2221 |
+
border:1px solid rgba(226,232,240,.82)!important;
|
| 2222 |
+
background:rgba(255,255,255,.72)!important;
|
| 2223 |
+
color:#475569!important;
|
| 2224 |
+
font-size:11px!important;
|
| 2225 |
+
line-height:1.25!important;
|
| 2226 |
+
}
|
| 2227 |
+
.prescan-recommendation-line b{color:#0f172a!important;font-size:10px!important;text-transform:uppercase!important;letter-spacing:.11em!important}
|
| 2228 |
+
.model-prescan-card.success #scanModel{padding:7px 10px!important;font-size:11.5px!important;border-radius:12px!important}
|
| 2229 |
+
@media(max-width:720px){.prescan-compact-grid{grid-template-columns:1fr!important}.prescan-pill{white-space:normal!important}}
|
| 2230 |
+
|
| 2231 |
+
/* v185: consistent compact Model pre-scan rendering for all states */
|
| 2232 |
+
.model-prescan-card.required{padding:14px!important;gap:10px!important}
|
| 2233 |
+
.model-prescan-card.required .model-prescan-signals{display:block!important;margin-top:1px!important}
|
| 2234 |
+
.model-prescan-card.running{
|
| 2235 |
+
border-color:rgba(37,99,235,.20)!important;
|
| 2236 |
+
background:radial-gradient(circle at 96% 0%,rgba(59,130,246,.09),transparent 34%),linear-gradient(180deg,rgba(255,255,255,.99),rgba(248,250,252,.94))!important;
|
| 2237 |
+
}
|
| 2238 |
+
.model-prescan-card.warn{
|
| 2239 |
+
border-color:rgba(245,158,11,.22)!important;
|
| 2240 |
+
background:radial-gradient(circle at 96% 0%,rgba(245,158,11,.10),transparent 34%),linear-gradient(180deg,rgba(255,255,255,.99),rgba(255,251,235,.52))!important;
|
| 2241 |
+
}
|
| 2242 |
+
.model-prescan-card.error{
|
| 2243 |
+
border-color:rgba(244,63,94,.20)!important;
|
| 2244 |
+
background:radial-gradient(circle at 96% 0%,rgba(244,63,94,.09),transparent 34%),linear-gradient(180deg,rgba(255,255,255,.99),rgba(255,241,242,.52))!important;
|
| 2245 |
+
}
|
| 2246 |
+
.model-prescan-card.running .model-prescan-head strong,
|
| 2247 |
+
.model-prescan-card.warn .model-prescan-head strong,
|
| 2248 |
+
.model-prescan-card.error .model-prescan-head strong{font-size:15px!important;letter-spacing:-.025em!important}
|
| 2249 |
+
.model-prescan-card.warn .prescan-chip,
|
| 2250 |
+
.model-prescan-card.error .prescan-chip,
|
| 2251 |
+
.model-prescan-card.running .prescan-chip{background:rgba(255,255,255,.78)!important}
|
| 2252 |
+
.prescan-pill.running{border-color:rgba(37,99,235,.18)!important;background:rgba(239,246,255,.72)!important;color:#1e3a8a!important}
|
| 2253 |
+
.prescan-recommendation-line.warn{border-color:rgba(245,158,11,.18)!important;background:rgba(255,251,235,.70)!important}
|
| 2254 |
+
.prescan-recommendation-line.error{border-color:rgba(244,63,94,.18)!important;background:rgba(255,241,242,.70)!important}
|
| 2255 |
+
.prescan-recommendation-line.running{border-color:rgba(37,99,235,.16)!important;background:rgba(239,246,255,.62)!important}
|
| 2256 |
+
.prescan-hints{margin-top:2px!important}
|
| 2257 |
+
.prescan-spinner{display:inline-flex!important;animation:prescan-spin 1.1s linear infinite!important}
|
| 2258 |
+
@keyframes prescan-spin{to{transform:rotate(360deg)}}
|
| 2259 |
+
.model-prescan-card.warn #scanModel,
|
| 2260 |
+
.model-prescan-card.error #scanModel,
|
| 2261 |
+
.model-prescan-card.running #scanModel{padding:7px 10px!important;font-size:11.5px!important;border-radius:12px!important}
|
| 2262 |
+
.model-prescan-card.error #scanModel{border-color:rgba(244,63,94,.18)!important;background:linear-gradient(180deg,#fff,#fff7f7)!important}
|
| 2263 |
+
@media(prefers-reduced-motion:reduce){.prescan-spinner{animation:none!important}}
|
web/static/app.js
CHANGED
|
@@ -229,6 +229,7 @@ function renderAnonymousEvalStatus(me){
|
|
| 229 |
const enable=$('enableEvalArchive');
|
| 230 |
const disable=$('disableEvalArchive');
|
| 231 |
const verify=$('verifyEvalArchive');
|
|
|
|
| 232 |
const cfg=me?.anonymous_eval||{};
|
| 233 |
const enabled=Boolean(cfg.enabled);
|
| 234 |
const canManage=Boolean(cfg.can_manage)&&cfg.env_override!==true;
|
|
@@ -238,16 +239,20 @@ function renderAnonymousEvalStatus(me){
|
|
| 238 |
const mount=cfg.job_mount_path||cfg.default_mount_path||'/evals';
|
| 239 |
if(card){
|
| 240 |
card.hidden=false;
|
| 241 |
-
card.className='eval-archive-
|
| 242 |
}
|
| 243 |
if(title){
|
| 244 |
-
title.textContent=enabled?'Anonymous eval archive
|
|
|
|
|
|
|
|
|
|
|
|
|
| 245 |
}
|
| 246 |
if(text){
|
| 247 |
text.className='eval-feedback '+(enabled?'on':'off');
|
| 248 |
if(enabled){
|
| 249 |
const manager=cfg.managed_by==='you'?'You manage this instance setting.':`Managed by ${cfg.managed_by||'instance owner'}.`;
|
| 250 |
-
text.textContent=`${bucket}${path} → ${mount}`;
|
| 251 |
text.title=`Anonymous project eval archive enabled from ${cfg.source||'config'}: ${bucket}${path} mounted at ${mount}. ${manager} ASF backend publishes anonymized eval records after user Jobs write local run evals.`;
|
| 252 |
}else if(me?.username){
|
| 253 |
text.textContent='Mount an operator eval bucket at /evals, then enable publishing.';
|
|
@@ -299,31 +304,45 @@ function renderModelPreScan(scan=null){
|
|
| 299 |
const card=$('modelPreScanCard'),badge=$('modelPreScanBadge'),signals=$('modelPreScanSignals'),ackWrap=$('modelRiskAckWrap');
|
| 300 |
if(!card)return;
|
| 301 |
const current=normalizeModelInput(formValue('modelId'));
|
| 302 |
-
const
|
|
|
|
| 303 |
if(!scan||!matches){
|
| 304 |
card.className='model-prescan-card required';
|
| 305 |
setText('modelPreScanTitle','Pre-scan required');
|
| 306 |
-
setText('modelPreScanSummary','Run a fast metadata scan before launching a paid Job. It checks
|
| 307 |
if(badge){badge.textContent='Required';badge.className='badge neutral'}
|
| 308 |
-
if(signals){signals.hidden=
|
| 309 |
if(ackWrap)ackWrap.hidden=true;
|
| 310 |
return;
|
| 311 |
}
|
| 312 |
const verdict=String(scan.verdict||'caution').toLowerCase();
|
| 313 |
const cls=scanVerdictClass(verdict);
|
|
|
|
| 314 |
card.className='model-prescan-card '+cls;
|
| 315 |
-
|
|
|
|
| 316 |
setText('modelPreScanSummary',scan.summary||'Model metadata scan completed.');
|
| 317 |
-
if(badge){badge.textContent=verdict;badge.className='badge '+cls}
|
| 318 |
-
const good=(scan.good_signals||[]).slice(0,
|
| 319 |
const risk=(scan.risk_signals||[]).slice(0,4);
|
| 320 |
const outputType=outputTypeFromModelScan(scan);
|
| 321 |
const recs=[...(scan.recommendations||[]).slice(0,2)];
|
| 322 |
-
if(outputType)recs.unshift(`Expected output: ${outputType}`);
|
| 323 |
if(signals){
|
| 324 |
-
const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 325 |
signals.hidden=false;
|
| 326 |
-
signals.innerHTML=`
|
| 327 |
}
|
| 328 |
if(ackWrap)ackWrap.hidden=!(verdict==='risky');
|
| 329 |
}
|
|
@@ -333,9 +352,7 @@ async function scanModel(){
|
|
| 333 |
const model=formValue('modelId');
|
| 334 |
if(!model){showMessage('Enter a model card URL or model ID before scanning.',true);return}
|
| 335 |
setButtonBusy('scanModel',true,'Scanning…');
|
| 336 |
-
|
| 337 |
-
setText('modelPreScanTitle','Scanning model metadata…');
|
| 338 |
-
setText('modelPreScanSummary','Reading the model card, Hub metadata and small config files. We do not download model weights.');
|
| 339 |
try{
|
| 340 |
const result=await apiPost('/api/models/pre-scan',{model_id:model});
|
| 341 |
state.modelScan=result;
|
|
@@ -344,7 +361,7 @@ async function scanModel(){
|
|
| 344 |
renderModelPreScan(result);
|
| 345 |
setBuildLaunchEnabled();
|
| 346 |
showMessage(`Model pre-scan: ${result.verdict} (${result.score}/100)`,result.verdict==='safe'?'success':(result.verdict==='unsupported'||result.verdict==='risky'?true:'warning'));
|
| 347 |
-
}catch(e){state.modelScan=null;renderModelPreScan(
|
| 348 |
finally{setButtonBusy('scanModel',false);setBuildLaunchEnabled()}
|
| 349 |
}
|
| 350 |
|
|
|
|
| 229 |
const enable=$('enableEvalArchive');
|
| 230 |
const disable=$('disableEvalArchive');
|
| 231 |
const verify=$('verifyEvalArchive');
|
| 232 |
+
const stateBadge=$('evalArchiveStateBadge');
|
| 233 |
const cfg=me?.anonymous_eval||{};
|
| 234 |
const enabled=Boolean(cfg.enabled);
|
| 235 |
const canManage=Boolean(cfg.can_manage)&&cfg.env_override!==true;
|
|
|
|
| 239 |
const mount=cfg.job_mount_path||cfg.default_mount_path||'/evals';
|
| 240 |
if(card){
|
| 241 |
card.hidden=false;
|
| 242 |
+
card.className='eval-archive-panel '+(enabled?'on':'off')+(readonly?' readonly':'')+(canManage?' manageable':'');
|
| 243 |
}
|
| 244 |
if(title){
|
| 245 |
+
title.textContent=enabled?'Anonymous eval archive':'Anonymous eval archive';
|
| 246 |
+
}
|
| 247 |
+
if(stateBadge){
|
| 248 |
+
stateBadge.textContent=enabled?'On':'Off';
|
| 249 |
+
stateBadge.className='badge '+(enabled?'success':'neutral');
|
| 250 |
}
|
| 251 |
if(text){
|
| 252 |
text.className='eval-feedback '+(enabled?'on':'off');
|
| 253 |
if(enabled){
|
| 254 |
const manager=cfg.managed_by==='you'?'You manage this instance setting.':`Managed by ${cfg.managed_by||'instance owner'}.`;
|
| 255 |
+
text.textContent=`On · ${bucket}${path} → ${mount}`;
|
| 256 |
text.title=`Anonymous project eval archive enabled from ${cfg.source||'config'}: ${bucket}${path} mounted at ${mount}. ${manager} ASF backend publishes anonymized eval records after user Jobs write local run evals.`;
|
| 257 |
}else if(me?.username){
|
| 258 |
text.textContent='Mount an operator eval bucket at /evals, then enable publishing.';
|
|
|
|
| 304 |
const card=$('modelPreScanCard'),badge=$('modelPreScanBadge'),signals=$('modelPreScanSignals'),ackWrap=$('modelRiskAckWrap');
|
| 305 |
if(!card)return;
|
| 306 |
const current=normalizeModelInput(formValue('modelId'));
|
| 307 |
+
const isTransient=scan&&scan.transient===true;
|
| 308 |
+
const matches=scan&&((scan.ok&&normalizeModelInput(scan.model_id)===current)||isTransient);
|
| 309 |
if(!scan||!matches){
|
| 310 |
card.className='model-prescan-card required';
|
| 311 |
setText('modelPreScanTitle','Pre-scan required');
|
| 312 |
+
setText('modelPreScanSummary','Run a fast metadata scan before launching a paid Job. It checks model card guidance, runnable examples, Diffusers signals, files, safetensors, gated access and custom-code risk without downloading weights.');
|
| 313 |
if(badge){badge.textContent='Required';badge.className='badge neutral'}
|
| 314 |
+
if(signals){signals.hidden=false;signals.innerHTML='<div class="prescan-pill-row prescan-hints"><span class="prescan-pill"><b class="prescan-icon">↗</b>Metadata only</span><span class="prescan-pill"><b class="prescan-icon">◇</b>No weight download</span><span class="prescan-pill"><b class="prescan-icon">✓</b>Required before Job</span></div>'}
|
| 315 |
if(ackWrap)ackWrap.hidden=true;
|
| 316 |
return;
|
| 317 |
}
|
| 318 |
const verdict=String(scan.verdict||'caution').toLowerCase();
|
| 319 |
const cls=scanVerdictClass(verdict);
|
| 320 |
+
const labelMap={safe:'Safe',caution:'Needs review',risky:'Risky',unsupported:'Unsupported',scanning:'Scanning',error:'Scan failed'};
|
| 321 |
card.className='model-prescan-card '+cls;
|
| 322 |
+
const scoreText=(scan.score===undefined||scan.score===null||verdict==='scanning'||verdict==='error')?'':` · score ${scan.score}/100`;
|
| 323 |
+
setText('modelPreScanTitle',`${labelMap[verdict]||labelMap.caution}${scoreText}`);
|
| 324 |
setText('modelPreScanSummary',scan.summary||'Model metadata scan completed.');
|
| 325 |
+
if(badge){badge.textContent=labelMap[verdict]||verdict;badge.className='badge '+cls}
|
| 326 |
+
const good=(scan.good_signals||[]).slice(0,4);
|
| 327 |
const risk=(scan.risk_signals||[]).slice(0,4);
|
| 328 |
const outputType=outputTypeFromModelScan(scan);
|
| 329 |
const recs=[...(scan.recommendations||[]).slice(0,2)];
|
| 330 |
+
if(outputType&&!recs.some(x=>String(x).toLowerCase().includes('expected output')))recs.unshift(`Expected output: ${outputType}`);
|
| 331 |
if(signals){
|
| 332 |
+
const metaCards=[
|
| 333 |
+
outputType?['↳','Output',outputType,verdict==='safe']:null,
|
| 334 |
+
scan.pipeline_tag?['◈','Pipeline',scan.pipeline_tag,false]:null,
|
| 335 |
+
scan.library_name?['◎','Library',scan.library_name,false]:null,
|
| 336 |
+
].filter(Boolean).slice(0,3);
|
| 337 |
+
const compactMeta=metaCards.length?`<div class="prescan-meta prescan-compact-grid">${metaCards.map(([icon,k,v,isGood])=>`<span class="prescan-chip ${isGood?'good':''}"><i>${escapeHtml(icon)}</i><em>${escapeHtml(k)}</em><strong>${escapeHtml(String(v))}</strong></span>`).join('')}</div>`:'';
|
| 338 |
+
const goodPills=good.length?`<div class="prescan-pill-row">${good.map(x=>`<span class="prescan-pill good"><b class="prescan-icon">✓</b>${escapeHtml(x)}</span>`).join('')}</div>`:'';
|
| 339 |
+
const riskPills=risk.length?`<div class="prescan-pill-row">${risk.map(x=>`<span class="prescan-pill risk"><b class="prescan-icon">!</b>${escapeHtml(x)}</span>`).join('')}</div>`:'';
|
| 340 |
+
const runningPills=verdict==='scanning'?'<div class="prescan-pill-row"><span class="prescan-pill running"><b class="prescan-icon prescan-spinner">◌</b>Reading model card</span><span class="prescan-pill running"><b class="prescan-icon">◇</b>Checking metadata</span></div>':'';
|
| 341 |
+
const errorPill=verdict==='error'?`<div class="prescan-pill-row"><span class="prescan-pill risk"><b class="prescan-icon">!</b>${escapeHtml(scan.error||'The scan could not complete. Try again.')}</span></div>`:'';
|
| 342 |
+
const recLine=recs.length?`<div class="prescan-recommendation-line ${cls}"><b>Recommendation</b><span>${escapeHtml(recs[0])}${recs.length>1?` · ${escapeHtml(recs.slice(1).join(' · '))}`:''}</span></div>`:'';
|
| 343 |
+
const emptyHint=(!compactMeta&&!goodPills&&!riskPills&&!runningPills&&!errorPill&&!recLine)?'<div class="prescan-pill-row"><span class="prescan-pill"><b class="prescan-icon">◇</b>No extra metadata found.</span></div>':'';
|
| 344 |
signals.hidden=false;
|
| 345 |
+
signals.innerHTML=`${compactMeta}${runningPills}${goodPills}${riskPills}${errorPill}${recLine}${emptyHint}`;
|
| 346 |
}
|
| 347 |
if(ackWrap)ackWrap.hidden=!(verdict==='risky');
|
| 348 |
}
|
|
|
|
| 352 |
const model=formValue('modelId');
|
| 353 |
if(!model){showMessage('Enter a model card URL or model ID before scanning.',true);return}
|
| 354 |
setButtonBusy('scanModel',true,'Scanning…');
|
| 355 |
+
renderModelPreScan({ok:true,transient:true,model_id:model,verdict:'scanning',summary:'Reading the model card, Hub metadata and small config files. We do not download model weights.'});
|
|
|
|
|
|
|
| 356 |
try{
|
| 357 |
const result=await apiPost('/api/models/pre-scan',{model_id:model});
|
| 358 |
state.modelScan=result;
|
|
|
|
| 361 |
renderModelPreScan(result);
|
| 362 |
setBuildLaunchEnabled();
|
| 363 |
showMessage(`Model pre-scan: ${result.verdict} (${result.score}/100)`,result.verdict==='safe'?'success':(result.verdict==='unsupported'||result.verdict==='risky'?true:'warning'));
|
| 364 |
+
}catch(e){state.modelScan=null;renderModelPreScan({ok:true,transient:true,model_id:model,verdict:'error',summary:'The model pre-scan could not complete. Fix the issue or try again before launching a Job.',error:e.message});showMessage(e.message,true)}
|
| 365 |
finally{setButtonBusy('scanModel',false);setBuildLaunchEnabled()}
|
| 366 |
}
|
| 367 |
|