openai/openai-dotnet

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
OpenAI_2.0.0-beta.8

Branches

Tags

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

Clone

HTTPS

Download ZIP

examples/Assistants/Example02b_FunctionCallingStreaming.cs

138lines · modeblame

9f9f2936Jose Arriaga Maldonado2 years ago1using NUnit.Framework;
2using OpenAI.Assistants;
3using System;
4using System.ClientModel;
5using System.ClientModel.Primitives;
6using System.Collections.Generic;
7using System.Threading.Tasks;
8
8cc6643fJose Arriaga Maldonado2 years ago9namespace OpenAI.Examples;
74848f8dJose Arriaga Maldonado2 years ago10
8cc6643fJose Arriaga Maldonado2 years ago11public partial class AssistantExamples
9f9f2936Jose Arriaga Maldonado2 years ago12{
13[Test]
8cc6643fJose Arriaga Maldonado2 years ago14public async Task Example02b_FunctionCallingStreaming()
9f9f2936Jose Arriaga Maldonado2 years ago15{
8cc6643fJose Arriaga Maldonado2 years ago16// This example parallels the content at the following location:
9f9f2936Jose Arriaga Maldonado2 years ago17// https://platform.openai.com/docs/assistants/tools/function-calling/function-calling-beta
18#region Step 1 - Define Functions
19
20// First, define the functions that the assistant will use in its defined tools.
21
22FunctionToolDefinition getTemperatureTool = new()
23{
24FunctionName = "get_current_temperature",
25Description = "Gets the current temperature at a specific location.",
26Parameters = BinaryData.FromString("""
27{
28"type": "object",
29"properties": {
30"location": {
31"type": "string",
32"description": "The city and state, e.g., San Francisco, CA"
33},
34"unit": {
35"type": "string",
36"enum": ["Celsius", "Fahrenheit"],
37"description": "The temperature unit to use. Infer this from the user's location."
38}
39}
40}
41"""),
42};
43
44FunctionToolDefinition getRainProbabilityTool = new()
45{
46FunctionName = "get_current_rain_probability",
47Description = "Gets the current forecasted probability of rain at a specific location,"
48+ " represented as a percent chance in the range of 0 to 100.",
49Parameters = BinaryData.FromString("""
50{
51"type": "object",
52"properties": {
53"location": {
54"type": "string",
55"description": "The city and state, e.g., San Francisco, CA"
56}
57},
58"required": ["location"]
59}
60"""),
61};
62
63#endregion
64
65// Assistants is a beta API and subject to change; acknowledge its experimental status by suppressing the matching warning.
66#pragma warning disable OPENAI001
67AssistantClient client = new(Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
68
69#region Create a new assistant with function tools
70// Create an assistant that can call the function tools.
71AssistantCreationOptions assistantOptions = new()
72{
8cc6643fJose Arriaga Maldonado2 years ago73Name = "Example: Function Calling",
9f9f2936Jose Arriaga Maldonado2 years ago74Instructions =
75"Don't make assumptions about what values to plug into functions."
76+ " Ask for clarification if a user request is ambiguous.",
77Tools = { getTemperatureTool, getRainProbabilityTool },
78};
79
80Assistant assistant = await client.CreateAssistantAsync("gpt-4-turbo", assistantOptions);
81#endregion
82
83#region Step 2 - Create a thread and add messages
84AssistantThread thread = await client.CreateThreadAsync();
85ThreadMessage message = await client.CreateMessageAsync(
86thread,
d665b61fTravis Wilson2 years ago87MessageRole.User,
9f9f2936Jose Arriaga Maldonado2 years ago88[
89"What's the weather in San Francisco today and the likelihood it'll rain?"
90]);
91#endregion
92
93#region Step 3 - Initiate a streaming run
7bdecfd8Anne Thompson2 years ago94AsyncCollectionResult<StreamingUpdate> asyncUpdates
9f9f2936Jose Arriaga Maldonado2 years ago95= client.CreateRunStreamingAsync(thread, assistant);
96
97ThreadRun currentRun = null;
98do
99{
100currentRun = null;
101List<ToolOutput> outputsToSubmit = [];
102await foreach (StreamingUpdate update in asyncUpdates)
103{
104if (update is RunUpdate runUpdate)
105{
106currentRun = runUpdate;
107}
108else if (update is RequiredActionUpdate requiredActionUpdate)
109{
110if (requiredActionUpdate.FunctionName == getTemperatureTool.FunctionName)
111{
112outputsToSubmit.Add(new ToolOutput(requiredActionUpdate.ToolCallId, "57"));
113}
114else if (requiredActionUpdate.FunctionName == getRainProbabilityTool.FunctionName)
115{
116outputsToSubmit.Add(new ToolOutput(requiredActionUpdate.ToolCallId, "25%"));
117}
118}
119else if (update is MessageContentUpdate contentUpdate)
120{
121Console.Write(contentUpdate.Text);
122}
123}
124if (outputsToSubmit.Count > 0)
125{
126asyncUpdates = client.SubmitToolOutputsToRunStreamingAsync(currentRun, outputsToSubmit);
127}
128}
129while (currentRun?.Status.IsTerminal == false);
130
131#endregion
132
133// Optionally, delete the resources for tidiness if no longer needed.
134RequestOptions noThrowOptions = new() { ErrorOptions = ClientErrorBehaviors.NoThrow };
135_ = await client.DeleteThreadAsync(thread.Id, noThrowOptions);
136_ = await client.DeleteAssistantAsync(assistant.Id, noThrowOptions);
137}
138}