AI-Studio/app/MindWork AI Studio/Models/Live/ModelListing.cs
Thorsten Sommer d85b4e71b6
Some checks are pending
Build and Release / Determine run mode (push) Waiting to run
Build and Release / Sync Flatpak repo (push) Blocked by required conditions
Build and Release / Collect Flatpak artifacts (push) Blocked by required conditions
Build and Release / Verify (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg,app,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage,updater, appimage) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg,app,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage,updater, appimage) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Rebuilt how AI Studio knows what a model can do (#960)
2026-09-13 14:17:25 +02:00

60 lines
3.4 KiB
C#

namespace AIStudio.Models.Live;
/// <summary>
/// What a provider's own model list says about one of the models it serves.
/// </summary>
/// <remarks>
/// That list is fetched anyway: before every chat round, before every assistant run, and whenever
/// somebody opens the provider dialog. Reading what it already carries therefore costs no request
/// of its own, which is the whole reason these numbers are taken from here and not asked for.
///
/// This describes one installation, never the model as such. Two machines may serve the same
/// weights behind different settings, and a statement about one of them says nothing about the
/// other -- which is why a listing is kept per configured provider instance and is gone with the
/// process. It is also the only source for a self-hosted model: a rule can say what the weights
/// were trained for, but only the engine knows what its operator started it with.
/// </remarks>
/// <param name="ModelId">The model, named the way the provider names it in its list.</param>
/// <param name="Context">The window the provider states for it, or unknown where it states none.</param>
public readonly record struct ModelListing(string ModelId, ContextWindow Context)
{
/// <summary>
/// What we have about a model nobody has reported anything about.
/// </summary>
public static readonly ModelListing NOTHING = new(string.Empty, ContextWindow.UNKNOWN);
/// <summary>
/// Whether this listing states anything at all.
/// </summary>
public bool IsKnown => this.Context.IsKnown;
/// <summary>
/// What a provider stated about one model, as every model list states it: a name and a number.
/// </summary>
/// <remarks>
/// A window of zero or less is dropped rather than repaired, and so is a nameless entry. A
/// provider answering that way is saying something we cannot interpret, and falling back to
/// what the rules say about the model is the one answer nobody has to invent. Every dialect
/// comes through here, so that none of them has to decide that on its own.
/// </remarks>
/// <param name="modelId">The model, named the way the provider names it.</param>
/// <param name="contextWindowTokens">The window the provider stated, where it stated one.</param>
/// <returns>The listing, or nothing when there is nothing usable to keep.</returns>
public static ModelListing For(string modelId, int? contextWindowTokens) => string.IsNullOrWhiteSpace(modelId) || contextWindowTokens is not > 0
? NOTHING
: new(modelId, ContextWindow.Of(contextWindowTokens.Value));
/// <summary>
/// Puts what the provider stated over what the rules worked out.
/// </summary>
/// <remarks>
/// A stated window replaces the whole window, the ceiling included, for the same reason the
/// expert settings do: what a model card says it could be raised to is a statement about the
/// model, while this is a statement about the installation serving it. Whoever started that
/// engine has already decided, and a ceiling nobody can reach without restarting it is not a
/// number to keep showing.
/// </remarks>
/// <param name="profile">What is known about the model without this listing.</param>
/// <returns>The profile, with what the provider stated in it.</returns>
public ModelProfile ApplyTo(in ModelProfile profile) => this.IsKnown ? profile with { Context = this.Context } : profile;
}