openai/openai-dotnet

Public

mirrored from https://github.com/openai/openai-dotnetAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
mredding/try-live-test-pipeline

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

examples/Responses/Example03_FunctionCallingAsync.cs

98lines · modecode

1using NUnit.Framework;
2using OpenAI.Responses;
3using System;
4using System.Collections.Generic;
5using System.Linq;
6using System.Text.Json;
7using System.Threading.Tasks;
8
9namespace OpenAI.Examples;
10
11// This example uses experimental APIs which are subject to change. To use experimental APIs,
12// please acknowledge their experimental status by suppressing the corresponding warning.
13#pragma warning disable OPENAI001
14
15public partial class ResponseExamples
16{
17 // See Example03_FunctionCalling.cs for the tool and function definitions.
18
19 [Test]
20 public async Task Example03_FunctionCallingAsync()
21 {
22 OpenAIResponseClient client = new("gpt-5", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
23
24 List<ResponseItem> inputItems =
25 [
26 ResponseItem.CreateUserMessageItem("What's the weather like today for my current location?"),
27 ];
28
29 ResponseCreationOptions options = new()
30 {
31 Tools = { getCurrentLocationTool, getCurrentWeatherTool },
32 };
33
34 PrintMessageItems(inputItems.OfType<MessageResponseItem>());
35
36 bool requiresAction;
37
38 do
39 {
40 requiresAction = false;
41 OpenAIResponse response = await client.CreateResponseAsync(inputItems, options);
42
43 inputItems.AddRange(response.OutputItems);
44
45 foreach (ResponseItem outputItem in response.OutputItems)
46 {
47 if (outputItem is FunctionCallResponseItem functionCall)
48 {
49 switch (functionCall.FunctionName)
50 {
51 case nameof(GetCurrentLocation):
52 {
53 string functionOutput = GetCurrentLocation();
54 inputItems.Add(new FunctionCallOutputResponseItem(functionCall.CallId, functionOutput));
55 break;
56 }
57
58 case nameof(GetCurrentWeather):
59 {
60 // The arguments that the model wants to use to call the function are specified as a
61 // stringified JSON object based on the schema defined in the tool definition. Note that
62 // the model may hallucinate arguments too. Consequently, it is important to do the
63 // appropriate parsing and validation before calling the function.
64 using JsonDocument argumentsJson = JsonDocument.Parse(functionCall.FunctionArguments);
65 bool hasLocation = argumentsJson.RootElement.TryGetProperty("location", out JsonElement location);
66 bool hasUnit = argumentsJson.RootElement.TryGetProperty("unit", out JsonElement unit);
67
68 if (!hasLocation)
69 {
70 throw new ArgumentNullException(nameof(location), "The location argument is required.");
71 }
72
73 string functionOutput = hasUnit
74 ? GetCurrentWeather(location.GetString(), unit.GetString())
75 : GetCurrentWeather(location.GetString());
76 inputItems.Add(new FunctionCallOutputResponseItem(functionCall.CallId, functionOutput));
77 break;
78 }
79
80 default:
81 {
82 // Handle other unexpected calls.
83 throw new NotImplementedException();
84 }
85 }
86
87 requiresAction = true;
88 break;
89 }
90 }
91
92 PrintMessageItems(response.OutputItems.OfType<MessageResponseItem>());
93
94 } while (requiresAction);
95 }
96}
97
98#pragma warning restore OPENAI001