Skip to content

Commit 3dff04c

Browse files
author
Piotr Stachaczynski
committed
feat: fin changes for CLI
1 parent 9dfc973 commit 3dff04c

7 files changed

Lines changed: 99 additions & 76 deletions

File tree

Examples/Examples/appsettings.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
},
88
"MaIN": {
99
"ImageGenUrl": "http://localhost:5003",
10-
"ModelsPath": "C:\\MAIN.Models",
11-
// "SqliteSettings": {
10+
// "SqliteSettings": {
1211
// "ConnectionString": "Data Source=Main_test.db"
1312
// }
1413
},

mcli.ps1

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,23 @@ param(
88

99
# Set script root as a global variable for other scripts to use
1010
$global:MCLI_ROOT = $PSScriptRoot
11+
$modelsPath = $env:MaIN_ModelsPath
12+
function Get-ModelsMap {
13+
$modelsMapFile = "$PSScriptRoot\models_map.txt"
14+
if (-not (Test-Path $modelsMapFile)) {
15+
Write-Host "Models map file not found at $modelsMapFile. Please provide a valid file."
16+
return $null
17+
}
18+
19+
$modelsMap = @{}
20+
Get-Content $modelsMapFile | ForEach-Object {
21+
$split = $_.Split("|")
22+
$key = $split[0].Trim()
23+
$value = $split[1].Trim()
24+
$modelsMap[$key] = $value
25+
}
26+
return $modelsMap
27+
}
1128

1229
function Show-Usage {
1330
Write-Host @"
@@ -36,14 +53,15 @@ Options for 'api':
3653
3754
Options for 'model':
3855
download <name> Download a specific model
56+
present List installed models
3957
list List available models
4058
update Update all installed models
4159
4260
Examples:
4361
mcli start-demo
4462
mcli start-demo --no-image-gen
4563
mcli api --hard
46-
mcli model download llama2-7b
64+
mcli model download gemma2-2b-maIN
4765
mcli help
4866
"@
4967
}
@@ -69,7 +87,7 @@ Options:
6987
Examples:
7088
mcli start-demo
7189
mcli start-demo --no-image-gen
72-
mcli start-demo --models=llama3.2:3b,gemma2:2b
90+
mcli start-demo --models=gemma2-2b-maIN
7391
"@
7492
}
7593
"api" {
@@ -108,11 +126,13 @@ Usage:
108126
Subcommands:
109127
download <name> Download a specific model
110128
list List available models
129+
present List installed models
111130
update Update all installed models
112131
113132
Examples:
114133
mcli model download llama2-7b
115134
mcli model list
135+
mcli model present
116136
mcli model update
117137
"@
118138
}
@@ -142,8 +162,29 @@ switch ($command) {
142162
& "$PSScriptRoot\download-models.ps1" $modelArgs[0]
143163
}
144164
"list" {
165+
$modelsMap = Get-ModelsMap
166+
if ($null -eq $modelsMap) { return }
167+
145168
Write-Host "Available models:"
146-
Get-Content "$PSScriptRoot\models_map.txt" | Where-Object { $_ -notmatch '^\s*#' -and $_ -notmatch '^\s*$' }
169+
$modelsMap.Keys | Sort-Object | ForEach-Object {
170+
Write-Host "- $_"
171+
}
172+
}
173+
"present" {
174+
Write-Host "Downloaded models:"
175+
Write-Host "Models path: $modelsPath"
176+
$downloadedModels = Get-ChildItem -Path $modelsPath -Filter "*.gguf" |
177+
Select-Object -ExpandProperty Name |
178+
ForEach-Object { $_ -replace '\.gguf$','' }
179+
180+
if ($downloadedModels.Count -eq 0) {
181+
Write-Host "No models found in $modelsPath"
182+
}
183+
else {
184+
$downloadedModels | Sort-Object | ForEach-Object {
185+
Write-Host "- $_"
186+
}
187+
}
147188
}
148189
"update" {
149190
Write-Host "Updating all installed models..."
@@ -170,4 +211,5 @@ switch ($command) {
170211
Write-Host "`nError: Unknown command '$command'" -ForegroundColor Red
171212
}
172213
}
173-
}
214+
}
215+

src/MaIN.Core/Hub/Contexts/AgentContext.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using MaIN.Domain.Entities;
22
using MaIN.Domain.Entities.Agents;
33
using MaIN.Domain.Entities.Agents.AgentSource;
4+
using MaIN.Domain.Models;
45
using MaIN.Services.Mappers;
56
using MaIN.Services.Models;
67
using MaIN.Services.Models.Ollama;
@@ -63,7 +64,7 @@ public AgentContext WithSource(IAgentSource source, AgentSourceType type)
6364
};
6465
return this;
6566
}
66-
67+
6768
public AgentContext WithName(string name)
6869
{
6970
_agent.Name = name;
@@ -76,6 +77,14 @@ public AgentContext WithModel(string model)
7677
return this;
7778
}
7879

80+
public AgentContext WithCustomModel(string model, string path)
81+
{
82+
KnownModels.AddModel(model, path);
83+
_agent.Model = model;
84+
return this;
85+
}
86+
87+
7988
public AgentContext WithInitialPrompt(string prompt)
8089
{
8190
_agent.Context.Instruction = prompt;
@@ -96,7 +105,6 @@ public AgentContext WithBehaviour(string name, string instruction)
96105
return this;
97106
}
98107

99-
// Creation and Processing
100108
public async Task<AgentContext> CreateAsync(bool flow = false, bool interactiveResponse = false)
101109
{
102110
await _agentService.CreateAgent(_agent, flow, interactiveResponse);
@@ -157,7 +165,6 @@ public async Task<ChatResult> ProcessAsync(Message message, bool translate = fal
157165
};
158166
}
159167

160-
// Chat Operations
161168
public async Task<Chat> GetChat()
162169
{
163170
return await _agentService.GetChatByAgent(_agent.Id);
@@ -168,7 +175,6 @@ public async Task<Chat> RestartChat()
168175
return await _agentService.Restart(_agent.Id);
169176
}
170177

171-
// Agent Management
172178
public async Task<List<Agent>> GetAllAgents()
173179
{
174180
return await _agentService.GetAgents();
@@ -184,7 +190,6 @@ public async Task<bool> Exists()
184190
return await _agentService.AgentExists(_agent.Id);
185191
}
186192

187-
// Static factory methods
188193
public static async Task<AgentContext> FromExisting(IAgentService agentService, string agentId)
189194
{
190195
var existingAgent = await agentService.GetAgentById(agentId);

src/MaIN.Core/Hub/Contexts/ChatContext.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using MaIN.Domain.Entities;
2+
using MaIN.Domain.Models;
23
using MaIN.Services.Models;
34
using MaIN.Services.Models.Ollama;
45
using MaIN.Services.Services.Abstract;
@@ -33,6 +34,13 @@ public ChatContext WithModel(string model)
3334
_chat.Model = model;
3435
return this;
3536
}
37+
38+
public ChatContext WithCustomModel(string model, string path)
39+
{
40+
KnownModels.AddModel(model, path);
41+
_chat.Model = model;
42+
return this;
43+
}
3644

3745
public ChatContext WithMessage(string content)
3846
{

src/MaIN.Domain/Models/SupportedModels.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public struct Model
1111

1212
public struct KnownModels
1313
{
14-
internal static Dictionary<string, Model> Models => new()
14+
internal static Dictionary<string, Model> Models => new(StringComparer.OrdinalIgnoreCase)
1515
{
1616
{
1717
KnownModelNames.Gemma2_2b, new Model()
@@ -130,7 +130,19 @@ public static Model GetModel(string path, string name)
130130
}
131131

132132
throw new Exception($"Model {fileName} is not downloaded");
133-
}
133+
}
134+
135+
public static void AddModel(string model, string path)
136+
{
137+
Models.Add(model, new Model()
138+
{
139+
Description = string.Empty,
140+
DownloadUrl = string.Empty,
141+
Name = model,
142+
FileName = $"{Path.GetFileName(path)}",
143+
Path = path
144+
});
145+
}
134146
}
135147

136148
public struct KnownModelNames

src/MaIN.Services/Services/AgentService.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@ public AgentService(
2828
IChatRepository chatRepository,
2929
ILogger<AgentService> logger,
3030
INotificationService notificationService,
31-
IStepProcessor stepProcessor)
31+
IStepProcessor stepProcessor,
32+
ILLMService llmService)
3233
{
3334
_agentRepository = agentRepository;
3435
_chatRepository = chatRepository;
3536
_logger = logger;
3637
_notificationService = notificationService;
3738
_stepProcessor = stepProcessor;
39+
_llmService = llmService;
3840
}
3941

4042
public async Task<Chat> Process(Chat chat, string agentId, bool translatePrompt = false)

src/MaIN.Services/Services/LLMService/LLMService.cs

Lines changed: 17 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ private void AddMessagesToHistory(ChatSession session, List<Message> messages)
209209
var model = KnownModels.GetModel(path, chat!.Model);
210210
var modelKey = model.FileName;
211211

212-
var kernelMemory = CreateMemory(modelKey, path);
212+
var kernelMemory = CreateMemory(modelKey, path, out var generator);
213213

214214
if (textData != null)
215215
{
@@ -251,13 +251,15 @@ private void AddMessagesToHistory(ChatSession session, List<Message> messages)
251251
Role = AuthorRole.Assistant.ToString()
252252
}
253253
};
254+
255+
generator.Dispose();
254256

255257
return chatResult;
256258
}
257259

258260

259261
[Experimental("KMEXP01")]
260-
private static IKernelMemory CreateMemory(string modelName, string path)
262+
private static IKernelMemory CreateMemory(string modelName, string path, out KernelMemFix.LlamaSharpTextGenerator generator)
261263
{
262264
InferenceParams infParams = new() { AntiPrompts = ["INFO", "<|im_end|>", "Question:"] };
263265

@@ -280,7 +282,7 @@ private static IKernelMemory CreateMemory(string modelName, string path)
280282

281283
return new KernelMemoryBuilder()
282284
//.WithLLamaSharpDefaults2(lsConfig)
283-
.WithLLamaSharpMaINTemp(lsConfig, Path.Combine(path, modelName))
285+
.WithLLamaSharpMaINTemp(lsConfig, Path.Combine(path, modelName), out generator)
284286
.WithSearchClientConfig(searchClientConfig)
285287
.WithCustomImageOcr(new OcrWrapper())
286288
.With(parseOptions)
@@ -325,10 +327,10 @@ public Task CleanSessionCache(string id)
325327
}
326328
}
327329

328-
file static class KernelMemFix
330+
internal static class KernelMemFix
329331
{
330332
[Experimental("KMEXP00")]
331-
public sealed class LlamaSharpTextGenerator2 : ITextGenerator, ITextTokenizer, IDisposable
333+
public sealed class LlamaSharpTextGenerator : ITextGenerator, ITextTokenizer, IDisposable
332334
{
333335
private readonly StatelessExecutor _executor;
334336
private readonly LLamaWeights _weights;
@@ -339,22 +341,8 @@ public sealed class LlamaSharpTextGenerator2 : ITextGenerator, ITextTokenizer, I
339341

340342
public int MaxTokenTotal { get; }
341343

342-
public LlamaSharpTextGenerator2(LLamaSharpConfig config)
343-
{
344-
ModelParams @params = new ModelParams(config.ModelPath)
345-
{
346-
ContextSize = new uint?(config.ContextSize.GetValueOrDefault(2048U)),
347-
GpuLayerCount = config.GpuLayerCount.GetValueOrDefault(20)
348-
};
349-
this._weights = LLamaWeights.LoadFromFile((IModelParams) @params);
350-
this._context = this._weights.CreateContext((IContextParams) @params);
351-
this._executor = new StatelessExecutor(this._weights, (IContextParams) @params);
352-
this._defaultInferenceParams = config.DefaultInferenceParams;
353-
this._ownsWeights = this._ownsContext = true;
354-
this.MaxTokenTotal = (int) @params.ContextSize.Value;
355-
}
356344

357-
public LlamaSharpTextGenerator2(
345+
public LlamaSharpTextGenerator(
358346
LLamaWeights weights,
359347
LLamaContext context,
360348
StatelessExecutor? executor = null,
@@ -431,45 +419,19 @@ public IReadOnlyList<string> GetTokens(string text)
431419
}
432420

433421
[Experimental("KMEXP00")]
434-
public static IKernelMemoryBuilder WithLLamaSharpTextGeneration2(
422+
public static IKernelMemoryBuilder WithLLamaSharpTextGeneration(
435423
this IKernelMemoryBuilder builder,
436-
LlamaSharpTextGenerator2 textGenerator)
424+
LlamaSharpTextGenerator textGenerator)
437425
{
438426
builder.AddSingleton((ITextGenerator) textGenerator);
439427
return builder;
440428
}
441429

442-
[Experimental("KMEXP00")]
443-
public static IKernelMemoryBuilder WithLLamaSharpDefaults2(
444-
this IKernelMemoryBuilder builder,
445-
LLamaSharpConfig config,
446-
LLamaWeights? weights = null,
447-
LLamaContext? context = null)
448-
{
449-
ModelParams @params = new ModelParams(config.ModelPath)
450-
{
451-
ContextSize = new uint?(config.ContextSize.GetValueOrDefault(2048U)),
452-
GpuLayerCount = config.GpuLayerCount.GetValueOrDefault(20),
453-
MainGpu = config.MainGpu,
454-
SplitMode = new GPUSplitMode?(config.SplitMode)
455-
};
456-
if (weights == null || context == null)
457-
{
458-
weights = LLamaWeights.LoadFromFile((IModelParams) @params);
459-
context = weights.CreateContext((IContextParams) @params);
460-
}
461-
StatelessExecutor executor = new StatelessExecutor(weights, (IContextParams) @params);
462-
builder.WithLLamaSharpTextEmbeddingGeneration(new LLamaSharpTextEmbeddingGenerator(config, weights));
463-
builder.WithLLamaSharpTextGeneration2(new LlamaSharpTextGenerator2(weights, context, executor,
464-
config.DefaultInferenceParams));
465-
return builder;
466-
}
467-
468430
private static readonly ConcurrentDictionary<string, LLamaWeights> ModelCache = new();
469431

470432
[Experimental("KMEXP01")]
471433
public static IKernelMemoryBuilder WithLLamaSharpMaINTemp(this IKernelMemoryBuilder builder,
472-
LLamaSharpConfig config, string modelPath)
434+
LLamaSharpConfig config, string modelPath, out LlamaSharpTextGenerator generator)
473435
{
474436
// Create ModelParams for the first model.
475437
var parameters1 = new ModelParams(modelPath)
@@ -495,26 +457,19 @@ public static IKernelMemoryBuilder WithLLamaSharpMaINTemp(this IKernelMemoryBuil
495457
var weights = GetOrLoadModel(parameters2);
496458

497459
var context = model.CreateContext(parameters2);
498-
499460
StatelessExecutor executor = new StatelessExecutor(model, parameters2);
461+
462+
generator = new LlamaSharpTextGenerator(model, context, executor,
463+
config.DefaultInferenceParams);
464+
500465
builder.WithLLamaSharpTextEmbeddingGeneration(new LLamaSharpTextEmbeddingGenerator(config, weights));
501-
builder.WithLLamaSharpTextGeneration2(new LlamaSharpTextGenerator2(model, context, executor,
502-
config.DefaultInferenceParams));
466+
builder.WithLLamaSharpTextGeneration(generator);
503467
return builder;
504468
}
505469

506470
private static LLamaWeights GetOrLoadModel(ModelParams modelParams)
507471
{
508-
// Use a unique key based on the serialized ModelParams object.
509-
string cacheKey = GenerateCacheKey(modelParams);
510-
511-
// Retrieve from cache or load if not already cached.
512-
return ModelCache.GetOrAdd(cacheKey, _ => LLamaWeights.LoadFromFile(modelParams));
472+
return LLamaWeights.LoadFromFile(modelParams);
513473
}
514474

515-
private static string GenerateCacheKey(ModelParams modelParams)
516-
{
517-
// Create a unique key by combining important properties of ModelParams.
518-
return $"{modelParams.ModelPath}:{modelParams.ContextSize}:{modelParams.GpuLayerCount}:{modelParams.MainGpu}:{modelParams.SplitMode}";
519-
}
520475
}

0 commit comments

Comments
 (0)