1- using System . Runtime . CompilerServices ;
2- using Microsoft . Extensions . AI ;
3- using Microsoft . SemanticKernel ;
4- using Microsoft . SemanticKernel . ChatCompletion ;
5- using Microsoft . SemanticKernel . TextGeneration ;
6- using Together ;
7- using Together . Models . ChatCompletions ;
8- using TextContent = Microsoft . SemanticKernel . TextContent ;
1+ using System . Diagnostics ;
2+ using System . Diagnostics . Metrics ;
3+ using System . Runtime . CompilerServices ;
94using System . Text . Json ;
105using Microsoft . Extensions . Logging ;
11- using System . Diagnostics ;
12- using System . Diagnostics . Metrics ;
136using Microsoft . Extensions . Logging . Abstractions ;
7+ using Microsoft . SemanticKernel ;
8+ using Microsoft . SemanticKernel . ChatCompletion ;
9+ using Microsoft . SemanticKernel . TextGeneration ;
1410using Together . Models . ChatCompletions ;
1511using Together . Models . Common ;
1612using Together . SemanticKernel . Extensions ;
13+ using TextContent = Microsoft . SemanticKernel . TextContent ;
1714
1815namespace Together . SemanticKernel . Services ;
1916
@@ -27,11 +24,11 @@ public sealed class TogetherChatCompletionService : IChatCompletionService, ITex
2724 s_meter . CreateCounter < int > ( "semantic_kernel.connectors.together.tokens.completion" ) ;
2825
2926 private static readonly Counter < int > s_totalTokensCounter = s_meter . CreateCounter < int > ( "semantic_kernel.connectors.together.tokens.total" ) ;
27+ private readonly Dictionary < string , object ? > _attributes = new ( ) ;
3028
3129 private readonly TogetherClient _client ;
32- private readonly string _model ;
33- private readonly Dictionary < string , object ? > _attributes = new ( ) ;
3430 private readonly ILogger < TogetherChatCompletionService > _logger ;
31+ private readonly string _model ;
3532
3633 public TogetherChatCompletionService ( TogetherClient togetherClient , string model , ILogger < TogetherChatCompletionService > ? logger )
3734 {
@@ -53,7 +50,7 @@ public async Task<IReadOnlyList<ChatMessageContent>> GetChatMessageContentsAsync
5350 {
5451 using var activity = StartActivity ( "ChatCompletion" ) ;
5552
56- for ( int requestIndex = 0 ; ; requestIndex ++ )
53+ for ( var requestIndex = 0 ; ; requestIndex ++ )
5754 {
5855 var request = new ChatCompletionRequest
5956 {
@@ -79,7 +76,9 @@ public async Task<IReadOnlyList<ChatMessageContent>> GetChatMessageContentsAsync
7976
8077 if ( response . Choices ? . FirstOrDefault ( )
8178 ? . Message == null )
79+ {
8280 return Array . Empty < ChatMessageContent > ( ) ;
81+ }
8382
8483 var result = response . Choices . First ( ) ;
8584 var messageContent = CreateChatMessageContent ( new ChatCompletionMessage
@@ -122,7 +121,6 @@ public async Task<IReadOnlyList<ChatMessageContent>> GetChatMessageContentsAsync
122121 } , kernel , chatHistory , cancellationToken ) )
123122 {
124123 _logger . LogWarning ( "Failed to process tool call: {ToolCall}" , toolCall . Function ? . Name ) ;
125- continue ;
126124 }
127125 }
128126
@@ -149,11 +147,66 @@ public async Task<IReadOnlyList<ChatMessageContent>> GetChatMessageContentsAsync
149147 }
150148 }
151149
150+ public async IAsyncEnumerable < StreamingChatMessageContent > GetStreamingChatMessageContentsAsync ( ChatHistory chatHistory ,
151+ PromptExecutionSettings ? executionSettings = null , Kernel ? kernel = null ,
152+ [ EnumeratorCancellation ] CancellationToken cancellationToken = default )
153+ {
154+ var request = new ChatCompletionRequest
155+ {
156+ Model = _model ,
157+ Messages = chatHistory . ToChatCompletionMessages ( )
158+ . ToList ( ) ,
159+ Stream = true
160+ } ;
161+ if ( kernel != null && executionSettings ? . ExtensionData ? . ContainsKey ( "tool_choice" ) == true )
162+ {
163+ ConfigureTools ( kernel , request ) ;
164+ }
165+
166+ var stream = _client . ChatCompletions . CreateStreamAsync ( request , cancellationToken ) ;
167+
168+ await foreach ( var chunk in stream )
169+ {
170+ foreach ( var choice in chunk . Choices )
171+ {
172+ yield return new StreamingChatMessageContent ( AuthorRole . Assistant , choice . Delta ? . Content , null , choice . Index . GetValueOrDefault ( ) ,
173+ chunk . Model ) ;
174+ }
175+ }
176+ }
177+
178+ public Task < IReadOnlyList < TextContent > > GetTextContentsAsync ( string prompt , PromptExecutionSettings ? executionSettings = null ,
179+ Kernel ? kernel = null , CancellationToken cancellationToken = default )
180+ {
181+ // Convert text prompt to chat format
182+ var chatHistory = new ChatHistory ( ) ;
183+ chatHistory . AddUserMessage ( prompt ) ;
184+ return GetChatMessageContentsAsync ( chatHistory , executionSettings , kernel , cancellationToken )
185+ . ContinueWith ( t => ( IReadOnlyList < TextContent > ) t . Result
186+ . Select ( m => new TextContent ( m . Content ) )
187+ . ToList ( ) , cancellationToken ) ;
188+ }
189+
190+ public async IAsyncEnumerable < StreamingTextContent > GetStreamingTextContentsAsync ( string prompt ,
191+ PromptExecutionSettings ? executionSettings = null , Kernel ? kernel = null ,
192+ [ EnumeratorCancellation ] CancellationToken cancellationToken = default )
193+ {
194+ var chatHistory = new ChatHistory ( ) ;
195+ chatHistory . AddUserMessage ( prompt ) ;
196+
197+ await foreach ( var message in GetStreamingChatMessageContentsAsync ( chatHistory , executionSettings , kernel , cancellationToken ) )
198+ {
199+ yield return new StreamingTextContent ( message . Content ) ;
200+ }
201+ }
202+
152203 // Modified to async: renamed to ProcessToolCallAsync
153204 private async Task < bool > ProcessToolCallAsync ( ToolCall toolCall , Kernel ? kernel , ChatHistory chatHistory , CancellationToken cancellationToken )
154205 {
155206 if ( kernel == null || string . IsNullOrEmpty ( toolCall . Function ? . Name ) )
207+ {
156208 return false ;
209+ }
157210
158211 try
159212 {
@@ -194,23 +247,25 @@ private KernelArguments ParseArguments(string argumentJson)
194247 }
195248 }
196249
197- private record ToolConfiguration ( bool HasTools , bool AutoInvoke , int MaxAttempts ) ;
198-
199250 private ToolConfiguration GetToolConfiguration ( Kernel ? kernel , PromptExecutionSettings ? settings , int requestIndex )
200251 {
201252 if ( kernel == null )
253+ {
202254 return new ToolConfiguration ( false , false , 0 ) ;
255+ }
203256
204257 // Check if kernel has any plugins/functions available
205258 var hasTools = kernel . Plugins
206259 . GetFunctionsMetadata ( )
207260 . Any ( ) ;
208261 if ( ! hasTools )
262+ {
209263 return new ToolConfiguration ( false , false , 0 ) ;
264+ }
210265
211266 // Check execution settings
212- bool autoInvoke = false ;
213- int maxAttempts = 1 ;
267+ var autoInvoke = false ;
268+ var maxAttempts = 1 ;
214269
215270 if ( settings ? . ExtensionData != null )
216271 {
@@ -231,20 +286,23 @@ private ToolConfiguration GetToolConfiguration(Kernel? kernel, PromptExecutionSe
231286 return new ToolConfiguration ( hasTools , autoInvoke , maxAttempts ) ;
232287 }
233288
234- private record FunctionName ( string PluginName , string Name ) ;
235-
236289 private FunctionName ParseFunctionName ( string fullName )
237290 {
238291 var parts = fullName . Split ( ':' ) ;
239292 return parts . Length > 1 ? new FunctionName ( parts [ 0 ] , parts [ 1 ] ) : new FunctionName ( string . Empty , parts [ 0 ] ) ;
240293 }
241294
242- private Activity ? StartActivity ( string name ) =>
243- Activity . Current ? . Source . StartActivity ( name ) ;
295+ private Activity ? StartActivity ( string name )
296+ {
297+ return Activity . Current ? . Source . StartActivity ( name ) ;
298+ }
244299
245300 private void LogUsage ( UsageData ? usage )
246301 {
247- if ( usage == null ) return ;
302+ if ( usage == null )
303+ {
304+ return ;
305+ }
248306
249307 s_promptTokensCounter . Add ( usage . PromptTokens ) ;
250308 s_completionTokensCounter . Add ( usage . CompletionTokens ) ;
@@ -254,22 +312,26 @@ private void LogUsage(UsageData? usage)
254312 usage . CompletionTokens , usage . TotalTokens ) ;
255313 }
256314
257- private ChatMessageContent CreateChatMessageContent ( ChatCompletionMessage message ) =>
258- new ChatMessageContent ( AuthorRole . Assistant , message . Content , metadata : new Dictionary < string , object ? >
315+ private ChatMessageContent CreateChatMessageContent ( ChatCompletionMessage message )
316+ {
317+ return new ChatMessageContent ( AuthorRole . Assistant , message . Content , metadata : new Dictionary < string , object ? >
259318 {
260319 { "tool_calls" , message . ToolCalls }
261320 } ) ;
321+ }
262322
263323 private void ConfigureTools ( Kernel kernel , ChatCompletionRequest request )
264324 {
265325 var functions = kernel . Plugins . GetFunctionsMetadata ( ) ;
266326 if ( ! functions . Any ( ) )
327+ {
267328 return ;
329+ }
268330
269- request . Tools = functions . Select ( f => new Together . Models . ChatCompletions . Tool
331+ request . Tools = functions . Select ( f => new Tool
270332 {
271333 Type = "function" ,
272- Function = new Together . Models . ChatCompletions . FunctionTool
334+ Function = new FunctionTool
273335 {
274336 Name = $ "{ f . PluginName } :{ f . Name } ",
275337 Description = f . Description ,
@@ -291,66 +353,13 @@ private void ConfigureTools(Kernel kernel, ChatCompletionRequest request)
291353 } )
292354 . ToList ( ) ;
293355
294- request . ToolChoice = new Together . Models . ChatCompletions . ToolChoice
356+ request . ToolChoice = new ToolChoice
295357 {
296358 Type = "auto" ,
297- Function = new Together . Models . ChatCompletions . FunctionToolChoice { Name = "auto" }
359+ Function = new FunctionToolChoice { Name = "auto" }
298360 } ;
299361 }
300362
301- public async IAsyncEnumerable < StreamingChatMessageContent > GetStreamingChatMessageContentsAsync ( ChatHistory chatHistory ,
302- PromptExecutionSettings ? executionSettings = null , Kernel ? kernel = null ,
303- [ EnumeratorCancellation ] CancellationToken cancellationToken = default )
304- {
305- var request = new ChatCompletionRequest
306- {
307- Model = _model ,
308- Messages = chatHistory . ToChatCompletionMessages ( )
309- . ToList ( ) ,
310- Stream = true
311- } ;
312- if ( kernel != null && executionSettings ? . ExtensionData ? . ContainsKey ( "tool_choice" ) == true )
313- {
314- ConfigureTools ( kernel , request ) ;
315- }
316-
317- var stream = _client . ChatCompletions . CreateStreamAsync ( request , cancellationToken ) ;
318-
319- await foreach ( var chunk in stream )
320- {
321- foreach ( var choice in chunk . Choices )
322- {
323- yield return new StreamingChatMessageContent ( AuthorRole . Assistant , choice . Delta ? . Content , null , choice . Index . GetValueOrDefault ( ) ,
324- chunk . Model ) ;
325- }
326- }
327- }
328-
329- public Task < IReadOnlyList < TextContent > > GetTextContentsAsync ( string prompt , PromptExecutionSettings ? executionSettings = null ,
330- Kernel ? kernel = null , CancellationToken cancellationToken = default )
331- {
332- // Convert text prompt to chat format
333- var chatHistory = new ChatHistory ( ) ;
334- chatHistory . AddUserMessage ( prompt ) ;
335- return GetChatMessageContentsAsync ( chatHistory , executionSettings , kernel , cancellationToken )
336- . ContinueWith ( t => ( IReadOnlyList < TextContent > ) t . Result
337- . Select ( m => new TextContent ( m . Content ) )
338- . ToList ( ) , cancellationToken ) ;
339- }
340-
341- public async IAsyncEnumerable < StreamingTextContent > GetStreamingTextContentsAsync ( string prompt ,
342- PromptExecutionSettings ? executionSettings = null , Kernel ? kernel = null ,
343- [ EnumeratorCancellation ] CancellationToken cancellationToken = default )
344- {
345- var chatHistory = new ChatHistory ( ) ;
346- chatHistory . AddUserMessage ( prompt ) ;
347-
348- await foreach ( var message in GetStreamingChatMessageContentsAsync ( chatHistory , executionSettings , kernel , cancellationToken ) )
349- {
350- yield return new StreamingTextContent ( message . Content ) ;
351- }
352- }
353-
354363 private async Task < ChatCompletionResponse > GetCompletionAsync ( IEnumerable < ChatCompletionMessage > messages ,
355364 PromptExecutionSettings ? settings = null , CancellationToken cancellationToken = default )
356365 {
@@ -368,10 +377,14 @@ private async Task<ChatCompletionResponse> GetCompletionAsync(IEnumerable<ChatCo
368377 {
369378 Messages = messages . ToList ( ) ,
370379 Model = _model ,
371- Stream = false ,
380+ Stream = false
372381 //Options = options
373382 } ;
374383
375384 return await _client . ChatCompletions . CreateAsync ( request , cancellationToken ) ;
376385 }
386+
387+ private record ToolConfiguration ( bool HasTools , bool AutoInvoke , int MaxAttempts ) ;
388+
389+ private record FunctionName ( string PluginName , string Name ) ;
377390}
0 commit comments