mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-05 02:43:32 +00:00
Add evolver variant generator
This commit is contained in:
parent
5f09f19726
commit
35d0116128
3 changed files with 254 additions and 0 deletions
|
|
@ -1,3 +1,4 @@
|
|||
export * from './types.js';
|
||||
export * from './metric-evaluator.js';
|
||||
export * from './resource-manager.js';
|
||||
export * from './variant-generator.js';
|
||||
|
|
|
|||
172
gitnexus/src/core/evolver/variant-generator.ts
Normal file
172
gitnexus/src/core/evolver/variant-generator.ts
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
import type {
|
||||
EvolutionPlan,
|
||||
MetricExpectation,
|
||||
MutationType,
|
||||
RollbackPlan,
|
||||
VariantPatch,
|
||||
VariantProvenance,
|
||||
VariantSpec,
|
||||
} from './types.js';
|
||||
|
||||
export type CurrentParameters = Record<string, unknown>;
|
||||
|
||||
const generatedAt = '2026-05-25T00:00:00.000Z';
|
||||
|
||||
export function generateVariants(
|
||||
plan: EvolutionPlan,
|
||||
currentParameters: CurrentParameters,
|
||||
): VariantSpec[] {
|
||||
return plan.allowedMutationTypes.map((mutationType) =>
|
||||
buildVariant(plan, currentParameters, mutationType),
|
||||
);
|
||||
}
|
||||
|
||||
function buildVariant(
|
||||
plan: EvolutionPlan,
|
||||
currentParameters: CurrentParameters,
|
||||
mutationType: MutationType,
|
||||
): VariantSpec {
|
||||
const expectedGain = defaultExpectedGain();
|
||||
|
||||
return {
|
||||
id: `${plan.id}-${mutationType}-variant`,
|
||||
planId: plan.id,
|
||||
mutationType,
|
||||
description: describeVariant(plan, mutationType),
|
||||
patch: buildPatch(currentParameters, mutationType),
|
||||
expectedGain,
|
||||
riskLevel: riskForMutationType(mutationType),
|
||||
rollbackPlan: buildRollbackPlan(currentParameters, mutationType),
|
||||
provenance: buildProvenance(plan, mutationType),
|
||||
};
|
||||
}
|
||||
|
||||
function describeVariant(plan: EvolutionPlan, mutationType: MutationType): string {
|
||||
if (mutationType === 'parameter') {
|
||||
return `Parameter variant for ${plan.targetObject.id}`;
|
||||
}
|
||||
|
||||
if (mutationType === 'algorithm') {
|
||||
return `Algorithm variant for ${plan.targetObject.id}`;
|
||||
}
|
||||
|
||||
return `Structure review variant for ${plan.targetObject.id}`;
|
||||
}
|
||||
|
||||
function buildPatch(currentParameters: CurrentParameters, mutationType: MutationType): VariantPatch {
|
||||
if (mutationType === 'parameter') {
|
||||
const previousValue = currentParameters['retrieval.topK'] ?? 5;
|
||||
const nextValue = typeof previousValue === 'number' ? previousValue + 1 : 6;
|
||||
|
||||
return {
|
||||
operations: [
|
||||
{
|
||||
op: 'setParameter',
|
||||
path: 'retrieval.topK',
|
||||
previousValue,
|
||||
nextValue,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
if (mutationType === 'algorithm') {
|
||||
const previousAlgorithm = String(currentParameters['ranking.algorithm'] ?? 'baseline-ranker');
|
||||
|
||||
return {
|
||||
operations: [
|
||||
{
|
||||
op: 'selectAlgorithm',
|
||||
policyId: 'ranking-policy',
|
||||
previousAlgorithm,
|
||||
nextAlgorithm: 'candidate-ranker',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
operations: [
|
||||
{
|
||||
op: 'proposeStructureChange',
|
||||
planPath: 'docs/aegis/plans/structure-change.md',
|
||||
summary: 'Review structure-level evolution before applying changes',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
function buildRollbackPlan(
|
||||
currentParameters: CurrentParameters,
|
||||
mutationType: MutationType,
|
||||
): RollbackPlan {
|
||||
if (mutationType === 'parameter') {
|
||||
const previousValue = currentParameters['retrieval.topK'] ?? 5;
|
||||
const candidateValue = typeof previousValue === 'number' ? previousValue + 1 : 6;
|
||||
|
||||
return {
|
||||
strategy: 'restore-previous-parameters',
|
||||
operations: [
|
||||
{
|
||||
op: 'setParameter',
|
||||
path: 'retrieval.topK',
|
||||
previousValue: candidateValue,
|
||||
nextValue: previousValue,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
if (mutationType === 'algorithm') {
|
||||
const previousAlgorithm = String(currentParameters['ranking.algorithm'] ?? 'baseline-ranker');
|
||||
|
||||
return {
|
||||
strategy: 'disable-candidate',
|
||||
operations: [
|
||||
{
|
||||
op: 'selectAlgorithm',
|
||||
policyId: 'ranking-policy',
|
||||
previousAlgorithm: 'candidate-ranker',
|
||||
nextAlgorithm: previousAlgorithm,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
strategy: 'manual-review-required',
|
||||
operations: [],
|
||||
};
|
||||
}
|
||||
|
||||
function riskForMutationType(mutationType: MutationType): VariantSpec['riskLevel'] {
|
||||
if (mutationType === 'parameter') {
|
||||
return 'low';
|
||||
}
|
||||
|
||||
if (mutationType === 'algorithm') {
|
||||
return 'medium';
|
||||
}
|
||||
|
||||
return 'high';
|
||||
}
|
||||
|
||||
function defaultExpectedGain(): MetricExpectation[] {
|
||||
return [
|
||||
{
|
||||
metricId: 'task_success_rate',
|
||||
expectedDelta: 0.05,
|
||||
direction: 'increase',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function buildProvenance(plan: EvolutionPlan, mutationType: MutationType): VariantProvenance[] {
|
||||
return [
|
||||
{
|
||||
source: 'evolver-variant-generator',
|
||||
reference: `${plan.id}:${mutationType}`,
|
||||
capturedAt: generatedAt,
|
||||
},
|
||||
];
|
||||
}
|
||||
81
gitnexus/test/unit/evolver/variant-generator.test.ts
Normal file
81
gitnexus/test/unit/evolver/variant-generator.test.ts
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import { describe, expect, it } from 'vitest';
|
||||
import { generateVariants } from '../../../src/core/evolver/index.js';
|
||||
import type { EvolutionPlan, ResourceBudget } from '../../../src/core/evolver/index.js';
|
||||
|
||||
const resourceBudget: ResourceBudget = {
|
||||
maxDurationMs: 1000,
|
||||
maxComputeUnits: 10,
|
||||
maxApiCostUsd: 1,
|
||||
maxStorageBytes: 2048,
|
||||
maxConcurrency: 2,
|
||||
maxHighRiskVariants: 1,
|
||||
};
|
||||
|
||||
const plan: EvolutionPlan = {
|
||||
id: 'plan-1',
|
||||
goalId: 'goal-1',
|
||||
hypothesis: 'Adjust retrieval and ranking strategy to improve task success rate',
|
||||
targetObject: {
|
||||
id: 'retrieval-policy',
|
||||
kind: 'parameter-set',
|
||||
description: 'Retrieval policy parameters and selection strategy',
|
||||
},
|
||||
allowedMutationTypes: ['parameter', 'algorithm', 'structure'],
|
||||
evaluationProtocolId: 'protocol-1',
|
||||
resourceBudget,
|
||||
};
|
||||
|
||||
describe('generateVariants', () => {
|
||||
it('generates deterministic parameter, algorithm, and structure variants with risk and rollback data', () => {
|
||||
const variants = generateVariants(plan, {
|
||||
'retrieval.topK': 5,
|
||||
'ranking.algorithm': 'baseline-ranker',
|
||||
});
|
||||
|
||||
expect(variants).toHaveLength(3);
|
||||
expect(variants.map((variant) => variant.id)).toEqual([
|
||||
'plan-1-parameter-variant',
|
||||
'plan-1-algorithm-variant',
|
||||
'plan-1-structure-variant',
|
||||
]);
|
||||
expect(variants.map((variant) => variant.mutationType)).toEqual([
|
||||
'parameter',
|
||||
'algorithm',
|
||||
'structure',
|
||||
]);
|
||||
expect(variants.map((variant) => variant.riskLevel)).toEqual(['low', 'medium', 'high']);
|
||||
expect(variants.map((variant) => variant.rollbackPlan.strategy)).toEqual([
|
||||
'restore-previous-parameters',
|
||||
'disable-candidate',
|
||||
'manual-review-required',
|
||||
]);
|
||||
expect(variants.every((variant) => variant.provenance.length === 1)).toBe(true);
|
||||
expect(variants.every((variant) => variant.provenance[0]?.source === 'evolver-variant-generator')).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it('only generates mutation types allowed by the plan', () => {
|
||||
const variants = generateVariants(
|
||||
{
|
||||
...plan,
|
||||
allowedMutationTypes: ['parameter'],
|
||||
},
|
||||
{
|
||||
'retrieval.topK': 5,
|
||||
'ranking.algorithm': 'baseline-ranker',
|
||||
},
|
||||
);
|
||||
|
||||
expect(variants).toHaveLength(1);
|
||||
expect(variants[0]?.mutationType).toBe('parameter');
|
||||
expect(variants[0]?.patch.operations).toEqual([
|
||||
{
|
||||
op: 'setParameter',
|
||||
path: 'retrieval.topK',
|
||||
previousValue: 5,
|
||||
nextValue: 6,
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue