openai/openai-dotnet

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
OpenAI_2.1.0-beta.1

Branches

Tags

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

Clone

HTTPS

Download ZIP

examples/Assistants/Example02b_FunctionCallingStreaming.cs

137lines · 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.
66AssistantClient client = new(Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
67
68#region Create a new assistant with function tools
69// Create an assistant that can call the function tools.
70AssistantCreationOptions assistantOptions = new()
71{
8cc6643fJose Arriaga Maldonado2 years ago72Name = "Example: Function Calling",
9f9f2936Jose Arriaga Maldonado2 years ago73Instructions =
74"Don't make assumptions about what values to plug into functions."
75+ " Ask for clarification if a user request is ambiguous.",
76Tools = { getTemperatureTool, getRainProbabilityTool },
77};
78
79Assistant assistant = await client.CreateAssistantAsync("gpt-4-turbo", assistantOptions);
80#endregion
81
82#region Step 2 - Create a thread and add messages
83AssistantThread thread = await client.CreateThreadAsync();
84ThreadMessage message = await client.CreateMessageAsync(
a330c2e7Jose Arriaga Maldonado1 years ago85thread.Id,
d665b61fTravis Wilson2 years ago86MessageRole.User,
9f9f2936Jose Arriaga Maldonado2 years ago87[
88"What's the weather in San Francisco today and the likelihood it'll rain?"
89]);
90#endregion
91
92#region Step 3 - Initiate a streaming run
7bdecfd8Anne Thompson2 years ago93AsyncCollectionResult<StreamingUpdate> asyncUpdates
a330c2e7Jose Arriaga Maldonado1 years ago94= client.CreateRunStreamingAsync(thread.Id, assistant.Id);
9f9f2936Jose Arriaga Maldonado2 years ago95
96ThreadRun currentRun = null;
97do
98{
99currentRun = null;
100List<ToolOutput> outputsToSubmit = [];
101await foreach (StreamingUpdate update in asyncUpdates)
102{
a330c2e7Jose Arriaga Maldonado1 years ago103if (update is RequiredActionUpdate requiredActionUpdate)
9f9f2936Jose Arriaga Maldonado2 years ago104{
105if (requiredActionUpdate.FunctionName == getTemperatureTool.FunctionName)
106{
107outputsToSubmit.Add(new ToolOutput(requiredActionUpdate.ToolCallId, "57"));
108}
109else if (requiredActionUpdate.FunctionName == getRainProbabilityTool.FunctionName)
110{
111outputsToSubmit.Add(new ToolOutput(requiredActionUpdate.ToolCallId, "25%"));
112}
113}
a330c2e7Jose Arriaga Maldonado1 years ago114else if (update is RunUpdate runUpdate)
115{
116currentRun = runUpdate;
117}
9f9f2936Jose Arriaga Maldonado2 years ago118else if (update is MessageContentUpdate contentUpdate)
119{
120Console.Write(contentUpdate.Text);
121}
122}
123if (outputsToSubmit.Count > 0)
124{
a330c2e7Jose Arriaga Maldonado1 years ago125asyncUpdates = client.SubmitToolOutputsToRunStreamingAsync(currentRun.ThreadId, currentRun.Id, outputsToSubmit);
9f9f2936Jose Arriaga Maldonado2 years ago126}
127}
128while (currentRun?.Status.IsTerminal == false);
129
130#endregion
131
132// Optionally, delete the resources for tidiness if no longer needed.
133RequestOptions noThrowOptions = new() { ErrorOptions = ClientErrorBehaviors.NoThrow };
134_ = await client.DeleteThreadAsync(thread.Id, noThrowOptions);
135_ = await client.DeleteAssistantAsync(assistant.Id, noThrowOptions);
136}
137}