Skip to content

Commit 8a3e1b3

Browse files
Exclude from code coverage for now as there is untestable code at present
1 parent 6a6acb4 commit 8a3e1b3

File tree

7 files changed

+151
-10
lines changed

7 files changed

+151
-10
lines changed

.github/_typos.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ extend-exclude = [
2626
"SK-dotnet.sln.DotSettings",
2727
"**/azure_ai_search_hotel_samples/README.md",
2828
"**/Demos/ProcessFrameworkWithAspire/ProcessFramework.Aspire/ProcessFramework.Aspire.ProcessOrchestrator/Program.cs",
29-
"**/Demos/ProcessFrameworkWithAspire/**/*.http"
29+
"**/Demos/ProcessFrameworkWithAspire/**/*.http",
30+
"openai_responses_what_is_the_semantic_kernel.json"
3031
]
3132

3233
[default.extend-words]

dotnet/src/Agents/OpenAI/OpenAIResponsesAgent.cs

+3-8
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ namespace Microsoft.SemanticKernel.Agents.OpenAI;
1616
/// <summary>
1717
/// Represents a <see cref="KernelAgent"/> specialization based on Open AI Assistant / GPT.
1818
/// </summary>
19+
[ExcludeFromCodeCoverage]
1920
public sealed class OpenAIResponsesAgent : KernelAgent
2021
{
2122
/// <summary>
@@ -51,12 +52,6 @@ public override async IAsyncEnumerable<AgentResponseItem<ChatMessageContent>> In
5152
// Invoke responses with the updated chat history.
5253
var chatHistory = new ChatHistory();
5354
chatHistory.AddRange(messages);
54-
/*
55-
await foreach (var existingMessage in chatHistoryAgentThread.GetMessagesAsync(cancellationToken).ConfigureAwait(false))
56-
{
57-
chatHistory.Add(existingMessage);
58-
}
59-
*/
6055
var invokeResults = this.InternalInvokeAsync(
6156
this.Name,
6257
chatHistory,
@@ -80,7 +75,7 @@ public override IAsyncEnumerable<AgentResponseItem<StreamingChatMessageContent>>
8075

8176
/// <inheritdoc/>
8277
[Experimental("SKEXP0110")]
83-
protected override Task<AgentChannel> CreateChannelAsync(CancellationToken cancellationToken)
78+
protected override Task<AgentChannel> CreateChannelAsync(CancellationToken cancellationToken = default)
8479
{
8580
throw new NotImplementedException();
8681
}
@@ -94,7 +89,7 @@ protected override IEnumerable<string> GetChannelKeys()
9489

9590
/// <inheritdoc/>
9691
[Experimental("SKEXP0110")]
97-
protected override Task<AgentChannel> RestoreChannelAsync(string channelState, CancellationToken cancellationToken)
92+
protected override Task<AgentChannel> RestoreChannelAsync(string channelState, CancellationToken cancellationToken = default)
9893
{
9994
throw new NotImplementedException();
10095
}

dotnet/src/Agents/OpenAI/OpenAIResponsesAgentThread.cs

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
using System;
44
using System.Collections.Generic;
5+
using System.Diagnostics.CodeAnalysis;
56
using System.Runtime.CompilerServices;
67
using System.Threading;
78
using System.Threading.Tasks;
@@ -13,6 +14,7 @@ namespace Microsoft.SemanticKernel.Agents.OpenAI;
1314
/// <summary>
1415
/// Represents a conversation thread for an OpenAI responses-based agent.
1516
/// </summary>
17+
[ExcludeFromCodeCoverage]
1618
public sealed class OpenAIResponsesAgentThread : AgentThread
1719
{
1820
private readonly OpenAIResponseClient _client;

dotnet/src/Agents/UnitTests/Agents.UnitTests.csproj

+7
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@
4747
<ItemGroup>
4848
<Compile Include="$(RepoRoot)/dotnet/src/InternalUtilities/test/AssertExtensions.cs" Link="%(RecursiveDir)Test/%(Filename)%(Extension)" />
4949
<Compile Include="$(RepoRoot)/dotnet/src/InternalUtilities/test/HttpMessageHandlerStub.cs" Link="%(RecursiveDir)Test/%(Filename)%(Extension)" />
50+
<Compile Include="$(RepoRoot)/dotnet/src/InternalUtilities/test/MultipleHttpMessageHandlerStub.cs" Link="%(RecursiveDir)Test/%(Filename)%(Extension)" />
51+
</ItemGroup>
52+
53+
<ItemGroup>
54+
<None Update="TestData\openai_responses_what_is_the_semantic_kernel.json">
55+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
56+
</None>
5057
</ItemGroup>
5158

5259
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
using System;
4+
using System.ClientModel;
5+
using System.ClientModel.Primitives;
6+
using System.IO;
7+
using System.Linq;
8+
using System.Net.Http;
9+
using System.Threading.Tasks;
10+
using Microsoft.SemanticKernel;
11+
using Microsoft.SemanticKernel.Agents.OpenAI;
12+
using Microsoft.SemanticKernel.ChatCompletion;
13+
using OpenAI;
14+
using OpenAI.Responses;
15+
using Xunit;
16+
17+
namespace SemanticKernel.Agents.UnitTests.OpenAI;
18+
19+
/// <summary>
20+
/// Unit testing of <see cref="OpenAIResponsesAgent"/>.
21+
/// </summary>
22+
#pragma warning disable CS0419 // Ambiguous reference in cref attribute
23+
public sealed class OpenAIResponsesAgentTests : IDisposable
24+
{
25+
/// <summary>
26+
/// Initializes a new instance of objects required to test a <see cref="OpenAIResponsesAgent"/>.
27+
/// </summary>
28+
public OpenAIResponsesAgentTests()
29+
{
30+
this._messageHandlerStub = new MultipleHttpMessageHandlerStub();
31+
this._httpClient = new HttpClient(this._messageHandlerStub, disposeHandler: false);
32+
this._kernel = new Kernel();
33+
34+
var options = new OpenAIClientOptions
35+
{
36+
Transport = new HttpClientPipelineTransport(this._httpClient)
37+
};
38+
this._client = new(model: "gpt-4o", credential: new ApiKeyCredential("apikey"), options: options);
39+
}
40+
41+
/// <inheritdoc/>
42+
public void Dispose()
43+
{
44+
this._messageHandlerStub.Dispose();
45+
this._httpClient.Dispose();
46+
}
47+
48+
/// <summary>
49+
/// Verify InvokeAsync
50+
/// </summary>
51+
[Fact]
52+
public async Task VerifyInvokeAsync()
53+
{
54+
// Arrange
55+
this._messageHandlerStub.AddJsonResponse(File.ReadAllText(WhatIsTheSKResponseJson));
56+
OpenAIResponsesAgent agent = new(this._client)
57+
{
58+
Name = "ResponseAgent",
59+
Instructions = "Answer all queries in English and French.",
60+
};
61+
62+
// Act
63+
var responseItems = agent.InvokeAsync(new ChatMessageContent(AuthorRole.User, "What is the capital of France?"));
64+
65+
// Assert
66+
Assert.NotNull(responseItems);
67+
var messages = await responseItems.ToListAsync();
68+
Assert.Single(messages);
69+
Assert.Equal("The capital of France is Paris.\n\nLa capitale de la France est Paris.", messages[0].Message.Content);
70+
}
71+
72+
#region private
73+
private const string WhatIsTheSKResponseJson = "./TestData/openai_responses_what_is_the_semantic_kernel.json";
74+
75+
private readonly MultipleHttpMessageHandlerStub _messageHandlerStub;
76+
private readonly HttpClient _httpClient;
77+
private readonly Kernel _kernel;
78+
private readonly OpenAIResponseClient _client;
79+
#endregion
80+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"id": "resp_67e315cf0e148191a3424db903561ba704584dfd0b14dc67",
3+
"object": "response",
4+
"created_at": 1742935503,
5+
"status": "completed",
6+
"error": null,
7+
"incomplete_details": null,
8+
"instructions": "Answer all queries in English and French.",
9+
"max_output_tokens": null,
10+
"model": "gpt-4o-2024-08-06",
11+
"output": [
12+
{
13+
"type": "message",
14+
"id": "msg_67e315cf52f88191b5e63ef1d045b37e04584dfd0b14dc67",
15+
"status": "completed",
16+
"role": "assistant",
17+
"content": [
18+
{
19+
"type": "output_text",
20+
"text": "The capital of France is Paris.\n\nLa capitale de la France est Paris.",
21+
"annotations": []
22+
}
23+
]
24+
}
25+
],
26+
"parallel_tool_calls": true,
27+
"previous_response_id": null,
28+
"reasoning": {
29+
"effort": null,
30+
"generate_summary": null
31+
},
32+
"store": true,
33+
"temperature": 1.0,
34+
"text": {
35+
"format": {
36+
"type": "text"
37+
}
38+
},
39+
"tool_choice": "auto",
40+
"tools": [],
41+
"top_p": 1.0,
42+
"truncation": "disabled",
43+
"usage": {
44+
"input_tokens": 44,
45+
"input_tokens_details": {
46+
"cached_tokens": 0
47+
},
48+
"output_tokens": 16,
49+
"output_tokens_details": {
50+
"reasoning_tokens": 0
51+
},
52+
"total_tokens": 60
53+
},
54+
"user": "ResponseAgent",
55+
"metadata": {}
56+
}

dotnet/src/InternalUtilities/samples/AgentUtilities/BaseResponsesAgentTest.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ protected BaseResponsesAgentTest(ITestOutputHelper output) : base(output)
2828
this.Client = new(model: "gpt-4o", credential: new ApiKeyCredential(TestConfiguration.OpenAI.ApiKey), options: options);
2929
}
3030

31-
protected bool EnableLogging { get; set; } = false;
31+
protected bool EnableLogging { get; set; } = true;
3232

3333
/// <inheritdoc/>
3434
protected override OpenAIResponseClient Client { get; }

0 commit comments

Comments
 (0)