From 576226aaa6d7f619070889e63262c443bf913967 Mon Sep 17 00:00:00 2001 From: Stephen Hodgson Date: Wed, 8 Nov 2023 19:10:55 -0500 Subject: [PATCH] update readme tweak some unit tests --- OpenAI-DotNet-Tests/TestFixture_03_Chat.cs | 38 ++++------ OpenAI-DotNet/Chat/ChatResponse.cs | 2 +- README.md | 86 +++++++++++++--------- 3 files changed, 66 insertions(+), 60 deletions(-) diff --git a/OpenAI-DotNet-Tests/TestFixture_03_Chat.cs b/OpenAI-DotNet-Tests/TestFixture_03_Chat.cs index da3f845c..5091c8f2 100644 --- a/OpenAI-DotNet-Tests/TestFixture_03_Chat.cs +++ b/OpenAI-DotNet-Tests/TestFixture_03_Chat.cs @@ -553,7 +553,7 @@ public async Task Test_08_GetChatToolCompletion_Streaming() var functionArgs = JsonSerializer.Deserialize(usedTool.Function.Arguments.ToString()); var functionResult = WeatherService.GetCurrentWeather(functionArgs); Assert.IsNotNull(functionResult); - messages.Add(new Message(Role.Tool, functionResult, nameof(WeatherService.GetCurrentWeather))); + messages.Add(new Message(usedTool, functionResult)); Console.WriteLine($"{Role.Tool}: {functionResult}"); } @@ -636,26 +636,20 @@ public async Task Test_09_GetChatToolForceCompletion() public async Task Test_10_GetChatVision() { Assert.IsNotNull(OpenAIClient.ChatEndpoint); - var content = new List - { - new Content(ContentType.Text, "What's in this image?"), - new Content(ContentType.ImageUrl, "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg") - }; var messages = new List { new Message(Role.System, "You are a helpful assistant."), - new Message(Role.User, content) + new Message(Role.User, new List + { + new Content(ContentType.Text, "What's in this image?"), + new Content(ContentType.ImageUrl, "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg") + }) }; var chatRequest = new ChatRequest(messages, model: "gpt-4-vision-preview"); var result = await OpenAIClient.ChatEndpoint.GetCompletionAsync(chatRequest); Assert.IsNotNull(result); Assert.IsNotNull(result.Choices); - - foreach (var choice in result.Choices) - { - Console.WriteLine($"[{choice.Index}] {choice.Message.Role}: {choice.Message.Content} | Finish Reason: {choice.FinishDetails}"); - } - + Console.WriteLine($"{result.FirstChoice.Message.Role}: {result.FirstChoice.Message.Content} | Finish Reason: {result.FirstChoice.FinishDetails}"); result.GetUsage(); } @@ -663,15 +657,14 @@ public async Task Test_10_GetChatVision() public async Task Test_10_GetChatVisionStreaming() { Assert.IsNotNull(OpenAIClient.ChatEndpoint); - var content = new List - { - new Content(ContentType.Text, "What's in this image?"), - new Content(ContentType.ImageUrl, "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg") - }; var messages = new List { new Message(Role.System, "You are a helpful assistant."), - new Message(Role.User, content) + new Message(Role.User, new List + { + new Content(ContentType.Text, "What's in this image?"), + new Content(ContentType.ImageUrl, "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg") + }) }; var chatRequest = new ChatRequest(messages, model: "gpt-4-vision-preview"); var result = await OpenAIClient.ChatEndpoint.StreamCompletionAsync(chatRequest, partialResponse => @@ -682,12 +675,7 @@ public async Task Test_10_GetChatVisionStreaming() }); Assert.IsNotNull(result); Assert.IsNotNull(result.Choices); - - foreach (var choice in result.Choices) - { - Console.WriteLine($"[{choice.Index}] {choice.Message.Role}: {choice.Message.Content} | Finish Reason: {choice.FinishDetails}"); - } - + Console.WriteLine($"{result.FirstChoice.Message.Role}: {result.FirstChoice.Message.Content} | Finish Reason: {result.FirstChoice.FinishDetails}"); result.GetUsage(); } } diff --git a/OpenAI-DotNet/Chat/ChatResponse.cs b/OpenAI-DotNet/Chat/ChatResponse.cs index 18cd2b89..81b64c66 100644 --- a/OpenAI-DotNet/Chat/ChatResponse.cs +++ b/OpenAI-DotNet/Chat/ChatResponse.cs @@ -63,7 +63,7 @@ public ChatResponse( /// [JsonInclude] [JsonPropertyName("system_fingerprint")] - public string Fingerprint { get; private set; } + public string SystemFingerprint { get; private set; } [JsonInclude] [JsonPropertyName("usage")] diff --git a/README.md b/README.md index 434c60ad..c81d3a2f 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,8 @@ Install-Package OpenAI-DotNet - [Chat](#chat) - [Chat Completions](#chat-completions) - [Streaming](#chat-streaming) - - [Functions](#chat-functions) + - [Tools](#chat-tools) + - [Vision](#chat-vision) - [Edits](#edits) - [Create Edit](#create-edit) - [Embeddings](#embeddings) @@ -425,9 +426,7 @@ await foreach (var result in api.ChatEndpoint.StreamCompletionEnumerableAsync(ch } ``` -##### [Chat Functions](https://platform.openai.com/docs/api-reference/chat/create#chat/create-functions) - -> Only available with the latest 0613 model series! +##### [Chat Tools](https://platform.openai.com/docs/guides/function-calling) ```csharp var api = new OpenAIClient(); @@ -442,33 +441,33 @@ foreach (var message in messages) Console.WriteLine($"{message.Role}: {message.Content}"); } -// Define the functions that the assistant is able to use: -var functions = new List +// Define the tools that the assistant is able to use: +var tools = new List { new Function( nameof(WeatherService.GetCurrentWeather), "Get the current weather in a given location", - new JsonObject - { - ["type"] = "object", - ["properties"] = new JsonObject - { - ["location"] = new JsonObject - { - ["type"] = "string", - ["description"] = "The city and state, e.g. San Francisco, CA" - }, - ["unit"] = new JsonObject - { - ["type"] = "string", - ["enum"] = new JsonArray {"celsius", "fahrenheit"} - } - }, - ["required"] = new JsonArray { "location", "unit" } - }) + new JsonObject + { + ["type"] = "object", + ["properties"] = new JsonObject + { + ["location"] = new JsonObject + { + ["type"] = "string", + ["description"] = "The city and state, e.g. San Francisco, CA" + }, + ["unit"] = new JsonObject + { + ["type"] = "string", + ["enum"] = new JsonArray {"celsius", "fahrenheit"} + } + }, + ["required"] = new JsonArray { "location", "unit" } + }) }; -var chatRequest = new ChatRequest(messages, functions: functions, functionCall: "auto", model: "gpt-3.5-turbo"); +var chatRequest = new ChatRequest(messages, tools: tools, toolChoice: "auto"); var result = await OpenAIClient.ChatEndpoint.GetCompletionAsync(chatRequest); messages.Add(result.FirstChoice.Message); @@ -477,7 +476,7 @@ Console.WriteLine($"{result.FirstChoice.Message.Role}: {result.FirstChoice.Messa var locationMessage = new Message(Role.User, "I'm in Glasgow, Scotland"); messages.Add(locationMessage); Console.WriteLine($"{locationMessage.Role}: {locationMessage.Content}"); -chatRequest = new ChatRequest(messages, functions: functions, functionCall: "auto", model: "gpt-3.5-turbo"); +chatRequest = new ChatRequest(messages, tools: tools, toolChoice: "auto"); result = await OpenAIClient.ChatEndpoint.GetCompletionAsync(chatRequest); messages.Add(result.FirstChoice.Message); @@ -489,26 +488,45 @@ if (!string.IsNullOrEmpty(result.FirstChoice.Message.Content)) var unitMessage = new Message(Role.User, "celsius"); messages.Add(unitMessage); Console.WriteLine($"{unitMessage.Role}: {unitMessage.Content}"); - chatRequest = new ChatRequest(messages, functions: functions, functionCall: "auto", model: "gpt-3.5-turbo"); + chatRequest = new ChatRequest(messages, tools: tools, toolChoice: "auto"); result = await OpenAIClient.ChatEndpoint.GetCompletionAsync(chatRequest); } -Console.WriteLine($"{result.FirstChoice.Message.Role}: {result.FirstChoice.Message.Function.Name} | Finish Reason: {result.FirstChoice.FinishReason}"); -Console.WriteLine($"{result.FirstChoice.Message.Function.Arguments}"); -var functionArgs = JsonSerializer.Deserialize(result.FirstChoice.Message.Function.Arguments.ToString()); +var usedTool = result.FirstChoice.Message.ToolCalls[0]; +Console.WriteLine($"{result.FirstChoice.Message.Role}: {usedTool.Function.Name} | Finish Reason: {result.FirstChoice.FinishReason}"); +Console.WriteLine($"{usedTool.Function.Arguments}"); +var functionArgs = JsonSerializer.Deserialize(usedTool.Function.Arguments.ToString()); var functionResult = WeatherService.GetCurrentWeather(functionArgs); -messages.Add(new Message(Role.Function, functionResult, nameof(WeatherService.GetCurrentWeather))); -Console.WriteLine($"{Role.Function}: {functionResult}"); +messages.Add(new Message(usedTool, functionResult)); +Console.WriteLine($"{Role.Tool}: {functionResult}"); // System: You are a helpful weather assistant. // User: What's the weather like today? // Assistant: Sure, may I know your current location? | Finish Reason: stop // User: I'm in Glasgow, Scotland -// Assistant: GetCurrentWeather | Finish Reason: function_call +// Assistant: GetCurrentWeather | Finish Reason: tool_calls // { // "location": "Glasgow, Scotland", // "unit": "celsius" // } -// Function: The current weather in Glasgow, Scotland is 20 celsius +// Tool: The current weather in Glasgow, Scotland is 20 celsius +``` + +##### [Chat Vision](https://platform.openai.com/docs/guides/vision) + +```csharp +var api = new OpenAIClient(); +var messages = new List +{ + new Message(Role.System, "You are a helpful assistant."), + new Message(Role.User, new List + { + new Content(ContentType.Text, "What's in this image?"), + new Content(ContentType.ImageUrl, "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg") + }) +}; +var chatRequest = new ChatRequest(messages, model: "gpt-4-vision-preview"); +var result = await OpenAIClient.ChatEndpoint.GetCompletionAsync(chatRequest); +Console.WriteLine($"{result.FirstChoice.Message.Role}: {result.FirstChoice.Message.Content} | Finish Reason: {result.FirstChoice.FinishDetails}"); ``` ### [Edits](https://platform.openai.com/docs/api-reference/edits)