11using Liquid . Core . Entities ;
2- using Liquid . Core . Interfaces ;
3- using Liquid . Core . Settings ;
2+ using Liquid . Core . GenAi ;
3+ using Liquid . Core . GenAi . Entities ;
4+ using Liquid . Core . GenAi . Enums ;
5+ using Liquid . Core . GenAi . Settings ;
46using OpenAI . Chat ;
57using System . Diagnostics . CodeAnalysis ;
68
7- namespace Liquid . ChatCompletions . OpenAi
9+ namespace Liquid . GenAi . OpenAi
810{
911 ///<inheritdoc/>
1012 [ ExcludeFromCodeCoverage ]
11- public class OpenAiChatCompletions : ILiquidChatCompletions
13+ public class OpenAiAdapter : ILiquidGenAi
1214 {
1315
1416 private readonly IOpenAiClientFactory _factory ;
1517 /// <summary>
16- /// Initialize a new instance of <see cref="OpenAiChatCompletions "/>
18+ /// Initialize a new instance of <see cref="OpenAiAdapter "/>
1719 /// </summary>
1820 /// <param name="factory">Open IA client Factory.</param>
1921 /// <exception cref="ArgumentNullException"></exception>
20- public OpenAiChatCompletions ( IOpenAiClientFactory factory )
22+ public OpenAiAdapter ( IOpenAiClientFactory factory )
2123 {
2224 _factory = factory ?? throw new ArgumentNullException ( nameof ( factory ) ) ;
2325 }
2426
2527 ///<inheritdoc/>
26- public async Task < ChatCompletionResult > FunctionCalling ( ChatMessages messages , List < FunctionBody > functions , CompletionsSettings settings )
28+ public async Task < ChatCompletionResult > FunctionCalling ( LiquidChatMessages messages , List < FunctionBody > functions , CompletionsOptions settings )
2729 {
2830 var client = _factory . GetOpenAIClient ( settings . ClientId ) ;
2931
30- var requestMessages = new List < OpenAI . Chat . ChatMessage > ( ) ;
32+ var requestMessages = new List < ChatMessage > ( ) ;
3133
3234 messages . Messages . ForEach ( m => requestMessages . Add ( MapChatRequestMessage ( m ) ) ) ;
3335
34- var option = MapChatCompletionOptions ( requestMessages , settings ) ;
36+ var option = MapChatCompletionOptions ( settings ) ;
3537
3638 functions . ForEach ( f => option . Tools . Add ( ChatTool . CreateFunctionTool ( f . Name , f . Description , f . Parameters ) ) ) ;
3739
@@ -51,13 +53,13 @@ public async Task<ChatCompletionResult> FunctionCalling(ChatMessages messages, L
5153 }
5254
5355 ///<inheritdoc/>
54- public async Task < ChatCompletionResult > ChatCompletions ( string content , string prompt , CompletionsSettings settings , ChatMessages ? chatHistory = null )
56+ public async Task < ChatCompletionResult > CompleteChatAsync ( string content , string prompt , CompletionsOptions settings , LiquidChatMessages chatHistory = null )
5557 {
5658 var client = _factory . GetOpenAIClient ( settings . ClientId ) ;
5759
5860 var messages = GetChatMessagesAsync ( content , prompt , chatHistory ) ;
5961
60- var option = MapChatCompletionOptions ( messages , settings ) ;
62+ var option = MapChatCompletionOptions ( settings ) ;
6163
6264 var responseWithoutStream = await client . CompleteChatAsync ( messages , option ) ;
6365 var response = responseWithoutStream . Value . Content [ 0 ] . Text ;
@@ -75,29 +77,54 @@ public async Task<ChatCompletionResult> ChatCompletions(string content, string p
7577 }
7678
7779 ///<inheritdoc/>
78- public async Task < ReadOnlyMemory < float > > GetEmbeddings ( string description , string modelName , string clientId )
80+ public async Task < ChatCompletionResult > CompleteChatAsync ( LiquidChatMessages messages , CompletionsOptions settings , List < FunctionBody > functions = null , LiquidChatMessages chatHistory = null )
7981 {
80- // var client = _factory.GetOpenAIClient(clientId );
82+ var client = _factory . GetOpenAIClient ( settings . ClientId ) ;
8183
82- //EmbeddingGenerationOptions embeddingsOptions = new(modelName, new string[] { description } );
84+ var requestMessages = new List < ChatMessage > ( ) ;
8385
84- //var embeddings = await client.(embeddingsOptions );
86+ messages . Messages . ForEach ( m => requestMessages . Add ( MapChatRequestMessage ( m ) ) ) ;
8587
86- //return embeddings.Value.Data[0].Embedding ;
88+ var option = MapChatCompletionOptions ( settings ) ;
8789
88- throw new NotImplementedException ( ) ;
89- }
90+ var responseWithoutStream = await client . CompleteChatAsync ( requestMessages , option ) ;
9091
92+ if ( functions != null )
93+ {
94+ functions . ForEach ( f => option . Tools . Add ( ChatTool . CreateFunctionTool ( f . Name , f . Description , f . Parameters ) ) ) ;
95+ }
96+
97+ if ( chatHistory ? . Messages != null && chatHistory . Messages . Count > 0 )
98+ {
99+ foreach ( var message in chatHistory . Messages )
100+ {
101+ requestMessages . Add ( MapChatRequestMessage ( message ) ) ;
102+ }
103+ }
104+
105+ var response = responseWithoutStream . Value . Content [ 0 ] . Text ;
106+
107+ var result = new ChatCompletionResult ( )
108+ {
109+ FinishReason = responseWithoutStream . Value . FinishReason . ToString ( ) ,
110+ Content = response ,
111+ Usage = responseWithoutStream . Value . Usage . TotalTokenCount ,
112+ PromptUsage = responseWithoutStream . Value . Usage . InputTokenCount ,
113+ CompletionUsage = responseWithoutStream . Value . Usage . OutputTokenCount ,
114+ } ;
115+
116+ return result ;
117+ }
91118
92119 /// <summary>
93120 /// get chat messages for a chat completions request.
94121 /// </summary>
95122 /// <param name="content">content of the user message</param>
96123 /// <param name="prompt">prompt message</param>
97124 /// <param name="chatHistory">chat context messages</param>
98- private List < OpenAI . Chat . ChatMessage > GetChatMessagesAsync ( string content , string prompt , ChatMessages ? chatHistory = null )
125+ private static List < ChatMessage > GetChatMessagesAsync ( string content , string prompt , LiquidChatMessages ? chatHistory = null )
99126 {
100- var messages = new List < OpenAI . Chat . ChatMessage >
127+ var messages = new List < ChatMessage >
101128 {
102129 new SystemChatMessage ( prompt )
103130 } ;
@@ -120,45 +147,57 @@ public async Task<ReadOnlyMemory<float>> GetEmbeddings(string description, strin
120147 /// </summary>
121148 /// <param name="message">chat message</param>
122149 /// <exception cref="ArgumentNullException"></exception>
123- private OpenAI . Chat . ChatMessage MapChatRequestMessage ( Core . Entities . ChatMessage message )
150+ private static ChatMessage MapChatRequestMessage ( LiquidChatMessage message )
124151 {
125- OpenAI . Chat . ChatMessage chatRequestMessage = null ;
152+ ChatMessage ? chatRequestMessage = null ;
126153 switch ( message . Role . ToLower ( ) )
127154 {
128155 case "system" :
129- chatRequestMessage = new SystemChatMessage ( message . Content ) ;
156+ chatRequestMessage = new SystemChatMessage ( CreateContent ( message ) ) ;
130157 break ;
131158 case "assistant" :
132- chatRequestMessage = new AssistantChatMessage ( message . Content ) ;
159+ chatRequestMessage = new AssistantChatMessage ( CreateContent ( message ) ) ;
133160 break ;
134161 case "user" :
135- chatRequestMessage = new UserChatMessage ( message . Content ) ;
162+ chatRequestMessage = new UserChatMessage ( CreateContent ( message ) ) ;
136163 break ;
137164 default :
138165 break ;
139166 }
140167
141168 if ( chatRequestMessage == null )
142169 {
143- throw new ArgumentNullException ( nameof ( chatRequestMessage ) ) ;
170+ throw new ApplicationException ( $ "The folowing message is invalid: { message } " ) ;
144171 }
145172
146173 return chatRequestMessage ;
147174 }
148175
176+ private static IEnumerable < ChatMessageContentPart > CreateContent ( LiquidChatMessage message )
177+ {
178+ var messageList = message . Content . ToList ( ) ;
179+
180+ var content = new List < ChatMessageContentPart > ( ) ;
181+
182+ messageList . ForEach ( x => content . Add ( x . Kind == LiquidContentKind . Text ?
183+ ChatMessageContentPart . CreateTextPart ( x . Text ) :
184+ ChatMessageContentPart . CreateImagePart ( x . ImageUri ) ) ) ;
185+
186+ return content ;
187+ }
188+
149189 /// <summary>
150190 /// Return a chat completions options based on the chat completions settings.
151191 /// </summary>
152- /// <param name="messages">Chat messages </param>
153192 /// <param name="settings">Chat completions settings</param>
154193 /// <returns></returns>
155- private ChatCompletionOptions MapChatCompletionOptions ( List < OpenAI . Chat . ChatMessage > messages , CompletionsSettings settings )
194+ private static ChatCompletionOptions MapChatCompletionOptions ( CompletionsOptions settings )
156195 {
157196 return new ChatCompletionOptions ( )
158197 {
159198 Temperature = settings . Temperature ,
160199 MaxOutputTokenCount = settings . MaxTokens ,
161- TopP = settings . NucleusSamplingFactor ,
200+ TopP = settings . TopP ,
162201 FrequencyPenalty = settings . FrequencyPenalty ,
163202 PresencePenalty = settings . PresencePenalty
164203
0 commit comments