feat(coding): declare maxRounds + moderator remainingRounds awareness
CI / test (push) Has been cancelled

This commit is contained in:
2026-04-17 12:25:17 +00:00
parent a54c36f758
commit bf6de91c61
2 changed files with 28 additions and 0 deletions
@@ -207,4 +207,29 @@ describe('CodingTask WorkflowType', () => {
rmSync(logTmpDir, { recursive: true, force: true });
}
});
it('limits.maxRounds is declared as 15', () => {
const wf = createCodingWorkflow();
expect(wf.limits?.maxRounds).toBe(15);
});
it('moderator: remainingRounds <= 1 forces closer even if reviewer rejected', () => {
const wf = createCodingWorkflow();
const result = wf.moderator(
{ role: 'reviewer', meta: { verdict: 'rejected', rejectionReason: [], retryCount: 0 } },
'topic-1',
1 // remainingRounds = 1, 紧急收敛
);
expect(result).toBe('closer');
});
it('moderator: remainingRounds > 1 keeps normal retry logic', () => {
const wf = createCodingWorkflow();
const result = wf.moderator(
{ role: 'reviewer', meta: { verdict: 'rejected', rejectionReason: [], retryCount: 0 } },
'topic-1',
5 // 还有余量,正常 retry
);
expect(result).toBe('coder');
});
});
+3
View File
@@ -95,6 +95,7 @@ type CodingInput = ModeratorInput<CodingRoles>;
function codingModerator(
output: CodingInput,
_topicId: string,
remainingRounds?: number,
): keyof CodingRoles | typeof END {
if (output.role === START) return 'architect';
switch (output.role) {
@@ -103,6 +104,7 @@ function codingModerator(
case 'coder':
return 'reviewer';
case 'reviewer': {
if (remainingRounds !== undefined && remainingRounds <= 1) return 'closer';
const rejected = output.meta?.verdict === 'rejected';
const retryCount = output.meta?.retryCount ?? 0;
return rejected && retryCount < 3 ? 'coder' : 'closer';
@@ -129,5 +131,6 @@ export function createCodingWorkflow(opts?: {
closer: defaultCloser,
},
moderator: codingModerator,
limits: { maxRounds: 15 },
};
}