Skip to content

Commit 77ef895

Browse files
authored
[AI] [Projects] add fabric sample (Azure#48473)
* add fabric sample * add sharepoint sample * Update sample and add readme * add SHAREPOINTCONNECTIONNAME to test env * snippets updated * review feedback
1 parent 719f702 commit 77ef895

File tree

5 files changed

+605
-0
lines changed

5 files changed

+605
-0
lines changed
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
# Sample for use of an Agent with Fabric tool in Azure.AI.Projects.
2+
3+
To enable your Agent to perform search against a Fabric resource, you use `MicrosoftFabricToolDefinition` along with a connection.
4+
1. First we need to create an Agent client and read the environment variables, which will be used in the next steps.
5+
6+
```C# Snippet:Fabric_CreateProject
7+
var connectionString = System.Environment.GetEnvironmentVariable("PROJECT_CONNECTION_STRING");
8+
var modelDeploymentName = System.Environment.GetEnvironmentVariable("MODEL_DEPLOYMENT_NAME");
9+
var fabricConnectionName = System.Environment.GetEnvironmentVariable("FABRIC_CONNECTION_NAME");
10+
11+
var projectClient = new AIProjectClient(connectionString, new DefaultAzureCredential());
12+
13+
AgentsClient agentClient = projectClient.GetAgentsClient();
14+
```
15+
16+
2. Next we will get the Fabric connection by name using connection client. This connection will be used to initialize the `MicrosoftFabricToolDefinition`.
17+
18+
Synchronous sample:
19+
```C# Snippet:Fabric_GetConnection
20+
ConnectionResponse fabricConnection = projectClient.GetConnectionsClient().GetConnection(fabricConnectionName);
21+
var connectionId = fabricConnection.Id;
22+
23+
ToolConnectionList connectionList = new()
24+
{
25+
ConnectionList = { new ToolConnection(connectionId) }
26+
};
27+
MicrosoftFabricToolDefinition fabricTool = new(connectionList);
28+
```
29+
30+
Asynchronous sample:
31+
```C# Snippet:FabricAsync_GetConnection
32+
ConnectionResponse fabricConnection = await projectClient.GetConnectionsClient().GetConnectionAsync(fabricConnectionName);
33+
var connectionId = fabricConnection.Id;
34+
35+
ToolConnectionList connectionList = new()
36+
{
37+
ConnectionList = { new ToolConnection(connectionId) }
38+
};
39+
MicrosoftFabricToolDefinition fabricTool = new(connectionList);
40+
```
41+
42+
3. We will use the `MicrosoftFabricToolDefinition` during the Agent initialization.
43+
44+
Synchronous sample:
45+
```C# Snippet:Fabric_CreateAgent
46+
Agent agent = agentClient.CreateAgent(
47+
model: modelDeploymentName,
48+
name: "my-assistant",
49+
instructions: "You are a helpful assistant.",
50+
tools: [fabricTool]);
51+
```
52+
53+
Asynchronous sample:
54+
```C# Snippet:FabricAsync_CreateAgent
55+
Agent agent = await agentClient.CreateAgentAsync(
56+
model: modelDeploymentName,
57+
name: "my-assistant",
58+
instructions: "You are a helpful assistant.",
59+
tools: [ fabricTool ]);
60+
```
61+
62+
4. Now we will create the thread, add the message containing a question for the Agent and start the run.
63+
64+
Synchronous sample:
65+
```C# Snippet:Fabric_CreateThreadMessage
66+
AgentThread thread = agentClient.CreateThread();
67+
68+
// Create message to thread
69+
ThreadMessage message = agentClient.CreateMessage(
70+
thread.Id,
71+
MessageRole.User,
72+
"What are the top 3 weather events with highest property damage?");
73+
74+
// Run the agent
75+
ThreadRun run = agentClient.CreateRun(thread, agent);
76+
do
77+
{
78+
Thread.Sleep(TimeSpan.FromMilliseconds(500));
79+
run = agentClient.GetRun(thread.Id, run.Id);
80+
}
81+
while (run.Status == RunStatus.Queued
82+
|| run.Status == RunStatus.InProgress);
83+
84+
Assert.AreEqual(
85+
RunStatus.Completed,
86+
run.Status,
87+
run.LastError?.Message);
88+
```
89+
90+
Asynchronous sample:
91+
```C# Snippet:FabricAsync_CreateThreadMessage
92+
AgentThread thread = await agentClient.CreateThreadAsync();
93+
94+
// Create message to thread
95+
ThreadMessage message = await agentClient.CreateMessageAsync(
96+
thread.Id,
97+
MessageRole.User,
98+
"What are the top 3 weather events with highest property damage?");
99+
100+
// Run the agent
101+
ThreadRun run = await agentClient.CreateRunAsync(thread, agent);
102+
do
103+
{
104+
await Task.Delay(TimeSpan.FromMilliseconds(500));
105+
run = await agentClient.GetRunAsync(thread.Id, run.Id);
106+
}
107+
while (run.Status == RunStatus.Queued
108+
|| run.Status == RunStatus.InProgress);
109+
110+
Assert.AreEqual(
111+
RunStatus.Completed,
112+
run.Status,
113+
run.LastError?.Message);
114+
```
115+
116+
5. Print the Agent messages to console in chronological order.
117+
118+
Synchronous sample:
119+
```C# Snippet:Fabric_Print
120+
PageableList<ThreadMessage> messages = agentClient.GetMessages(
121+
threadId: thread.Id,
122+
order: ListSortOrder.Ascending
123+
);
124+
125+
foreach (ThreadMessage threadMessage in messages)
126+
{
127+
Console.Write($"{threadMessage.CreatedAt:yyyy-MM-dd HH:mm:ss} - {threadMessage.Role,10}: ");
128+
foreach (MessageContent contentItem in threadMessage.ContentItems)
129+
{
130+
if (contentItem is MessageTextContent textItem)
131+
{
132+
string response = textItem.Text;
133+
if (textItem.Annotations != null)
134+
{
135+
foreach (MessageTextAnnotation annotation in textItem.Annotations)
136+
{
137+
if (annotation is MessageTextUrlCitationAnnotation urlAnnotation)
138+
{
139+
response = response.Replace(urlAnnotation.Text, $" [{urlAnnotation.UrlCitation.Title}]({urlAnnotation.UrlCitation.Url})");
140+
}
141+
}
142+
}
143+
Console.Write($"Agent response: {response}");
144+
}
145+
else if (contentItem is MessageImageFileContent imageFileItem)
146+
{
147+
Console.Write($"<image from ID: {imageFileItem.FileId}");
148+
}
149+
Console.WriteLine();
150+
}
151+
}
152+
```
153+
154+
Asynchronous sample:
155+
```C# Snippet:FabricAsync_Print
156+
PageableList<ThreadMessage> messages = await agentClient.GetMessagesAsync(
157+
threadId: thread.Id,
158+
order: ListSortOrder.Ascending
159+
);
160+
161+
foreach (ThreadMessage threadMessage in messages)
162+
{
163+
Console.Write($"{threadMessage.CreatedAt:yyyy-MM-dd HH:mm:ss} - {threadMessage.Role,10}: ");
164+
foreach (MessageContent contentItem in threadMessage.ContentItems)
165+
{
166+
if (contentItem is MessageTextContent textItem)
167+
{
168+
string response = textItem.Text;
169+
if (textItem.Annotations != null)
170+
{
171+
foreach (MessageTextAnnotation annotation in textItem.Annotations)
172+
{
173+
if (annotation is MessageTextUrlCitationAnnotation urlAnnotation)
174+
{
175+
response = response.Replace(urlAnnotation.Text, $" [{urlAnnotation.UrlCitation.Title}]({urlAnnotation.UrlCitation.Url})");
176+
}
177+
}
178+
}
179+
Console.Write($"Agent response: {response}");
180+
}
181+
else if (contentItem is MessageImageFileContent imageFileItem)
182+
{
183+
Console.Write($"<image from ID: {imageFileItem.FileId}");
184+
}
185+
Console.WriteLine();
186+
}
187+
}
188+
```
189+
190+
6. Clean up resources by deleting the thread and the Agent.
191+
192+
Synchronous sample:
193+
```C# Snippet:FabricCleanup
194+
agentClient.DeleteThread(threadId: thread.Id);
195+
agentClient.DeleteAgent(agentId: agent.Id);
196+
```
197+
198+
Asynchronous sample:
199+
```C# Snippet:FabricCleanupAsync
200+
await agentClient.DeleteThreadAsync(threadId: thread.Id);
201+
await agentClient.DeleteAgentAsync(agentId: agent.Id);
202+
```

sdk/ai/Azure.AI.Projects/tests/AIProjectsTestEnvironment.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,7 @@ public class AIProjectsTestEnvironment : TestEnvironment
1313
public string EMBEDDINGMODELDEPLOYMENTNAME => GetRecordedVariable("EMBEDDING_MODEL_DEPLOYMENT_NAME");
1414
public string STORAGE_QUEUE_URI => GetRecordedVariable("STORAGE_QUEUE_URI");
1515
public string AZURE_BLOB_URI => GetRecordedVariable("AZURE_BLOB_URI");
16+
public string FABRICCONNECTIONNAME => GetRecordedVariable("FABRIC_CONNECTION_NAME");
17+
public string SHAREPOINTCONNECTIONNAME => GetRecordedVariable("SHAREPOINT_CONNECTION_NAME");
1618
}
1719
}

0 commit comments

Comments
 (0)