using AIStudio.Models.Matching;
namespace AIStudio.Models;
///
/// Everything the app knows about one family of models, in one place.
///
///
/// A family is a class, and adding one is all it takes: the source generator finds it at compile
/// time and the registry asks it for its rules. There is no list to remember to add it to, which is
/// what the old code got wrong in the other direction -- there, a new family meant editing a file
/// which had already grown past a thousand lines, and putting the block in the wrong place changed
/// the answer for models nobody was thinking about.
///
/// The source is an abstract member, so the compiler asks for it. That is deliberate: a rule
/// without a page behind it is a guess, and a guess which nobody can check ages into a defect.
///
public abstract class ModelFamily
{
private IReadOnlyList? declaredRules;
///
/// Who builds the models of this family.
///
public abstract ModelVendor Vendor { get; }
///
/// Where the statements below were read, and when.
///
public abstract ModelSource Source { get; }
///
/// The other pages this family was read from, where one was not enough.
///
///
/// A vendor keeps what a model can do, how much it reads and how many images it takes on three
/// different pages often enough. The source above stays the one to start from; these are the
/// rest, and the same is asked of them -- a page and a day, so that every number in the family
/// leads back to something somebody can open.
///
public virtual IReadOnlyList FurtherSources => [];
///
/// What this family is called, which is what its rules name as their origin.
///
public string Name => this.GetType().Name;
///
/// The rules this family states, worked out once.
///
public IReadOnlyList Rules => this.declaredRules ??= this.BuildRules();
///
/// Adjusts a profile in a way no pattern can express.
///
///
/// The way out for the handful of families whose capabilities are computed from the name rather
/// than looked up: Mistral encodes a release date as four digits and gains abilities from a
/// certain date onwards, and Z AI marks its vision models by putting a "v" behind the version
/// number. Writing one rule per possible date is not a rule set, it is a table of everything.
///
/// Everything which can be said with a pattern belongs in a pattern, where the specificity can
/// see it. This runs afterwards, on the family whose rule won.
///
/// The model name.
/// What the rules made of it.
/// The profile, adjusted.
public virtual ModelProfile Refine(in ModelId id, in ModelProfile selected) => selected;
///
/// States the rules of this family.
///
/// What to state them with.
protected abstract void Declare(ModelFamilyBuilder builder);
private IReadOnlyList BuildRules()
{
var builder = new ModelFamilyBuilder(this.Name);
this.Declare(builder);
return builder.Build();
}
}