openai/openai-dotnet

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
OpenAI_2.9.1

Branches

Tags

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

Clone

HTTPS

Download ZIP

examples/Responses/Example03_FunctionCalling.cs

166lines · modeblame

d893a79fJose Arriaga Maldonado11 months ago1using NUnit.Framework;
2using OpenAI.Responses;
3using System;
4using System.Collections.Generic;
5using System.Linq;
6using System.Text.Json;
7
8namespace OpenAI.Examples;
9
10// This example uses experimental APIs which are subject to change. To use experimental APIs,
11// please acknowledge their experimental status by suppressing the corresponding warning.
12#pragma warning disable OPENAI001
13
14public partial class ResponseExamples
15{
16#region
17private static string GetCurrentLocation()
18{
19// Call the location API here.
20return "San Francisco";
21}
22
23private static string GetCurrentWeather(string location, string unit = "celsius")
24{
25// Call the weather API here.
26return $"31 {unit}";
27}
28#endregion
29
30#region
31private static readonly FunctionTool getCurrentLocationTool = ResponseTool.CreateFunctionTool(
32functionName: nameof(GetCurrentLocation),
33functionDescription: "Get the user's current location",
34functionParameters: null,
35strictModeEnabled: false
36);
37
38private static readonly FunctionTool getCurrentWeatherTool = ResponseTool.CreateFunctionTool(
39functionName: nameof(GetCurrentWeather),
40functionDescription: "Get the current weather in a given location",
41functionParameters: BinaryData.FromBytes("""
42{
43"type": "object",
44"properties": {
45"location": {
46"type": "string",
47"description": "The city and state, e.g. Boston, MA"
48},
49"unit": {
50"type": "string",
51"enum": [ "celsius", "fahrenheit" ],
52"description": "The temperature unit to use. Infer this from the specified location."
53}
54},
55"required": [ "location" ]
56}
57"""u8.ToArray()),
58strictModeEnabled: false
59);
60#endregion
61
62[Test]
63public void Example03_FunctionCalling()
64{
5ff668b5Copilot5 months ago65ResponsesClient client = new(apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
d893a79fJose Arriaga Maldonado11 months ago66
67List<ResponseItem> inputItems =
68[
69ResponseItem.CreateUserMessageItem("What's the weather like today for my current location?"),
70];
71
72PrintMessageItems(inputItems.OfType<MessageResponseItem>());
73
74bool requiresAction;
75
76do
77{
78requiresAction = false;
74f7e256Jose Arriaga Maldonado8 months ago79
5ff668b5Copilot5 months ago80CreateResponseOptions options = new("gpt-5-mini", inputItems)
74f7e256Jose Arriaga Maldonado8 months ago81{
82Tools = { getCurrentLocationTool, getCurrentWeatherTool },
83};
84
33db028aChristopher Scott8 months ago85ResponseResult response = client.CreateResponse(options);
d893a79fJose Arriaga Maldonado11 months ago86
87inputItems.AddRange(response.OutputItems);
88
89foreach (ResponseItem outputItem in response.OutputItems)
90{
91if (outputItem is FunctionCallResponseItem functionCall)
92{
93switch (functionCall.FunctionName)
94{
95case nameof(GetCurrentLocation):
96{
97string functionOutput = GetCurrentLocation();
98inputItems.Add(new FunctionCallOutputResponseItem(functionCall.CallId, functionOutput));
99break;
100}
101
102case nameof(GetCurrentWeather):
103{
104// The arguments that the model wants to use to call the function are specified as a
105// stringified JSON object based on the schema defined in the tool definition. Note that
106// the model may hallucinate arguments too. Consequently, it is important to do the
107// appropriate parsing and validation before calling the function.
108using JsonDocument argumentsJson = JsonDocument.Parse(functionCall.FunctionArguments);
109bool hasLocation = argumentsJson.RootElement.TryGetProperty("location", out JsonElement location);
110bool hasUnit = argumentsJson.RootElement.TryGetProperty("unit", out JsonElement unit);
111
112if (!hasLocation)
113{
114throw new ArgumentNullException(nameof(location), "The location argument is required.");
115}
116
117string functionOutput = hasUnit
118? GetCurrentWeather(location.GetString(), unit.GetString())
119: GetCurrentWeather(location.GetString());
120inputItems.Add(new FunctionCallOutputResponseItem(functionCall.CallId, functionOutput));
121break;
122}
123
124default:
125{
126// Handle other unexpected calls.
127throw new NotImplementedException();
128}
129}
130
131requiresAction = true;
132break;
133}
134}
135
136PrintMessageItems(response.OutputItems.OfType<MessageResponseItem>());
137
138} while (requiresAction);
139}
140
141private void PrintMessageItems(IEnumerable<ResponseItem> messageItems)
142{
143foreach (MessageResponseItem messageItem in messageItems)
144{
145switch (messageItem.Role)
146{
147case MessageRole.User:
148Console.WriteLine($"[USER]:");
149Console.WriteLine($"{messageItem.Content[0].Text}");
150Console.WriteLine();
151break;
152
153case MessageRole.Assistant:
154Console.WriteLine($"[ASSISTANT]:");
155Console.WriteLine($"{messageItem.Content[0].Text}");
156Console.WriteLine();
157break;
158
159default:
160break;
161}
162}
163}
164}
165
166#pragma warning restore OPENAI001