mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-12 21:03:05 -07:00
Run evals for all models. (#17123)
This commit is contained in:
committed by
GitHub
parent
8605d0d024
commit
c43b04b44c
@@ -22,6 +22,12 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
|
model:
|
||||||
|
- 'gemini-3-pro-preview'
|
||||||
|
- 'gemini-3-flash-preview'
|
||||||
|
- 'gemini-2.5-pro'
|
||||||
|
- 'gemini-2.5-flash'
|
||||||
|
- 'gemini-2.5-flash-lite'
|
||||||
run_attempt: [1, 2, 3]
|
run_attempt: [1, 2, 3]
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout'
|
- name: 'Checkout'
|
||||||
@@ -45,6 +51,7 @@ jobs:
|
|||||||
- name: 'Run Evals'
|
- name: 'Run Evals'
|
||||||
env:
|
env:
|
||||||
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
|
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
|
||||||
|
GEMINI_MODEL: '${{ matrix.model }}'
|
||||||
RUN_EVALS: "${{ github.event.inputs.run_all != 'false' }}"
|
RUN_EVALS: "${{ github.event.inputs.run_all != 'false' }}"
|
||||||
run: 'npm run test:all_evals'
|
run: 'npm run test:all_evals'
|
||||||
|
|
||||||
@@ -52,7 +59,7 @@ jobs:
|
|||||||
if: 'always()'
|
if: 'always()'
|
||||||
uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4
|
uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: 'eval-logs-${{ matrix.run_attempt }}'
|
name: 'eval-logs-${{ matrix.model }}-${{ matrix.run_attempt }}'
|
||||||
path: 'evals/logs'
|
path: 'evals/logs'
|
||||||
retention-days: 7
|
retention-days: 7
|
||||||
|
|
||||||
|
|||||||
+49
-15
@@ -32,11 +32,33 @@ function findReports(dir) {
|
|||||||
return reports;
|
return reports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getModelFromPath(reportPath) {
|
||||||
|
const parts = reportPath.split(path.sep);
|
||||||
|
// Find the part that starts with 'eval-logs-'
|
||||||
|
const artifactDir = parts.find((p) => p.startsWith('eval-logs-'));
|
||||||
|
if (!artifactDir) return 'unknown';
|
||||||
|
|
||||||
|
const matchNew = artifactDir.match(/^eval-logs-(.+)-(\d+)$/);
|
||||||
|
if (matchNew) return matchNew[1];
|
||||||
|
|
||||||
|
const matchOld = artifactDir.match(/^eval-logs-(\d+)$/);
|
||||||
|
if (matchOld) return 'gemini-2.5-pro'; // Legacy default
|
||||||
|
|
||||||
|
return 'unknown';
|
||||||
|
}
|
||||||
|
|
||||||
function getStats(reports) {
|
function getStats(reports) {
|
||||||
const testStats = {};
|
// Structure: { [model]: { [testName]: { passed, failed, total } } }
|
||||||
|
const statsByModel = {};
|
||||||
|
|
||||||
for (const reportPath of reports) {
|
for (const reportPath of reports) {
|
||||||
try {
|
try {
|
||||||
|
const model = getModelFromPath(reportPath);
|
||||||
|
if (!statsByModel[model]) {
|
||||||
|
statsByModel[model] = {};
|
||||||
|
}
|
||||||
|
const testStats = statsByModel[model];
|
||||||
|
|
||||||
const content = fs.readFileSync(reportPath, 'utf-8');
|
const content = fs.readFileSync(reportPath, 'utf-8');
|
||||||
const json = JSON.parse(content);
|
const json = JSON.parse(content);
|
||||||
|
|
||||||
@@ -58,7 +80,7 @@ function getStats(reports) {
|
|||||||
console.error(`Error processing report at ${reportPath}:`, error);
|
console.error(`Error processing report at ${reportPath}:`, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return testStats;
|
return statsByModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchHistoricalData() {
|
function fetchHistoricalData() {
|
||||||
@@ -92,7 +114,7 @@ function fetchHistoricalData() {
|
|||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
// Download report.json files.
|
// Download report.json files.
|
||||||
// The artifacts are named 'eval-logs-X'.
|
// The artifacts are named 'eval-logs-X' or 'eval-logs-MODEL-X'.
|
||||||
// We use -p to match pattern.
|
// We use -p to match pattern.
|
||||||
execSync(
|
execSync(
|
||||||
`gh run download ${run.databaseId} -p "eval-logs-*" -D "${tmpDir}"`,
|
`gh run download ${run.databaseId} -p "eval-logs-*" -D "${tmpDir}"`,
|
||||||
@@ -103,7 +125,7 @@ function fetchHistoricalData() {
|
|||||||
if (runReports.length > 0) {
|
if (runReports.length > 0) {
|
||||||
history.push({
|
history.push({
|
||||||
run,
|
run,
|
||||||
stats: getStats(runReports),
|
stats: getStats(runReports), // Now returns stats grouped by model
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -122,7 +144,19 @@ function fetchHistoricalData() {
|
|||||||
return history;
|
return history;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateMarkdown(currentStats, history) {
|
function generateMarkdown(currentStatsByModel, history) {
|
||||||
|
console.log('### Evals Nightly Summary\n');
|
||||||
|
console.log(
|
||||||
|
'See [evals/README.md](https://github.com/google-gemini/gemini-cli/tree/main/evals) for more details.\n',
|
||||||
|
);
|
||||||
|
|
||||||
|
// Reverse history to show oldest first
|
||||||
|
const reversedHistory = [...history].reverse();
|
||||||
|
|
||||||
|
const models = Object.keys(currentStatsByModel).sort();
|
||||||
|
|
||||||
|
for (const model of models) {
|
||||||
|
const currentStats = currentStatsByModel[model];
|
||||||
const totalStats = Object.values(currentStats).reduce(
|
const totalStats = Object.values(currentStats).reduce(
|
||||||
(acc, stats) => {
|
(acc, stats) => {
|
||||||
acc.passed += stats.passed;
|
acc.passed += stats.passed;
|
||||||
@@ -137,14 +171,8 @@ function generateMarkdown(currentStats, history) {
|
|||||||
? ((totalStats.passed / totalStats.total) * 100).toFixed(1) + '%'
|
? ((totalStats.passed / totalStats.total) * 100).toFixed(1) + '%'
|
||||||
: 'N/A';
|
: 'N/A';
|
||||||
|
|
||||||
console.log('### Evals Nightly Summary');
|
console.log(`#### Model: ${model}`);
|
||||||
console.log(`**Total Pass Rate: ${totalPassRate}**\n`);
|
console.log(`**Total Pass Rate: ${totalPassRate}**\n`);
|
||||||
console.log(
|
|
||||||
'See [evals/README.md](https://github.com/google-gemini/gemini-cli/tree/main/evals) for more details.\n',
|
|
||||||
);
|
|
||||||
|
|
||||||
// Reverse history to show oldest first
|
|
||||||
const reversedHistory = [...history].reverse();
|
|
||||||
|
|
||||||
// Header
|
// Header
|
||||||
let header = '| Test Name |';
|
let header = '| Test Name |';
|
||||||
@@ -162,10 +190,14 @@ function generateMarkdown(currentStats, history) {
|
|||||||
console.log(header);
|
console.log(header);
|
||||||
console.log(separator);
|
console.log(separator);
|
||||||
|
|
||||||
// Collect all test names
|
// Collect all test names for this model
|
||||||
const allTestNames = new Set(Object.keys(currentStats));
|
const allTestNames = new Set(Object.keys(currentStats));
|
||||||
for (const item of reversedHistory) {
|
for (const item of reversedHistory) {
|
||||||
Object.keys(item.stats).forEach((name) => allTestNames.add(name));
|
if (item.stats[model]) {
|
||||||
|
Object.keys(item.stats[model]).forEach((name) =>
|
||||||
|
allTestNames.add(name),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const name of Array.from(allTestNames).sort()) {
|
for (const name of Array.from(allTestNames).sort()) {
|
||||||
@@ -174,7 +206,7 @@ function generateMarkdown(currentStats, history) {
|
|||||||
|
|
||||||
// History
|
// History
|
||||||
for (const item of reversedHistory) {
|
for (const item of reversedHistory) {
|
||||||
const stat = item.stats[name];
|
const stat = item.stats[model] ? item.stats[model][name] : null;
|
||||||
if (stat) {
|
if (stat) {
|
||||||
const passRate = ((stat.passed / stat.total) * 100).toFixed(0) + '%';
|
const passRate = ((stat.passed / stat.total) * 100).toFixed(0) + '%';
|
||||||
row += ` ${passRate} |`;
|
row += ` ${passRate} |`;
|
||||||
@@ -194,6 +226,8 @@ function generateMarkdown(currentStats, history) {
|
|||||||
|
|
||||||
console.log(row);
|
console.log(row);
|
||||||
}
|
}
|
||||||
|
console.log('\n');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Main ---
|
// --- Main ---
|
||||||
|
|||||||
Reference in New Issue
Block a user