-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathAIModel.cs
More file actions
235 lines (207 loc) · 9.42 KB
/
AIModel.cs
File metadata and controls
235 lines (207 loc) · 9.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
using MaIN.Domain.Configuration;
using MaIN.Domain.Exceptions.Models.LocalModels;
namespace MaIN.Domain.Models.Abstract;
public abstract record AIModel(
string Id,
BackendType Backend,
string? Name = null,
uint MaxContextWindowSize = ModelDefaults.DefaultMaxContextWindow,
string? Description = null,
string? SystemMessage = null)
{
/// <summary> Internal Id. For cloud models it is the cloud Id. </summary>
public string Id { get; } = Id;
/// <summary> Name displayed to users. </summary>
public string Name { get; } = Name ?? Id;
/// <summary> Gets the type of backend used by the model eg OpenAI or Self (Local). </summary>
public BackendType Backend { get; } = Backend;
/// <summary> System Message added before first prompt. </summary>
public string? SystemMessage { get; } = SystemMessage;
/// <summary> Model description eg. capabilities or purpose. </summary>
public string? Description { get; } = Description;
/// <summary> Max context window size supported by the model. </summary>
public uint MaxContextWindowSize { get; } = MaxContextWindowSize;
/// <summary> Checks if model supports reasoning/thinking mode. </summary>
public bool HasReasoning => this is IReasoningModel;
/// <summary> Checks if model supports vision/image input. </summary>
public bool HasVision => this is IVisionModel;
/// <summary> Checks if model generates images from text prompts. </summary>
public bool HasImageGeneration => this is IImageGenerationModel;
}
/// <summary> Base class for local models. </summary>
public abstract record LocalModel(
string Id,
string FileName,
Uri? DownloadUrl = null,
string? Name = null,
uint MaxContextWindowSize = ModelDefaults.DefaultMaxContextWindow,
string? Description = null,
string? SystemMessage = null,
string? CustomPath = null) : AIModel(Id, BackendType.Self, Name, MaxContextWindowSize, Description, SystemMessage)
{
/// <summary> Name of the model file on the hard drive eg. Gemma2-2b.gguf </summary>
public string FileName { get; } = FileName;
/// <summary> Uri to download model eg. https://huggingface.co/Inza124/gemma2_2b/resolve/main/gemma2-2b-maIN.gguf?download=true </summary>
public Uri? DownloadUrl { get; } = DownloadUrl;
/// <summary> Gets or sets the custom file system path (excluding file name eg. your\path\). If not null will be prioritized over the default base path. </summary>
public string? CustomPath { get; } = CustomPath;
public bool IsDownloaded(string? basePath)
{
try
{
return File.Exists(GetFullPath(basePath));
}
catch (ModelPathNullOrEmptyException)
{
return false;
}
}
/// <summary>
/// Combines the specified base path with the file name to generate a full file path.
/// </summary>
/// <remarks>This method ensures that a valid path is generated by requiring at least one of the
/// CustomPath or basePath to be provided.</remarks>
/// <param name="basePath">The base path to combine with the file name. If null or empty, the method uses the custom path.</param>
/// <returns>A string representing the full file path formed by combining the base path and the file name.</returns>
/// <exception cref="ModelPathNullOrEmptyException">Thrown if both CustomPath and basePath are null or empty.</exception>
public string GetFullPath(string? basePath = null)
{
if (string.IsNullOrEmpty(CustomPath) && string.IsNullOrEmpty(basePath))
{
throw new ModelPathNullOrEmptyException();
}
return Path.Combine((CustomPath ?? basePath)!, FileName);
}
}
/// <summary> Base class for cloud models. </summary>
public abstract record CloudModel(
string Id,
BackendType Backend,
string? Name = null,
uint MaxContextWindowSize = ModelDefaults.DefaultMaxContextWindow,
string? Description = null,
string? SystemMessage = null) : AIModel(Id, Backend, Name, MaxContextWindowSize, Description, SystemMessage);
/// <summary> Generic class for runtime defined cloud models. </summary>
public record GenericCloudModel(
string Id,
BackendType Backend,
string? Name = null,
uint MaxContextWindowSize = ModelDefaults.DefaultMaxContextWindow,
string? Description = null,
string? SystemMessage = null
) : CloudModel(Id, Backend, Name, MaxContextWindowSize, Description, SystemMessage);
/// <summary> Generic class for runtime defined cloud models with reasoning capability. </summary>
public record GenericCloudReasoningModel(
string Id,
BackendType Backend,
string? Name = null,
uint MaxContextWindowSize = ModelDefaults.DefaultMaxContextWindow,
string? Description = null,
string? SystemMessage = null,
string? AdditionalPrompt = null
) : CloudModel(Id, Backend, Name, MaxContextWindowSize, Description, SystemMessage), IReasoningModel
{
// IReasoningModel - null for cloud (handled by provider API)
public Func<string, ThinkingState, LLMTokenValue>? ReasonFunction => null;
public string? AdditionalPrompt { get; } = AdditionalPrompt;
}
/// <summary> Generic class for runtime defined cloud models with vision capability. </summary>
public record GenericCloudVisionModel(
string Id,
BackendType Backend,
string? Name = null,
uint MaxContextWindowSize = ModelDefaults.DefaultMaxContextWindow,
string? Description = null,
string? SystemMessage = null
) : CloudModel(Id, Backend, Name, MaxContextWindowSize, Description, SystemMessage), IVisionModel
{
// IVisionModel - cloud models don't need MMProjectPath
public string? MMProjectName => null;
}
/// <summary> Generic class for runtime defined cloud models with both vision and reasoning capabilities. </summary>
public record GenericCloudVisionReasoningModel(
string Id,
BackendType Backend,
string? Name = null,
uint MaxContextWindowSize = ModelDefaults.DefaultMaxContextWindow,
string? Description = null,
string? SystemMessage = null,
string? AdditionalPrompt = null
) : CloudModel(Id, Backend, Name, MaxContextWindowSize, Description, SystemMessage), IVisionModel, IReasoningModel
{
// IVisionModel - null for cloud (handled by provider API)
public string? MMProjectName => null;
// IReasoningModel - null for cloud (handled by provider API)
public Func<string, ThinkingState, LLMTokenValue>? ReasonFunction => null;
public string? AdditionalPrompt { get; } = AdditionalPrompt;
}
/// <summary> Generic class for runtime defined local models. </summary>
public record GenericLocalModel(
string FileName,
string? Name = null,
string? Id = null,
Uri? DownloadUrl = null,
uint MaxContextWindowSize = 4096,
string? CustomPath = null,
string? Description = null,
string? SystemMessage = null
) : LocalModel(Id ?? FileName, FileName, DownloadUrl, Name ?? FileName, MaxContextWindowSize, Description, SystemMessage, CustomPath);
/// <summary> Generic class for runtime defined local models with reasoning capability. </summary>
public record GenericLocalReasoningModel(
string FileName,
Func<string, ThinkingState, LLMTokenValue> ReasonFunction,
string? Name = null,
string? Id = null,
Uri? DownloadUrl = null,
uint MaxContextWindowSize = 4096,
string? CustomPath = null,
string? AdditionalPrompt = null,
string? Description = null,
string? SystemMessage = null
) : LocalModel(Id ?? FileName, FileName, DownloadUrl, Name ?? FileName, MaxContextWindowSize, Description, SystemMessage, CustomPath), IReasoningModel
{
// IReasoningModel implementation
public Func<string, ThinkingState, LLMTokenValue> ReasonFunction { get; } = ReasonFunction;
public string? AdditionalPrompt { get; } = AdditionalPrompt;
}
/// <summary> Generic class for runtime defined local models with vision capability. </summary>
public record GenericLocalVisionModel(
string FileName,
string MMProjectPath,
string? Name = null,
string? Id = null,
Uri? DownloadUrl = null,
uint MaxContextWindowSize = 4096,
string? CustomPath = null,
string? Description = null,
string? SystemMessage = null
) : LocalModel(Id ?? FileName, FileName, DownloadUrl, Name ?? FileName, MaxContextWindowSize, Description, SystemMessage, CustomPath), IVisionModel
{
// IVisionModel implementation
public string MMProjectName { get; } = MMProjectPath;
}
/// <summary> Generic class for runtime defined local models with both vision and reasoning capabilities. </summary>
public record GenericLocalVisionReasoningModel(
string FileName,
string MMProjectPath,
Func<string, ThinkingState, LLMTokenValue> ReasonFunction,
string? Name = null,
string? Id = null,
Uri? DownloadUrl = null,
uint MaxContextWindowSize = 4096,
string? CustomPath = null,
string? AdditionalPrompt = null,
string? Description = null,
string? SystemMessage = null
) : LocalModel(Id ?? FileName, FileName, DownloadUrl, Name ?? FileName, MaxContextWindowSize, Description, SystemMessage, CustomPath), IVisionModel, IReasoningModel
{
// IVisionModel implementation
public string MMProjectName { get; } = MMProjectPath;
// IReasoningModel implementation
public Func<string, ThinkingState, LLMTokenValue> ReasonFunction { get; } = ReasonFunction;
public string? AdditionalPrompt { get; } = AdditionalPrompt;
}
public static class ModelDefaults
{
public const uint DefaultMaxContextWindow = 128000;
}