openai/openai-dotnet

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
copilot/update-properties-to-string

Branches

Tags

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

Clone

HTTPS

Download ZIP

examples/Responses/Example03_FunctionCallingAsync.cs

99lines · 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 ResponsesClient client = new(apiKey: 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 PrintMessageItems(inputItems.OfType<MessageResponseItem>());
30
31 bool requiresAction;
32
33 do
34 {
35 requiresAction = false;
36
37 CreateResponseOptions options = new("gpt-5", inputItems)
38 {
39 Tools = { getCurrentLocationTool, getCurrentWeatherTool },
40 };
41
42 ResponseResult response = await client.CreateResponseAsync(options);
43
44 inputItems.AddRange(response.OutputItems);
45
46 foreach (ResponseItem outputItem in response.OutputItems)
47 {
48 if (outputItem is FunctionCallResponseItem functionCall)
49 {
50 switch (functionCall.FunctionName)
51 {
52 case nameof(GetCurrentLocation):
53 {
54 string functionOutput = GetCurrentLocation();
55 inputItems.Add(new FunctionCallOutputResponseItem(functionCall.CallId, functionOutput));
56 break;
57 }
58
59 case nameof(GetCurrentWeather):
60 {
61 // The arguments that the model wants to use to call the function are specified as a
62 // stringified JSON object based on the schema defined in the tool definition. Note that
63 // the model may hallucinate arguments too. Consequently, it is important to do the
64 // appropriate parsing and validation before calling the function.
65 using JsonDocument argumentsJson = JsonDocument.Parse(functionCall.FunctionArguments);
66 bool hasLocation = argumentsJson.RootElement.TryGetProperty("location", out JsonElement location);
67 bool hasUnit = argumentsJson.RootElement.TryGetProperty("unit", out JsonElement unit);
68
69 if (!hasLocation)
70 {
71 throw new ArgumentNullException(nameof(location), "The location argument is required.");
72 }
73
74 string functionOutput = hasUnit
75 ? GetCurrentWeather(location.GetString(), unit.GetString())
76 : GetCurrentWeather(location.GetString());
77 inputItems.Add(new FunctionCallOutputResponseItem(functionCall.CallId, functionOutput));
78 break;
79 }
80
81 default:
82 {
83 // Handle other unexpected calls.
84 throw new NotImplementedException();
85 }
86 }
87
88 requiresAction = true;
89 break;
90 }
91 }
92
93 PrintMessageItems(response.OutputItems.OfType<MessageResponseItem>());
94
95 } while (requiresAction);
96 }
97}
98
99#pragma warning restore OPENAI001