Spaces:
Running
Running
sync: 157 file da Baida98/AI@5bb711cb (2026-08-15 12:51 UTC) [deploy-all]
Browse files- api/benchmark_handler.py +20 -3
- benchmark-extended.mjs +38 -20
api/benchmark_handler.py
CHANGED
|
@@ -145,24 +145,41 @@ def _format_v7_report(report: dict[str, Any]) -> str:
|
|
| 145 |
if canary:
|
| 146 |
lines.append(f"β οΈ <b>Canary leak:</b> {canary} task\n")
|
| 147 |
|
| 148 |
-
# Score per categoria
|
|
|
|
| 149 |
tasks = report.get("tasks", [])
|
| 150 |
if tasks:
|
|
|
|
| 151 |
by_cat: dict[str, list[float]] = {}
|
| 152 |
for t in tasks:
|
| 153 |
cat = t.get("cat", "?")
|
| 154 |
sc = t.get("score")
|
| 155 |
if isinstance(sc, (int, float)):
|
| 156 |
by_cat.setdefault(cat, []).append(float(sc))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
if by_cat:
|
| 158 |
-
coverage = len(by_cat)
|
| 159 |
-
lines.append(f"π§ͺ <b>Copertura:</b> <code>{coverage}/20 categorie Β· {len(tasks)} task</code>\n")
|
| 160 |
lines.append("\nπ <b>Per categoria:</b>\n")
|
| 161 |
for cat, scores in sorted(by_cat.items()):
|
| 162 |
avg_cat = sum(scores) / len(scores)
|
| 163 |
icon = "π’" if avg_cat >= 70 else "π‘" if avg_cat >= 50 else "π΄"
|
| 164 |
lines.append(f" {icon} <code>{avg_cat:5.1f}</code> {cat}\n")
|
| 165 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 166 |
# Gap cards (prime 3)
|
| 167 |
gap_cards = report.get("gapCards", [])
|
| 168 |
if gap_cards:
|
|
|
|
| 145 |
if canary:
|
| 146 |
lines.append(f"β οΈ <b>Canary leak:</b> {canary} task\n")
|
| 147 |
|
| 148 |
+
# Score per categoria. Una categoria in timeout resta tentata ma non entra
|
| 149 |
+
# nella media: non va trasformata silenziosamente in uno score pari a zero.
|
| 150 |
tasks = report.get("tasks", [])
|
| 151 |
if tasks:
|
| 152 |
+
attempted_categories = {str(t.get("cat")) for t in tasks if t.get("cat")}
|
| 153 |
by_cat: dict[str, list[float]] = {}
|
| 154 |
for t in tasks:
|
| 155 |
cat = t.get("cat", "?")
|
| 156 |
sc = t.get("score")
|
| 157 |
if isinstance(sc, (int, float)):
|
| 158 |
by_cat.setdefault(cat, []).append(float(sc))
|
| 159 |
+
attempted = s.get("attemptedTaskCount", len(tasks))
|
| 160 |
+
scored = s.get("scoredTaskCount", sum(len(v) for v in by_cat.values()))
|
| 161 |
+
skipped = s.get("skippedTaskCount", max(0, attempted - scored))
|
| 162 |
+
lines.append(
|
| 163 |
+
f"π§ͺ <b>Copertura:</b> <code>{len(attempted_categories)}/20 categorie tentate Β· "
|
| 164 |
+
f"{scored} valutabili Β· {skipped} non valutabili</code>\n"
|
| 165 |
+
)
|
| 166 |
if by_cat:
|
|
|
|
|
|
|
| 167 |
lines.append("\nπ <b>Per categoria:</b>\n")
|
| 168 |
for cat, scores in sorted(by_cat.items()):
|
| 169 |
avg_cat = sum(scores) / len(scores)
|
| 170 |
icon = "π’" if avg_cat >= 70 else "π‘" if avg_cat >= 50 else "π΄"
|
| 171 |
lines.append(f" {icon} <code>{avg_cat:5.1f}</code> {cat}\n")
|
| 172 |
|
| 173 |
+
failures = report.get("taskFailures", [])
|
| 174 |
+
if failures:
|
| 175 |
+
lines.append("\nβ οΈ <b>Categorie non valutabili:</b>\n")
|
| 176 |
+
for failure in failures[:3]:
|
| 177 |
+
cat = failure.get("cat", "?")
|
| 178 |
+
reason = str(failure.get("reason", "errore non specificato"))[:100]
|
| 179 |
+
lines.append(f" β’ <code>{cat}</code> β {reason}\n")
|
| 180 |
+
if len(failures) > 3:
|
| 181 |
+
lines.append(f" <i>...e altre {len(failures) - 3}.</i>\n")
|
| 182 |
+
|
| 183 |
# Gap cards (prime 3)
|
| 184 |
gap_cards = report.get("gapCards", [])
|
| 185 |
if gap_cards:
|
benchmark-extended.mjs
CHANGED
|
@@ -2042,6 +2042,7 @@ async function runOneSeed(seed,opts={}){
|
|
| 2042 |
try{spaceV=(await fetch(`${BASE_URL}/api/state/health`).then(r=>r.json())).version??"";}catch{}
|
| 2043 |
|
| 2044 |
const results=[];
|
|
|
|
| 2045 |
for(let i=0;i<n;i++){
|
| 2046 |
const task=selected[i];
|
| 2047 |
const isNC=!!task.isNonCoding,isAG=!!task.isAgentic;
|
|
@@ -2055,7 +2056,17 @@ async function runOneSeed(seed,opts={}){
|
|
| 2055 |
const agent=await callAgentWithRetry(task,Math.max(task.targetMs||65000,180000));
|
| 2056 |
const agentMs=Date.now()-t0;
|
| 2057 |
if(agent.failed){
|
| 2058 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2059 |
}
|
| 2060 |
|
| 2061 |
let vr;
|
|
@@ -2098,30 +2109,35 @@ async function runOneSeed(seed,opts={}){
|
|
| 2098 |
|
| 2099 |
// ββ Summary ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 2100 |
const avg =r=>r.length?+(r.reduce((a,b)=>a+b,0)/r.length).toFixed(1):null;
|
| 2101 |
-
const
|
|
|
|
| 2102 |
const avgS=avg(scores);
|
| 2103 |
-
const avgR=avg(
|
| 2104 |
-
const avgC=avg(
|
| 2105 |
-
const avgD=avg(
|
| 2106 |
-
const avgM=avg(
|
| 2107 |
-
const wins_r=
|
| 2108 |
-
const wins_d=
|
| 2109 |
-
const wins_m=
|
| 2110 |
-
const mft =avg(
|
| 2111 |
-
const tools =avg(
|
| 2112 |
-
const hfUsed=
|
| 2113 |
|
| 2114 |
_log(`\n${BOLD}${"β".repeat(78)}${NC}`);
|
| 2115 |
_log(`${DIM} ${`Categoria`.padEnd(19)} ${`AI`.padEnd(6)} ${`Replit`.padEnd(7)} ${`Cursor`.padEnd(7)} ${`Devin`.padEnd(7)} ${`Manus`.padEnd(7)} Ξ${NC}`);
|
| 2116 |
for(const r of results){
|
| 2117 |
-
const dc=r.score>=r.ref.manus?G:r.score>=r.ref.devin?G:r.score>=r.ref.replit?Y:R;
|
| 2118 |
const tag=r.isAgentic?`${M}[AG]${NC}`:r.isNonCoding?`${C}[NC]${NC}`:`${Y}[C] ${NC}`;
|
| 2119 |
const hf=r.hfSource&&!r.hfSource.startsWith("local")?`${B}*${NC}`:" ";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2120 |
_log(` ${tag}${hf}${r.cat.padEnd(17)} ${dc}${String(r.score).padEnd(6)}${NC}${String(r.ref.replit).padEnd(7)}${String(r.ref.cursor).padEnd(7)}${String(r.ref.devin).padEnd(7)}${String(r.ref.manus).padEnd(7)}${dc}${r.score-r.ref.replit>=0?"+":""}${r.score-r.ref.replit}${NC}`);
|
| 2121 |
}
|
| 2122 |
|
| 2123 |
// Gap analysis
|
| 2124 |
-
const gaps=
|
| 2125 |
.filter(r=>r.score<r.ref.replit)
|
| 2126 |
.map(r=>buildGapCard(selected.find(t=>t.id===r.id&&t.category===r.cat),r,r.score,r.ref))
|
| 2127 |
.sort((a,b)=>a.priorita-b.priorita);
|
|
@@ -2135,13 +2151,14 @@ async function runOneSeed(seed,opts={}){
|
|
| 2135 |
}
|
| 2136 |
}
|
| 2137 |
|
| 2138 |
-
const nodeMap=buildNodeMap(
|
| 2139 |
-
const verdict=avgS>=avgM?"SUPERA_MANUS":avgS>=avgD?"SUPERA_DEVIN":avgS>=avgR?"PARI_REPLIT":"SOTTO_REPLIT";
|
| 2140 |
-
const vc=avgS>=avgM?G:avgS>=avgD?G:avgS>=avgR?Y:R;
|
| 2141 |
|
| 2142 |
_log(`\n${BOLD}${"β".repeat(78)}${NC}`);
|
| 2143 |
-
_log(` ${BOLD}AI Agent: ${vc}${avgS}/100${NC} vs Replit:${wins_r}/${
|
| 2144 |
_log(` ${DIM}Refs β Replit:${avgR} Cursor:${avgC} Devin:${avgD} Manus:${avgM}${NC}`);
|
|
|
|
| 2145 |
_log(` ${BOLD}HF tasks: ${hfUsed}/${n} reali mft:${mft}s tools:${tools}${NC}`);
|
| 2146 |
_log(` ${BOLD}Gap cards: ${gaps.length} task sotto Replit${NC}`);
|
| 2147 |
_log(` ${BOLD}Verdetto: ${vc}${verdict.replace(/_/g," ")}${NC}`);
|
|
@@ -2169,13 +2186,14 @@ async function runOneSeed(seed,opts={}){
|
|
| 2169 |
},
|
| 2170 |
summary:{avgScore:avgS,avgReplit:avgR,avgCursor:avgC,avgDevin:avgD,avgManus:avgM,
|
| 2171 |
wins_replit:wins_r,wins_devin:wins_d,wins_manus:wins_m,
|
|
|
|
| 2172 |
mft,hfTasksUsed:hfUsed,gapCount:gaps.length,verdict},
|
| 2173 |
-
gapCards:gaps,orchestrationNodeMap:nodeMap,tasks:results,
|
| 2174 |
};
|
| 2175 |
wsf(reportPath,JSON.stringify(report,null,2));
|
| 2176 |
_log(`${DIM}β Report: ${reportPath}${NC}`);
|
| 2177 |
if(F_JSON||OUTFILE){wsf(OUTFILE??"/tmp/agente-ai/benchmark-v5-latest.json",JSON.stringify(report,null,2));}
|
| 2178 |
-
return{seed,avgScore:avgS,avgReplit:avgR,avgDevin:avgD,avgManus:avgM,wins_r,wins_d,wins_m,mft,gaps,tasks:results,selectedTasks:selected};
|
| 2179 |
}
|
| 2180 |
|
| 2181 |
// ββ Compare mode con CI95 per categoria βββββββββββββββββββββββββββββββββββββββ
|
|
|
|
| 2042 |
try{spaceV=(await fetch(`${BASE_URL}/api/state/health`).then(r=>r.json())).version??"";}catch{}
|
| 2043 |
|
| 2044 |
const results=[];
|
| 2045 |
+
const taskFailures=[];
|
| 2046 |
for(let i=0;i<n;i++){
|
| 2047 |
const task=selected[i];
|
| 2048 |
const isNC=!!task.isNonCoding,isAG=!!task.isAgentic;
|
|
|
|
| 2056 |
const agent=await callAgentWithRetry(task,Math.max(task.targetMs||65000,180000));
|
| 2057 |
const agentMs=Date.now()-t0;
|
| 2058 |
if(agent.failed){
|
| 2059 |
+
const reason=String(agent.failureReason||"errore sconosciuto").slice(0,240);
|
| 2060 |
+
taskFailures.push({id:task.id,cat:task.category,label:task.label.slice(0,60),reason,agentMs});
|
| 2061 |
+
_log(` ${Y}N/A ${NC} ${DIM}categoria non valutabile: ${reason.slice(0,80)} β continuo con le restanti${NC}`);
|
| 2062 |
+
results.push({id:task.id,cat:task.category,label:task.label.slice(0,60),
|
| 2063 |
+
isCoding:!!task.isCoding,isNonCoding:isNC,isAgentic:isAG,
|
| 2064 |
+
hfSource:task.hfSource||"local",hfOffset:task.hfOffset??null,
|
| 2065 |
+
score:null,ref:task.ref,buildPassed:null,testsPassed:null,
|
| 2066 |
+
planScore:null,executionScore:null,recoveryScore:null,autonomyScore:null,
|
| 2067 |
+
agentMs,ttfa:agent.ttfa??9999,toolCalls:agent.toolCalls??0,tokEstimate:0,
|
| 2068 |
+
engine:agent.engine,breakdown:null,detail:`non valutabile: ${reason}`,unavailable:true,failureReason:reason});
|
| 2069 |
+
continue;
|
| 2070 |
}
|
| 2071 |
|
| 2072 |
let vr;
|
|
|
|
| 2109 |
|
| 2110 |
// ββ Summary ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 2111 |
const avg =r=>r.length?+(r.reduce((a,b)=>a+b,0)/r.length).toFixed(1):null;
|
| 2112 |
+
const scoredResults=results.filter(r=>typeof r.score==="number"&&Number.isFinite(r.score));
|
| 2113 |
+
const scores=scoredResults.map(r=>r.score);
|
| 2114 |
const avgS=avg(scores);
|
| 2115 |
+
const avgR=avg(scoredResults.map(r=>r.ref.replit));
|
| 2116 |
+
const avgC=avg(scoredResults.map(r=>r.ref.cursor));
|
| 2117 |
+
const avgD=avg(scoredResults.map(r=>r.ref.devin));
|
| 2118 |
+
const avgM=avg(scoredResults.map(r=>r.ref.manus));
|
| 2119 |
+
const wins_r=scoredResults.filter(r=>r.score>=r.ref.replit).length;
|
| 2120 |
+
const wins_d=scoredResults.filter(r=>r.score>=r.ref.devin).length;
|
| 2121 |
+
const wins_m=scoredResults.filter(r=>r.score>=r.ref.manus).length;
|
| 2122 |
+
const mft =avg(scoredResults.map(r=>r.agentMs/1000));
|
| 2123 |
+
const tools =avg(scoredResults.map(r=>r.toolCalls));
|
| 2124 |
+
const hfUsed=scoredResults.filter(r=>r.hfSource&&!r.hfSource.startsWith("local")).length;
|
| 2125 |
|
| 2126 |
_log(`\n${BOLD}${"β".repeat(78)}${NC}`);
|
| 2127 |
_log(`${DIM} ${`Categoria`.padEnd(19)} ${`AI`.padEnd(6)} ${`Replit`.padEnd(7)} ${`Cursor`.padEnd(7)} ${`Devin`.padEnd(7)} ${`Manus`.padEnd(7)} Ξ${NC}`);
|
| 2128 |
for(const r of results){
|
|
|
|
| 2129 |
const tag=r.isAgentic?`${M}[AG]${NC}`:r.isNonCoding?`${C}[NC]${NC}`:`${Y}[C] ${NC}`;
|
| 2130 |
const hf=r.hfSource&&!r.hfSource.startsWith("local")?`${B}*${NC}`:" ";
|
| 2131 |
+
if(typeof r.score!=="number"){
|
| 2132 |
+
_log(` ${tag}${hf}${r.cat.padEnd(17)} ${Y}N/A ${NC}${DIM}non valutabile: ${(r.failureReason||"errore").slice(0,42)}${NC}`);
|
| 2133 |
+
continue;
|
| 2134 |
+
}
|
| 2135 |
+
const dc=r.score>=r.ref.manus?G:r.score>=r.ref.devin?G:r.score>=r.ref.replit?Y:R;
|
| 2136 |
_log(` ${tag}${hf}${r.cat.padEnd(17)} ${dc}${String(r.score).padEnd(6)}${NC}${String(r.ref.replit).padEnd(7)}${String(r.ref.cursor).padEnd(7)}${String(r.ref.devin).padEnd(7)}${String(r.ref.manus).padEnd(7)}${dc}${r.score-r.ref.replit>=0?"+":""}${r.score-r.ref.replit}${NC}`);
|
| 2137 |
}
|
| 2138 |
|
| 2139 |
// Gap analysis
|
| 2140 |
+
const gaps=scoredResults
|
| 2141 |
.filter(r=>r.score<r.ref.replit)
|
| 2142 |
.map(r=>buildGapCard(selected.find(t=>t.id===r.id&&t.category===r.cat),r,r.score,r.ref))
|
| 2143 |
.sort((a,b)=>a.priorita-b.priorita);
|
|
|
|
| 2151 |
}
|
| 2152 |
}
|
| 2153 |
|
| 2154 |
+
const nodeMap=buildNodeMap(scoredResults);
|
| 2155 |
+
const verdict=avgS===null?"NON_VALUTABILE":avgS>=avgM?"SUPERA_MANUS":avgS>=avgD?"SUPERA_DEVIN":avgS>=avgR?"PARI_REPLIT":"SOTTO_REPLIT";
|
| 2156 |
+
const vc=avgS===null?Y:avgS>=avgM?G:avgS>=avgD?G:avgS>=avgR?Y:R;
|
| 2157 |
|
| 2158 |
_log(`\n${BOLD}${"β".repeat(78)}${NC}`);
|
| 2159 |
+
_log(` ${BOLD}AI Agent: ${vc}${avgS??"N/A"}/100${NC} vs Replit:${wins_r}/${scoredResults.length} vs Devin:${wins_d}/${scoredResults.length} vs Manus:${wins_m}/${scoredResults.length}`);
|
| 2160 |
_log(` ${DIM}Refs β Replit:${avgR} Cursor:${avgC} Devin:${avgD} Manus:${avgM}${NC}`);
|
| 2161 |
+
if(taskFailures.length)_log(` ${Y}Categorie non valutabili: ${taskFailures.length}/${n}${NC}`);
|
| 2162 |
_log(` ${BOLD}HF tasks: ${hfUsed}/${n} reali mft:${mft}s tools:${tools}${NC}`);
|
| 2163 |
_log(` ${BOLD}Gap cards: ${gaps.length} task sotto Replit${NC}`);
|
| 2164 |
_log(` ${BOLD}Verdetto: ${vc}${verdict.replace(/_/g," ")}${NC}`);
|
|
|
|
| 2186 |
},
|
| 2187 |
summary:{avgScore:avgS,avgReplit:avgR,avgCursor:avgC,avgDevin:avgD,avgManus:avgM,
|
| 2188 |
wins_replit:wins_r,wins_devin:wins_d,wins_manus:wins_m,
|
| 2189 |
+
attemptedTaskCount:n,scoredTaskCount:scoredResults.length,skippedTaskCount:taskFailures.length,
|
| 2190 |
mft,hfTasksUsed:hfUsed,gapCount:gaps.length,verdict},
|
| 2191 |
+
taskFailures,gapCards:gaps,orchestrationNodeMap:nodeMap,tasks:results,
|
| 2192 |
};
|
| 2193 |
wsf(reportPath,JSON.stringify(report,null,2));
|
| 2194 |
_log(`${DIM}β Report: ${reportPath}${NC}`);
|
| 2195 |
if(F_JSON||OUTFILE){wsf(OUTFILE??"/tmp/agente-ai/benchmark-v5-latest.json",JSON.stringify(report,null,2));}
|
| 2196 |
+
return{seed,avgScore:avgS,avgReplit:avgR,avgDevin:avgD,avgManus:avgM,wins_r,wins_d,wins_m,mft,gaps,taskFailures,tasks:results,selectedTasks:selected};
|
| 2197 |
}
|
| 2198 |
|
| 2199 |
// ββ Compare mode con CI95 per categoria βββββββββββββββββββββββββββββββββββββββ
|