@@ -44,115 +44,154 @@ Use this article to find step-by-step instructions and code samples for using Op
44
44
45
45
:::zone pivot="csharp"
46
46
47
- ## Step 1: Create a project client
48
- Create a client object, which will contain the connection string for connecting to your AI project and other resources.
47
+ # How to use the OpenAPI spec tool
49
48
50
- ``` csharp
51
- using System ;
52
- using System .Collections .Generic ;
53
- using System .IO ;
54
- using System .Runtime .CompilerServices ;
55
- using System .Text .Json .Serialization ;
56
- using System .Text .Json ;
57
- using System .Threading .Tasks ;
58
- using Azure .Core .TestFramework ;
59
- using NUnit .Framework ;
60
- using Newtonsoft .Json .Linq ;
61
-
62
- namespace Azure .AI .Projects .Tests ;
63
-
64
- public partial class Sample_Agent_OpenAPI : SamplesBase <AIProjectsTestEnvironment >
65
- {
66
- private static string GetFile ([CallerFilePath ] string pth = " " )
67
- {
68
- var dirName = Path .GetDirectoryName (pth ) ?? " " ;
69
- return Path .Combine (dirName , " weather_openapi.json" );
70
- }
49
+ In this example we will demonstrate the possibility to use services with [ OpenAPI Specification] ( https://en.wikipedia.org/wiki/OpenAPI_Specification ) with the agent. We will use [ wttr.in] ( https://wttr.in ) service to get weather and its specification file [ weather_openapi.json] ( https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/ai/Azure.AI.Projects/tests/Samples/Agent/weather_openapi.json ) .
71
50
72
- [Test ]
73
- public async Task OpenAPICallingExample ()
74
- {
75
- var connectionString = TestEnvironment .AzureAICONNECTIONSTRING ;
76
- var storageQueueUri = TestEnvironment .STORAGE_QUEUE_URI ;
77
- AgentsClient client = new (connectionString , new DefaultAzureCredential ());
78
- var file_path = GetFile ();
51
+ 1 . First get ` ProjectEndpoint ` and ` ModelDeploymentName ` from config and create a ` PersistentAgentsClient ` . Also, create an ` OpenApiAnonymousAuthDetails ` and ` OpenApiToolDefinition ` from config.
52
+
53
+ ``` csharp
54
+ var projectEndpoint = configuration [" ProjectEndpoint" ];
55
+ var modelDeploymentName = configuration [" ModelDeploymentName" ];
56
+ var openApiSpec = configuration [" OpenApiSpec" ];
57
+ PersistentAgentsClient client = new (new Uri (projectEndpoint ), new DefaultAzureCredential ());
58
+
59
+ var spec = BinaryData .FromBytes (File .ReadAllBytes (openApiSpec ));
60
+ OpenApiAnonymousAuthDetails openApiAnonAuth = new ();
61
+ OpenApiToolDefinition openApiTool = new (
62
+ name : " get_weather" ,
63
+ description : " Retrieve weather information for a location" ,
64
+ spec : spec ,
65
+ auth : openApiAnonAuth ,
66
+ defaultParams : [" format" ]
67
+ );
79
68
```
80
69
70
+ 2 . Next we will need to create an agent.
81
71
82
- ## Step 2: Create the OpenAPI Spec tool definition
83
- You might want to store the OpenAPI specification in another file and import the content to initialize the tool . The sample code is using `anonymous ` as the authentication type .
72
+ Synchronous sample:
84
73
85
74
``` csharp
86
- OpenApiAnonymousAuthDetails oaiAuth = new ();
87
- OpenApiToolDefinition openapiTool = new (
88
- name : " get_weather" ,
89
- description : " Retrieve weather information for a location" ,
90
- spec : BinaryData .FromBytes (File .ReadAllBytes (file_path )),
91
- auth : oaiAuth
92
- );
75
+ PersistentAgent agent = client .CreateAgent (
76
+ model : modelDeploymentName ,
77
+ name : " Open API Tool Calling Agent" ,
78
+ instructions : " You are a helpful agent." ,
79
+ tools : [openApiTool ]
80
+ );
93
81
```
94
82
95
- ## Step 3: Create an agent and a thread
83
+ Asynchronous sample:
96
84
97
85
``` csharp
98
- Response < Agent > agentResponse = await client .CreateAgentAsync (
99
- model : " gpt-4o" ,
100
- name : " azure-function-agent-foo" ,
101
- instructions : " You are a helpful assistant." ,
102
- tools : new List <ToolDefinition > { openapiTool }
103
- );
104
- Agent agent = agentResponse .Value ;
105
- #endregion
106
- Response < AgentThread > threadResponse = await client .CreateThreadAsync ();
107
- AgentThread thread = threadResponse .Value ;
86
+ PersistentAgent agent = await client .CreateAgentAsync (
87
+ model : modelDeploymentName ,
88
+ name : " Open API Tool Calling Agent" ,
89
+ instructions : " You are a helpful agent." ,
90
+ tools : [openApiTool ]
91
+ );
108
92
```
109
93
94
+ 3 . Now we will create a ` ThreadRun ` and wait until it is complete. If the run will not be successful, we will print the last error.
110
95
111
- ## Step 4: Create a run and check the output
112
- Create a run and observe that the model uses the OpenAPI Spec tool to provide a response to the user 's question.
96
+ Synchronous sample:
97
+ ``` csharp
98
+ PersistentAgentThread thread = client .CreateThread ();
99
+ ThreadMessage message = client .CreateMessage (
100
+ thread .Id ,
101
+ MessageRole .User ,
102
+ " What's the weather in Seattle?" );
103
+
104
+ ThreadRun run = client .CreateRun (thread , agent );
105
+
106
+ do
107
+ {
108
+ Thread .Sleep (TimeSpan .FromMilliseconds (500 ));
109
+ run = client .GetRun (thread .Id , run .Id );
110
+ }
111
+ while (run .Status == RunStatus .Queued
112
+ || run .Status == RunStatus .InProgress
113
+ || run .Status == RunStatus .RequiresAction );
114
+ ```
113
115
116
+ Asynchronous sample:
114
117
115
118
``` csharp
116
- #region Snippet:OpenAPIHandlePollingWithRequiredAction
117
- Response < ThreadMessage > messageResponse = await client .CreateMessageAsync (
118
- thread .Id ,
119
- MessageRole .User ,
120
- " What's the weather in Seattle?" );
121
- ThreadMessage message = messageResponse .Value ;
119
+ PersistentAgentThread thread = await client .CreateThreadAsync ();
120
+ ThreadMessage message = await client .CreateMessageAsync (
121
+ thread .Id ,
122
+ MessageRole .User ,
123
+ " What's the weather in Seattle?" );
124
+
125
+ ThreadRun run = await client .CreateRunAsync (thread , agent );
126
+
127
+ do
128
+ {
129
+ await Task .Delay (TimeSpan .FromMilliseconds (500 ));
130
+ run = await client .GetRunAsync (thread .Id , run .Id );
131
+ }
132
+ while (run .Status == RunStatus .Queued
133
+ || run .Status == RunStatus .InProgress
134
+ || run .Status == RunStatus .RequiresAction );
135
+ ```
122
136
123
- Response < ThreadRun > runResponse = await client . CreateRunAsync ( thread , agent );
137
+ 4 . Print the messages to the console in chronological order.
124
138
125
- do
139
+ Synchronous sample:
140
+
141
+ ``` csharp
142
+ PageableList < ThreadMessage > messages = client .GetMessages (
143
+ threadId : thread .Id ,
144
+ order : ListSortOrder .Ascending
145
+ );
146
+
147
+ foreach (ThreadMessage threadMessage in messages )
148
+ {
149
+ foreach (MessageContent contentItem in threadMessage .ContentItems )
150
+ {
151
+ if (contentItem is MessageTextContent textItem )
126
152
{
127
- await Task .Delay (TimeSpan .FromMilliseconds (500 ));
128
- runResponse = await client .GetRunAsync (thread .Id , runResponse .Value .Id );
153
+ Console .Write ($" {threadMessage .Role }: {textItem .Text }" );
129
154
}
130
- while (runResponse .Value .Status == RunStatus .Queued
131
- || runResponse .Value .Status == RunStatus .InProgress
132
- || runResponse .Value .Status == RunStatus .RequiresAction );
133
- #endregion
155
+ Console .WriteLine ();
156
+ }
157
+ }
158
+ ```
159
+
160
+ Asynchronous sample:
134
161
135
- Response < PageableList < ThreadMessage >> afterRunMessagesResponse
136
- = await client .GetMessagesAsync (thread .Id );
137
- IReadOnlyList < ThreadMessage > messages = afterRunMessagesResponse .Value .Data ;
162
+ ``` csharp
163
+ PageableList < ThreadMessage > messages = await client .GetMessagesAsync (
164
+ threadId : thread .Id ,
165
+ order : ListSortOrder .Ascending
166
+ );
138
167
139
- // Note: messages iterate from newest to oldest, with the messages[0] being the most recent
140
- foreach (ThreadMessage threadMessage in messages )
168
+ foreach (ThreadMessage threadMessage in messages )
169
+ {
170
+ foreach (MessageContent contentItem in threadMessage .ContentItems )
171
+ {
172
+ if (contentItem is MessageTextContent textItem )
141
173
{
142
- Console .Write ($" {threadMessage .CreatedAt : yyyy - MM - dd HH : mm : ss } - {threadMessage .Role ,10 }: " );
143
- foreach (MessageContent contentItem in threadMessage .ContentItems )
144
- {
145
- if (contentItem is MessageTextContent textItem )
146
- {
147
- Console .Write (textItem .Text );
148
- }
149
- else if (contentItem is MessageImageFileContent imageFileItem )
150
- {
151
- Console .Write ($" <image from ID: {imageFileItem .FileId }" );
152
- }
153
- Console .WriteLine ();
154
- }
174
+ Console .Write ($" {threadMessage .Role }: {textItem .Text }" );
155
175
}
176
+ Console .WriteLine ();
177
+ }
178
+ }
179
+ ```
180
+
181
+ 5 . Finally, we delete all the resources, we have created in this sample.
182
+
183
+ Synchronous sample:
184
+
185
+ ``` csharp
186
+ client .DeleteThread (thread .Id );
187
+ client .DeleteAgent (agent .Id );
188
+ ```
189
+
190
+ Asynchronous sample:
191
+
192
+ ``` csharp
193
+ await client .DeleteThreadAsync (thread .Id );
194
+ await client .DeleteAgentAsync (agent .Id );
156
195
```
157
196
158
197
::: zone-end
0 commit comments