Skip to content

Commit 4aed65b

Browse files
authored
Merge pull request #4725 from RobiladK/patch-4
Update openapi-spec-samples.md
2 parents 8c75a00 + ca8c8e0 commit 4aed65b

File tree

1 file changed

+62
-90
lines changed

1 file changed

+62
-90
lines changed

articles/ai-services/agents/how-to/tools/openapi-spec-samples.md

Lines changed: 62 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Use this article to find step-by-step instructions and code samples for using Op
2020
:::zone pivot="portal"
2121

2222
1. Go to the [Azure AI Foundry portal](https://ai.azure.com/). in the **Create and debug** screen or **Agent playground**, select your agent.
23-
1. Scroll down the **Setup** pane on the right to **action**. Then select **Add**.
23+
1. Scroll down the **Setup** pane to **action**. Then select **Add**.
2424

2525
:::image type="content" source="../../media/tools/action-tools.png" alt-text="A screenshot showing the available tool categories in the Azure AI Foundry portal." lightbox="../../media/tools/action-tools.png":::
2626

@@ -32,7 +32,7 @@ Use this article to find step-by-step instructions and code samples for using Op
3232

3333
:::image type="content" source="../../media/tools/open-api-details.png" alt-text="A screenshot showing the openAPI tool details in the Azure AI Foundry portal." lightbox="../../media/tools/open-api-details.png":::
3434

35-
1. Click Next and select your authentication method. Choose `connection` for `API key`.
35+
1. Select **Next** and select your authentication method. Choose `connection` for `API key`.
3636
1. If you choose `connection`, you need to select the custom keys connection you have created before.
3737
1. If you choose `managed identity`, you need to input the audience to get your token. An example of an audience would be `https://cognitiveservices.azure.com/` to connect to Azure AI Services. Make sure you have already set up authentication and role assignment (as described in the [section](./openapi-spec.md#authenticating-with-managed-identity-microsoft-entra-id) above).
3838

@@ -44,115 +44,88 @@ Use this article to find step-by-step instructions and code samples for using Op
4444

4545
:::zone pivot="csharp"
4646

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.
49-
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-
}
71-
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();
79-
```
47+
## Using the .NET SDK
8048

49+
In this example we'll 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).
8150

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.
51+
1. First get `ProjectEndpoint` and `ModelDeploymentName` from config and create a `PersistentAgentsClient`. Also, create an `OpenApiAnonymousAuthDetails` and `OpenApiToolDefinition` from config.
8452

8553
```csharp
86-
OpenApiAnonymousAuthDetails oaiAuth = new();
87-
OpenApiToolDefinition openapiTool = new(
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(
8862
name: "get_weather",
8963
description: "Retrieve weather information for a location",
90-
spec: BinaryData.FromBytes(File.ReadAllBytes(file_path)),
91-
auth: oaiAuth
64+
spec: spec,
65+
auth: openApiAnonAuth,
66+
defaultParams: ["format"]
9267
);
9368
```
9469

95-
## Step 3: Create an agent and a thread
70+
2. Next we'll need to create an agent.
9671

9772
```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;
73+
PersistentAgent agent = client.CreateAgent(
74+
model: modelDeploymentName,
75+
name: "Open API Tool Calling Agent",
76+
instructions: "You are a helpful agent.",
77+
tools: [openApiTool]
78+
);
10879
```
10980

110-
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.
81+
3. Now we'll create a `ThreadRun` and wait until it is complete. If the run will not be successful, we'll print the last error.
11382

11483

11584
```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;
122-
123-
Response<ThreadRun> runResponse = await client.CreateRunAsync(thread, agent);
85+
PersistentAgentThread thread = client.CreateThread();
86+
ThreadMessage message = client.CreateMessage(
87+
thread.Id,
88+
MessageRole.User,
89+
"What's the weather in Seattle?");
90+
91+
ThreadRun run = client.CreateRun(thread, agent);
92+
93+
do
94+
{
95+
Thread.Sleep(TimeSpan.FromMilliseconds(500));
96+
run = client.GetRun(thread.Id, run.Id);
97+
}
98+
while (run.Status == RunStatus.Queued
99+
|| run.Status == RunStatus.InProgress
100+
|| run.Status == RunStatus.RequiresAction);
101+
```
124102

125-
do
126-
{
127-
await Task.Delay(TimeSpan.FromMilliseconds(500));
128-
runResponse = await client.GetRunAsync(thread.Id, runResponse.Value.Id);
129-
}
130-
while (runResponse.Value.Status == RunStatus.Queued
131-
|| runResponse.Value.Status == RunStatus.InProgress
132-
|| runResponse.Value.Status == RunStatus.RequiresAction);
133-
#endregion
103+
4. Print the messages to the console in chronological order.
134104

135-
Response<PageableList<ThreadMessage>> afterRunMessagesResponse
136-
= await client.GetMessagesAsync(thread.Id);
137-
IReadOnlyList<ThreadMessage> messages = afterRunMessagesResponse.Value.Data;
105+
```csharp
106+
Pageable<ThreadMessage> messages = client.Messages.GetMessages(
107+
threadId: thread.Id,
108+
order: ListSortOrder.Ascending);
138109

139-
// Note: messages iterate from newest to oldest, with the messages[0] being the most recent
140-
foreach (ThreadMessage threadMessage in messages)
110+
foreach (ThreadMessage threadMessage in messages)
111+
{
112+
foreach (MessageContent content in threadMessage.ContentItems)
141113
{
142-
Console.Write($"{threadMessage.CreatedAt:yyyy-MM-dd HH:mm:ss} - {threadMessage.Role,10}: ");
143-
foreach (MessageContent contentItem in threadMessage.ContentItems)
114+
switch (content)
144115
{
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();
116+
case MessageTextContent textItem:
117+
Console.WriteLine($"[{threadMessage.Role}]: {textItem.Text}");
118+
break;
154119
}
155120
}
121+
}
122+
```
123+
124+
5. Finally, we delete all the resources we have created in this sample.
125+
126+
```csharp
127+
client.DeleteThread(thread.Id);
128+
client.DeleteAgent(agent.Id);
156129
```
157130

158131
:::zone-end
@@ -259,7 +232,7 @@ Create a run and observe that the model uses the OpenAPI Spec tool to provide a
259232

260233
:::zone pivot="rest-api"
261234

262-
## Step 1: Create the OpenAPI Spec tool definition, agent and thread
235+
## Step 1: Create the OpenAPI Spec tool definition, agent, and thread
263236

264237
You might want to store the OpenAPI specification in another file and import the content to initialize the tool. This example is using `anonymous` as the authentication type.
265238

@@ -393,4 +366,3 @@ curl $AZURE_AI_AGENTS_ENDPOINT/threads/thread_abc123/messages?api-version=2024-1
393366
```
394367

395368
:::zone-end
396-

0 commit comments

Comments
 (0)