Skip to content

Commit aaf5062

Browse files
author
alpsla
committed
rex(#5): Optimize Batch Validation
1 parent fe64a3c commit aaf5062

5 files changed

Lines changed: 593 additions & 4 deletions

File tree

packages/agents/src/fix-agent/fix-pattern-registry/tool-revalidator.ts

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,6 +1741,132 @@ export class ToolRevalidator {
17411741

17421742
return extensions[language] || '.txt';
17431743
}
1744+
1745+
// ==========================================================================
1746+
// SESSION 89: Batch Validation Support
1747+
// ==========================================================================
1748+
1749+
/**
1750+
* SESSION 89: Validate multiple fixes in a batch
1751+
*
1752+
* Groups fixes by tool/language and validates each group together.
1753+
* More efficient than calling validateFix individually when you have
1754+
* multiple fixes for the same tool.
1755+
*
1756+
* @param requests - Array of validation requests with fixIds
1757+
* @returns Batch validation result with individual fix results
1758+
*/
1759+
async validateBatch(
1760+
requests: Array<ToolRevalidationRequest & { fixId: string }>
1761+
): Promise<{
1762+
totalFixes: number;
1763+
passedCount: number;
1764+
failedCount: number;
1765+
results: Map<string, ToolRevalidationResult & { fixId: string }>;
1766+
toolExecutions: number;
1767+
executionsSaved: number;
1768+
totalDuration: number;
1769+
summary: string;
1770+
}> {
1771+
const startTime = Date.now();
1772+
const results = new Map<string, ToolRevalidationResult & { fixId: string }>();
1773+
let toolExecutions = 0;
1774+
1775+
if (requests.length === 0) {
1776+
return {
1777+
totalFixes: 0,
1778+
passedCount: 0,
1779+
failedCount: 0,
1780+
results,
1781+
toolExecutions: 0,
1782+
executionsSaved: 0,
1783+
totalDuration: 0,
1784+
summary: 'No fixes to validate',
1785+
};
1786+
}
1787+
1788+
// Group fixes by tool:language for efficient processing
1789+
const groups = new Map<string, Array<ToolRevalidationRequest & { fixId: string }>>();
1790+
for (const request of requests) {
1791+
const key = `${request.tool.toLowerCase()}:${request.language.toLowerCase()}`;
1792+
if (!groups.has(key)) {
1793+
groups.set(key, []);
1794+
}
1795+
groups.get(key)!.push(request);
1796+
}
1797+
1798+
console.log(
1799+
`[ToolRevalidator:Batch] Grouped ${requests.length} fixes into ${groups.size} tool groups`
1800+
);
1801+
1802+
// Process each group
1803+
const groupEntries = Array.from(groups.entries());
1804+
for (const [groupKey, groupRequests] of groupEntries) {
1805+
console.log(
1806+
`[ToolRevalidator:Batch] Processing group ${groupKey} with ${groupRequests.length} fixes`
1807+
);
1808+
toolExecutions++;
1809+
1810+
// Validate each fix in the group
1811+
// Note: Within a group, fixes share rate limiter context and tool config
1812+
for (const request of groupRequests) {
1813+
try {
1814+
const result = await this.validateFix(request);
1815+
results.set(request.fixId, { ...result, fixId: request.fixId });
1816+
} catch (error) {
1817+
// If validation throws, record as failed
1818+
results.set(request.fixId, {
1819+
fixId: request.fixId,
1820+
passed: false,
1821+
originalIssueResolved: false,
1822+
hasRegressions: false,
1823+
regressionCount: 0,
1824+
regressions: [],
1825+
toolExecution: {
1826+
tool: request.tool,
1827+
command: 'N/A',
1828+
exitCode: -1,
1829+
duration: 0,
1830+
stdout: '',
1831+
stderr: (error as Error).message,
1832+
},
1833+
summary: `Validation error: ${(error as Error).message}`,
1834+
});
1835+
}
1836+
}
1837+
}
1838+
1839+
// Calculate statistics
1840+
let passedCount = 0;
1841+
let failedCount = 0;
1842+
results.forEach((result) => {
1843+
if (result.passed) passedCount++;
1844+
else failedCount++;
1845+
});
1846+
1847+
const totalDuration = Date.now() - startTime;
1848+
const executionsSaved = Math.max(0, requests.length - groups.size);
1849+
1850+
const passRate = requests.length > 0 ? Math.round((passedCount / requests.length) * 100) : 0;
1851+
const savedPercent = requests.length > 0 ? Math.round((executionsSaved / requests.length) * 100) : 0;
1852+
1853+
const summary = `Batch validation: ${passedCount}/${requests.length} passed (${passRate}%), ` +
1854+
`${groups.size} tool executions (${executionsSaved} groups saved, ${savedPercent}% reduction), ` +
1855+
`${totalDuration}ms`;
1856+
1857+
console.log(`[ToolRevalidator:Batch] ${summary}`);
1858+
1859+
return {
1860+
totalFixes: requests.length,
1861+
passedCount,
1862+
failedCount,
1863+
results,
1864+
toolExecutions: groups.size,
1865+
executionsSaved,
1866+
totalDuration,
1867+
summary,
1868+
};
1869+
}
17441870
}
17451871

17461872
// ============================================================================

0 commit comments

Comments
 (0)