openai/openai-dotnet

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
OpenAI_2.6.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

examples/Assistants/Example02b_FunctionCallingStreaming.cs

141lines · modecode

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