1+ using System . Text ;
2+ using MaIN . Domain . Configuration ;
3+ using MaIN . Domain . Entities ;
4+ using MaIN . Services . Constants ;
5+ using MaIN . Services . Services . Abstract ;
6+ using MaIN . Services . Services . LLMService . Memory ;
7+ using MaIN . Services . Services . Models ;
8+ using Microsoft . Extensions . Logging ;
9+
10+ namespace MaIN . Services . Services . LLMService ;
11+
12+ public sealed class OllamaService (
13+ MaINSettings settings ,
14+ INotificationService notificationService ,
15+ IHttpClientFactory httpClientFactory ,
16+ IMemoryFactory memoryFactory ,
17+ IMemoryService memoryService ,
18+ ILogger < OpenAiService > ? logger = null )
19+ : OpenAiCompatibleService ( notificationService , httpClientFactory , memoryFactory , memoryService , logger )
20+ {
21+ private readonly MaINSettings _settings = settings ?? throw new ArgumentNullException ( nameof ( settings ) ) ;
22+
23+ protected override string HttpClientName => ServiceConstants . HttpClients . OllamaClient ;
24+ protected override string ChatCompletionsUrl => ServiceConstants . ApiUrls . OllamaOpenAiChatCompletions ;
25+ protected override string ModelsUrl => ServiceConstants . ApiUrls . OllamaModels ;
26+
27+ protected override string GetApiKey ( )
28+ {
29+ return _settings . OllamaKey ?? Environment . GetEnvironmentVariable ( "OLLAMA_API_KEY" ) ??
30+ throw new InvalidOperationException ( "Olama Key not configured" ) ;
31+ }
32+
33+ protected override void ValidateApiKey ( )
34+ {
35+ if ( string . IsNullOrEmpty ( _settings . OllamaKey ) && string . IsNullOrEmpty ( Environment . GetEnvironmentVariable ( "OLLAMA_API_KEY" ) ) )
36+ {
37+ throw new InvalidOperationException ( "Ollama Key not configured" ) ;
38+ }
39+ }
40+
41+ public override async Task < ChatResult ? > AskMemory (
42+ Chat chat ,
43+ ChatMemoryOptions memoryOptions ,
44+ ChatRequestOptions requestOptions ,
45+ CancellationToken cancellationToken = default )
46+ {
47+ var lastMsg = chat . Messages . Last ( ) ;
48+ var filePaths = await DocumentProcessor . ConvertToFilesContent ( memoryOptions ) ;
49+ var message = new Message ( )
50+ {
51+ Role = ServiceConstants . Roles . User ,
52+ Content = ComposeMessage ( lastMsg , filePaths ) ,
53+ Type = MessageType . CloudLLM
54+ } ;
55+
56+ chat . Messages . Last ( ) . Content = message . Content ;
57+ chat . Messages . Last ( ) . Files = [ ] ;
58+ var result = await Send ( chat , new ChatRequestOptions ( ) , cancellationToken ) ;
59+ chat . Messages . Last ( ) . Content = lastMsg . Content ;
60+ return result ;
61+ }
62+
63+ private string ComposeMessage ( Message lastMsg , string [ ] filePaths )
64+ {
65+ var stringBuilder = new StringBuilder ( ) ;
66+ stringBuilder . AppendLine ( $ "== FILES IN MEMORY") ;
67+ foreach ( var path in filePaths )
68+ {
69+ var doc = DocumentProcessor . ProcessDocument ( path ) ;
70+ stringBuilder . Append ( doc ) ;
71+ stringBuilder . AppendLine ( ) ;
72+ }
73+ stringBuilder . AppendLine ( $ "== END OF FILES") ;
74+ stringBuilder . AppendLine ( ) ;
75+ stringBuilder . Append ( lastMsg . Content ) ;
76+ return stringBuilder . ToString ( ) ;
77+ }
78+ }
0 commit comments