Skip to content

Commit 006a91f

Browse files
committed
Unit-tests draft
1 parent 218fa76 commit 006a91f

File tree

2 files changed

+259
-1
lines changed

2 files changed

+259
-1
lines changed

test/Libraries/Microsoft.Extensions.AI.OpenAI.Tests/Microsoft.Extensions.AI.OpenAI.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<RootNamespace>Microsoft.Extensions.AI</RootNamespace>
44
<Description>Unit tests for Microsoft.Extensions.AI.OpenAI</Description>
55
<NoWarn>$(NoWarn);S104</NoWarn>
6-
<NoWarn>$(NoWarn);OPENAI001;MEAI001</NoWarn>
6+
<NoWarn>$(NoWarn);OPENAI001;OPENAICUA001;MEAI001</NoWarn>
77
</PropertyGroup>
88

99
<PropertyGroup>

test/Libraries/Microsoft.Extensions.AI.OpenAI.Tests/OpenAIResponseClientTests.cs

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,264 @@ public async Task BasicRequestResponse_Streaming()
593593
Assert.Equal(36, usage.Details.TotalTokenCount);
594594
}
595595

596+
[Fact]
597+
public async Task MissingAbstractionResponse_NonStreaming()
598+
{
599+
const string Input =
600+
"""
601+
{
602+
"model": "computer-use-preview",
603+
"reasoning": {
604+
"summary": "concise"
605+
},
606+
"tools": [
607+
{
608+
"type": "computer_use_preview",
609+
"environment": "browser",
610+
"display_width": 1024,
611+
"display_height": 768
612+
}
613+
],
614+
"truncation": "auto",
615+
"input": [
616+
{
617+
"type": "message",
618+
"role": "user",
619+
"content": [
620+
{
621+
"type": "input_text",
622+
"text": "Search the web for the temperature today in Fremont"
623+
}
624+
]
625+
}
626+
]
627+
}
628+
""";
629+
630+
const string Output =
631+
"""
632+
{
633+
"id": "resp_67d327649b288191aeb46a824e49dc40058a5e08c46a181d",
634+
"object": "response",
635+
"created_at": 1741891428,
636+
"status": "completed",
637+
"error": null,
638+
"incomplete_details": null,
639+
"instructions": null,
640+
"max_output_tokens": 20,
641+
"model": "computer-use-preview-2025-03-11",
642+
"output": [
643+
{
644+
"type": "reasoning",
645+
"id": "rs_67cc...",
646+
"summary": [
647+
{
648+
"type": "summary_text",
649+
"text": "Clicking on the browser address bar."
650+
}
651+
]
652+
},
653+
{
654+
"type": "computer_call",
655+
"id": "cu_67cc...",
656+
"call_id": "call_zw3...",
657+
"action": {
658+
"type": "click",
659+
"button": "left",
660+
"x": 156,
661+
"y": 50
662+
},
663+
"pending_safety_checks": [],
664+
"status": "completed"
665+
}
666+
],
667+
"parallel_tool_calls": true,
668+
"previous_response_id": null,
669+
"reasoning": {
670+
"generate_summary": "concise"
671+
},
672+
"store": true,
673+
"temperature": 1.0,
674+
"text": {
675+
"format": {
676+
"type": "text"
677+
}
678+
},
679+
"tool_choice": "auto",
680+
"tools": [],
681+
"top_p": 1.0,
682+
"usage": {
683+
"input_tokens": 18,
684+
"input_tokens_details": {
685+
"cached_tokens": 0
686+
},
687+
"output_tokens": 53,
688+
"output_tokens_details": {
689+
"reasoning_tokens": 12
690+
},
691+
"total_tokens": 71
692+
},
693+
"user": null,
694+
"metadata": {}
695+
}
696+
""";
697+
698+
using VerbatimHttpHandler handler = new(Input, Output);
699+
using HttpClient httpClient = new(handler);
700+
using IChatClient client = CreateResponseClient(httpClient, "computer-use-preview");
701+
702+
var responseCreationOptions =
703+
new ResponseCreationOptions
704+
{
705+
TruncationMode = ResponseTruncationMode.Auto,
706+
ReasoningOptions = new()
707+
{
708+
ReasoningSummaryVerbosity = ResponseReasoningSummaryVerbosity.Concise
709+
},
710+
Tools =
711+
{
712+
ResponseTool.CreateComputerTool(ComputerToolEnvironment.Browser, 1024, 768),
713+
}
714+
};
715+
var chatOptions =
716+
new ChatOptions
717+
{
718+
RawRepresentationFactory = options => responseCreationOptions
719+
};
720+
var response = await client.GetResponseAsync([new ChatMessage(ChatRole.User, "Search the web for the temperature today in Fremont")], chatOptions);
721+
Assert.NotNull(response);
722+
723+
Assert.Equal("resp_67d327649b288191aeb46a824e49dc40058a5e08c46a181d", response.ResponseId);
724+
Assert.Equal("resp_67d327649b288191aeb46a824e49dc40058a5e08c46a181d", response.ConversationId);
725+
Assert.Empty(response.Text);
726+
Assert.Equal("computer-use-preview-2025-03-11", response.ModelId);
727+
Assert.Equal(DateTimeOffset.FromUnixTimeSeconds(1_741_891_428), response.CreatedAt);
728+
Assert.Null(response.FinishReason);
729+
ChatMessage responseMessage = Assert.Single(response.Messages);
730+
Assert.Equal(ChatRole.Assistant, responseMessage.Role);
731+
Assert.Equal(2, responseMessage.Contents.Count);
732+
Assert.Single(responseMessage.Contents, content => content is TextReasoningContent);
733+
AIContent computerUserItem = Assert.Single(responseMessage.Contents, content => content.GetType() == typeof(AIContent));
734+
Assert.NotNull(computerUserItem.RawRepresentation);
735+
Assert.IsType<ComputerCallResponseItem>(computerUserItem.RawRepresentation);
736+
Assert.NotNull(response.Usage);
737+
Assert.Equal(18, response.Usage.InputTokenCount);
738+
Assert.Equal(53, response.Usage.OutputTokenCount);
739+
Assert.Equal(71, response.Usage.TotalTokenCount);
740+
}
741+
742+
[Fact]
743+
public async Task MissingAbstractionResponse_Streaming()
744+
{
745+
const string Input =
746+
"""
747+
{
748+
"model": "computer-use-preview",
749+
"reasoning": {
750+
"summary": "concise"
751+
},
752+
"tools": [
753+
{
754+
"type": "computer_use_preview",
755+
"environment": "browser",
756+
"display_width": 1024,
757+
"display_height": 768
758+
}
759+
],
760+
"truncation": "auto",
761+
"input": [
762+
{
763+
"type": "message",
764+
"role": "user",
765+
"content": [
766+
{
767+
"type": "input_text",
768+
"text": "Search the web for the temperature today in Fremont"
769+
}
770+
]
771+
}
772+
],
773+
"stream":true
774+
}
775+
""";
776+
777+
const string Output =
778+
"""
779+
event: response.created
780+
data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_0b949080ec8e4b8a006920e0661d00819383ed81438ab11299","object":"response","created_at":1763762278,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"computer-use-preview-2025-03-11","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","generate_summary":"concise","summary":"concise"},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":null,"tools":[{"type":"computer-use-preview-2025-03-11","environment":"browser","display_width":1024,"display_height":768}],"top_logprobs":0,"top_p":1.0,"truncation":"auto","usage":null,"user":null,"metadata":{}}}
781+
782+
event: response.in_progress
783+
data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_0b949080ec8e4b8a006920e0661d00819383ed81438ab11299","object":"response","created_at":1763762278,"status":"in_progress","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"computer-use-preview-2025-03-11","output":[],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","generate_summary":"concise","summary":"concise"},"safety_identifier":null,"service_tier":"auto","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":null,"tools":[{"type":"computer_use_preview","environment":"browser","display_width":1024,"display_height":768}],"top_logprobs":0,"top_p":1.0,"truncation":"auto","usage":null,"user":null,"metadata":{}}}
784+
785+
event: response.output_item.added
786+
data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"type":"computer_call","id":"cu_0b949080ec8e4b8a006920e067a7c0819384d047d21b484357","status":"in_progress","call_id":"call_p7K8YjFwNjqMgkKhSiExgFH6","action":{"type":"screenshot"},"pending_safety_checks":[]}}
787+
788+
event: response.output_item.done
789+
data: {"type":"response.output_item.done","sequence_number":3,"output_index":0,"item":{"type":"computer_call","id":"cu_0b949080ec8e4b8a006920e067a7c0819384d047d21b484357","status":"completed","call_id":"call_p7K8YjFwNjqMgkKhSiExgFH6","action":{"type":"screenshot"},"pending_safety_checks":[]}}
790+
791+
event: response.completed
792+
data: {"type":"response.completed","sequence_number":4,"response":{"id":"resp_0b949080ec8e4b8a006920e0661d00819383ed81438ab11299","object":"response","created_at":1763762278,"status":"completed","background":false,"content_filters":null,"error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"max_tool_calls":null,"model":"computer-use-preview-2025-03-11","output":[{"type":"computer_call","id":"cu_0b949080ec8e4b8a006920e067a7c0819384d047d21b484357","status":"completed","call_id":"call_p7K8YjFwNjqMgkKhSiExgFH6","action":{"type":"screenshot"},"pending_safety_checks":[]}],"parallel_tool_calls":true,"previous_response_id":null,"prompt_cache_key":null,"reasoning":{"effort":"medium","generate_summary":"concise","summary":"concise"},"safety_identifier":null,"service_tier":"default","store":true,"temperature":1.0,"text":{"format":{"type":"text"},"verbosity":"medium"},"tool_choice":null,"tools":[{"type":"computer-use-preview-2025-03-11","environment":"browser","display_width":1024,"display_height":768}],"top_logprobs":0,"top_p":1.0,"truncation":"auto","usage":{"input_tokens":18,"input_tokens_details":{"cached_tokens":0},"output_tokens":53,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":71},"user":null,"metadata":{}}}
793+
""";
794+
795+
using VerbatimHttpHandler handler = new(Input, Output);
796+
using HttpClient httpClient = new(handler);
797+
using IChatClient client = CreateResponseClient(httpClient, "computer-use-preview");
798+
799+
var responseCreationOptions =
800+
new ResponseCreationOptions
801+
{
802+
TruncationMode = ResponseTruncationMode.Auto,
803+
ReasoningOptions = new()
804+
{
805+
ReasoningSummaryVerbosity = ResponseReasoningSummaryVerbosity.Concise
806+
},
807+
Tools =
808+
{
809+
ResponseTool.CreateComputerTool(ComputerToolEnvironment.Browser, 1024, 768),
810+
}
811+
};
812+
var chatOptions =
813+
new ChatOptions
814+
{
815+
RawRepresentationFactory = options => responseCreationOptions
816+
};
817+
818+
List<ChatResponseUpdate> updates = [];
819+
await foreach (var update in client.GetStreamingResponseAsync([new ChatMessage(ChatRole.User, "Search the web for the temperature today in Fremont")], chatOptions))
820+
{
821+
updates.Add(update);
822+
}
823+
824+
Assert.Empty(string.Concat(updates.Select(u => u.Text)));
825+
826+
var createdAt = DateTimeOffset.FromUnixTimeSeconds(1_763_762_278);
827+
Assert.Equal(4, updates.Count);
828+
829+
HashSet<int> updatesWithContents = [3];
830+
for (int i = 0; i < updates.Count; i++)
831+
{
832+
Assert.Equal("resp_0b949080ec8e4b8a006920e0661d00819383ed81438ab11299", updates[i].ResponseId);
833+
Assert.Equal("resp_0b949080ec8e4b8a006920e0661d00819383ed81438ab11299", updates[i].ConversationId);
834+
Assert.Equal(createdAt, updates[i].CreatedAt);
835+
Assert.Equal("computer-use-preview-2025-03-11", updates[i].ModelId);
836+
Assert.Null(updates[i].AdditionalProperties);
837+
Assert.Equal(i == 3 ? 1 : 0, updates[i].Contents.Count);
838+
////Assert.Equal(i < updates.Count - 1 ? null : ChatFinishReason.Stop, updates[i].FinishReason);
839+
Assert.Null(updates[i].FinishReason);
840+
Assert.Null(updates[i].Role);
841+
}
842+
843+
////Assert.Equal(ChatRole.Assistant, updates[4].Role);
844+
AIContent content = Assert.Single(updates[3].Contents);
845+
Assert.NotNull(content.RawRepresentation);
846+
Assert.IsType<ComputerCallResponseItem>(content.RawRepresentation);
847+
848+
////UsageContent usage = Assert.Single(updates.SelectMany(u => u.Contents).OfType<UsageContent>());
849+
////Assert.Equal(18, usage.Details.InputTokenCount);
850+
////Assert.Equal(53, usage.Details.OutputTokenCount);
851+
////Assert.Equal(71, usage.Details.TotalTokenCount);
852+
}
853+
596854
[Fact]
597855
public async Task ChatOptions_StrictRespected()
598856
{

0 commit comments

Comments
 (0)