Skip to content

Commit 3e880a3

Browse files
committed
api tests
1 parent fedf8a4 commit 3e880a3

File tree

8 files changed

+126
-123
lines changed

8 files changed

+126
-123
lines changed

Directory.Build.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
3434
</PropertyGroup>
3535
<ItemGroup>
36-
<None Include="$(SolutionDir)\logo.png" Pack="true" Visible="false" PackagePath="\" />
37-
<None Include="$(SolutionDir)\README.md" Pack="true" Visible="false" PackagePath="\" />
36+
<None Include="$(SolutionDir)\logo.png" Pack="true" Visible="false" PackagePath="\"/>
37+
<None Include="$(SolutionDir)\README.md" Pack="true" Visible="false" PackagePath="\"/>
3838
</ItemGroup>
3939
<ItemGroup>
4040
<PackageReference Update="DotNet.ReproducibleBuilds" Version="1.2.25">

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,13 @@ var images = await imageService.GetImageContentsAsync(
9393

9494
## 📚 Documentation
9595

96-
For more information about available models and features, visit the [Together.ai Documentation](https://docs.together.ai/)
96+
For more information about available models and features, visit
97+
the [Together.ai Documentation](https://docs.together.ai/)
9798

9899
## 💪 Contributing
99100

100101
Contributions are welcome! Feel free to:
102+
101103
- Open issues for bugs or feature requests
102104
- Submit pull requests
103105
- Improve documentation

Together.SemanticKernel/Services/TogetherChatCompletionService.cs

Lines changed: 96 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
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;
94
using System.Text.Json;
105
using Microsoft.Extensions.Logging;
11-
using System.Diagnostics;
12-
using System.Diagnostics.Metrics;
136
using Microsoft.Extensions.Logging.Abstractions;
7+
using Microsoft.SemanticKernel;
8+
using Microsoft.SemanticKernel.ChatCompletion;
9+
using Microsoft.SemanticKernel.TextGeneration;
1410
using Together.Models.ChatCompletions;
1511
using Together.Models.Common;
1612
using Together.SemanticKernel.Extensions;
13+
using TextContent = Microsoft.SemanticKernel.TextContent;
1714

1815
namespace 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
}

Together.SemanticKernel/Together.SemanticKernel.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</ItemGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="Microsoft.SemanticKernel.Core" Version="1.36.1" />
12+
<PackageReference Include="Microsoft.SemanticKernel.Core" Version="1.36.1"/>
1313
</ItemGroup>
1414

1515

0 commit comments

Comments
 (0)