Skip to content

Commit 3c10b9d

Browse files
authored
Merge pull request #4723 from RobiladK/patch-3
Update code-interpreter-samples.md
2 parents e9f47a8 + b07f953 commit 3c10b9d

File tree

1 file changed

+148
-70
lines changed

1 file changed

+148
-70
lines changed

articles/ai-services/agents/how-to/tools/code-interpreter-samples.md

Lines changed: 148 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -144,125 +144,203 @@ for image_content in messages.image_contents:
144144

145145
:::zone pivot="csharp"
146146

147-
## Create a project client
147+
## Using the .NET SDK
148148

149-
To use code interpreter, first you need to create a project client, which will contain a connection string to your AI project, and will be used to authenticate API calls.
149+
In this example we will demonstrate the Agent streaming support, code interpreter creating an image and downloading and viewing the image.
150+
151+
1. First, we set up configuration using `appsettings.json`, create a `PersistentAgentsClient`, and then create a `PersistentAgent` with the Code Interpreter tool.
150152

151153
```csharp
152-
var connectionString = Environment.GetEnvironmentVariable("PROJECT_CONNECTION_STRING");
153-
AgentsClient client = new AgentsClient(connectionString, new DefaultAzureCredential());
154+
using Azure;
155+
using Azure.AI.Agents.Persistent;
156+
using Azure.Identity;
157+
using Microsoft.Extensions.Configuration;
158+
using System.Diagnostics;
159+
160+
IConfigurationRoot configuration = new ConfigurationBuilder()
161+
.SetBasePath(AppContext.BaseDirectory)
162+
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
163+
.Build();
164+
165+
var projectEndpoint = configuration["ProjectEndpoint"];
166+
var modelDeploymentName = configuration["ModelDeploymentName"];
167+
168+
PersistentAgentsClient client = new(projectEndpoint, new DefaultAzureCredential());
154169
```
155170

156-
## Upload a File
171+
Synchronous sample:
157172

158-
Files can be uploaded and then referenced by agents or messages. First, use the generalized upload API with a `purpose` of `Agents` to make a file ID available. Once uploaded, the file ID can then be provided to create a vector store for it. The vector store ID can then be provided to an agent upon creation.
173+
```csharp
174+
PersistentAgent agent = client.Administration.CreateAgent(
175+
model: modelDeploymentName,
176+
name: "My Friendly Test Agent",
177+
instructions: "You politely help with math questions. Use the code interpreter tool when asked to visualize numbers.",
178+
tools: [new CodeInterpreterToolDefinition()]
179+
);
180+
```
181+
182+
Asynchronous sample:
159183

160184
```csharp
161-
// Upload a file and wait for it to be processed
162-
Response<AgentFile> uploadAgentFileResponse = await client.UploadFileAsync(
163-
filePath: "sample_file_for_upload.txt",
164-
purpose: AgentFilePurpose.Agents);
185+
PersistentAgent agent = await client.Administration.CreateAgentAsync(
186+
model: modelDeploymentName,
187+
name: "My Friendly Test Agent",
188+
instructions: "You politely help with math questions. Use the code interpreter tool when asked to visualize numbers.",
189+
tools: [new CodeInterpreterToolDefinition()]
190+
);
191+
```
192+
193+
2. Next, we create a `PersistentAgentThread` and add a user message to it.
165194

166-
AgentFile uploadedAgentFile = uploadAgentFileResponse.Value;
195+
Synchronous sample:
167196

168-
// Create a vector store with the file and wait for it to be processed.
169-
// If you do not specify a vector store, create_message will create a vector store with a default expiration policy of seven days after they were last active
170-
VectorStore vectorStore = await client.CreateVectorStoreAsync(
171-
fileIds: new List<string> { uploadedAgentFile.Id },
172-
name: "my_vector_store");
197+
```csharp
198+
PersistentAgentThread thread = client.Threads.CreateThread();
173199

174-
CodeInterpreterToolResource codeInterpreterToolResource = new CodeInterpreterToolResource();
175-
CodeInterpreterToolResource.VectorStoreIds.Add(vectorStore.Id);
200+
client.Messages.CreateMessage(
201+
thread.Id,
202+
MessageRole.User,
203+
"Hi, Agent! Draw a graph for a line with a slope of 4 and y-intercept of 9.");
176204
```
177205

178-
## Create an Agent with the Code Interpreter Tool
206+
Asynchronous sample:
179207

180208
```csharp
181-
Response<Agent> agentResponse = await client.CreateAgentAsync(
182-
model: "gpt-4o-mini",
183-
name: "My agent",
184-
instructions: "You are a helpful agent.",
185-
tools: new List<ToolDefinition> { new CodeInterpreterToolDefinition() },
186-
toolResources: new ToolResources() { CodeInterpreter = codeInterpreterToolResource });
187-
Agent agent = agentResponse.Value;
209+
PersistentAgentThread thread = await client.Threads.CreateThreadAsync();
210+
211+
await client.Messages.CreateMessageAsync(
212+
thread.Id,
213+
MessageRole.User,
214+
"Hi, Agent! Draw a graph for a line with a slope of 4 and y-intercept of 9.");
188215
```
189216

190-
## Create a Thread, Message, and Get the Agent Response
217+
3. Then, we create a `ThreadRun` for the thread and agent, providing any additional instructions. We poll the run's status until it is no longer queued, in progress, or requires action.
191218

192-
Next create a thread with `CreateThreadAsync()` and a thread with `CreateMessageAsync()`. After the thread is created, you can add messages to it with `CreateMessageAsync()` that will cause the code interpreter tool to trigger. Create a run, and then continue polling it until it reaches a terminal status. Assuming the run was successful, parse the agent's response by listing the messages.
219+
Synchronous sample:
193220

194221
```csharp
195-
//Create a thread
196-
Response<AgentThread> threadResponse = await client.CreateThreadAsync();
197-
AgentThread thread = threadResponse.Value;
198-
199-
//With a thread created, messages can be created on it:
200-
Response<ThreadMessage> messageResponse = await client.CreateMessageAsync(
222+
ThreadRun run = client.Runs.CreateRun(
201223
thread.Id,
202-
MessageRole.User,
203-
"I need to solve the equation `3x + 11 = 14`. Can you help me?");
204-
ThreadMessage message = messageResponse.Value;
224+
agent.Id,
225+
additionalInstructions: "Please address the user as Jane Doe. The user has a premium account.");
205226

206-
//A run can then be started that evaluates the thread against an agent:
207-
Response<ThreadRun> runResponse = await client.CreateRunAsync(
227+
do
228+
{
229+
Thread.Sleep(TimeSpan.FromMilliseconds(500));
230+
run = client.Runs.GetRun(thread.Id, run.Id);
231+
}
232+
while (run.Status == RunStatus.Queued
233+
|| run.Status == RunStatus.InProgress
234+
|| run.Status == RunStatus.RequiresAction);
235+
```
236+
237+
Asynchronous sample:
238+
239+
```csharp
240+
ThreadRun run = await client.Runs.CreateRunAsync(
208241
thread.Id,
209242
agent.Id,
210243
additionalInstructions: "Please address the user as Jane Doe. The user has a premium account.");
211-
ThreadRun run = runResponse.Value;
212244

213-
//Once the run has started, it should then be polled until it reaches a terminal status:
214245
do
215246
{
216247
await Task.Delay(TimeSpan.FromMilliseconds(500));
217-
runResponse = await client.GetRunAsync(thread.Id, runResponse.Value.Id);
248+
run = await client.Runs.GetRunAsync(thread.Id, run.Id);
218249
}
219-
while (runResponse.Value.Status == RunStatus.Queued
220-
|| runResponse.Value.Status == RunStatus.InProgress);
250+
while (run.Status == RunStatus.Queued
251+
|| run.Status == RunStatus.InProgress
252+
|| run.Status == RunStatus.RequiresAction);
253+
```
254+
255+
4. Once the run is finished, we retrieve all messages from the thread. We then iterate through the messages to display text content and handle any image files by saving them locally and opening them.
221256

222-
//Assuming the run successfully completed, listing messages from the thread that was run will now reflect new information added by the agent:
257+
Synchronous sample:
223258

224-
Response<PageableList<ThreadMessage>> afterRunMessagesResponse
225-
= await client.GetMessagesAsync(thread.Id);
226-
IReadOnlyList<ThreadMessage> messages = afterRunMessagesResponse.Value.Data;
259+
```csharp
260+
Pageable<ThreadMessage> messages = client.Messages.GetMessages(
261+
threadId: thread.Id,
262+
order: ListSortOrder.Ascending);
227263

228-
// Note: messages iterate from newest to oldest, with the messages[0] being the most recent
229264
foreach (ThreadMessage threadMessage in messages)
230265
{
231-
Console.Write($"{threadMessage.CreatedAt:yyyy-MM-dd HH:mm:ss} - {threadMessage.Role,10}: ");
232-
foreach (MessageContent contentItem in threadMessage.ContentItems)
266+
foreach (MessageContent content in threadMessage.ContentItems)
233267
{
234-
if (contentItem is MessageTextContent textItem)
235-
{
236-
Console.Write(textItem.Text);
237-
}
238-
else if (contentItem is MessageImageFileContent imageFileItem)
268+
switch (content)
239269
{
240-
Console.Write($"<image from ID: {imageFileItem.FileId}");
270+
case MessageTextContent textItem:
271+
Console.WriteLine($"[{threadMessage.Role}]: {textItem.Text}");
272+
break;
273+
case MessageImageFileContent imageFileContent:
274+
Console.WriteLine($"[{threadMessage.Role}]: Image content file ID = {imageFileContent.FileId}");
275+
BinaryData imageContent = client.Files.GetFileContent(imageFileContent.FileId);
276+
string tempFilePath = Path.Combine(AppContext.BaseDirectory, $"{Guid.NewGuid()}.png");
277+
File.WriteAllBytes(tempFilePath, imageContent.ToArray());
278+
client.Files.DeleteFile(imageFileContent.FileId);
279+
280+
ProcessStartInfo psi = new()
281+
{
282+
FileName = tempFilePath,
283+
UseShellExecute = true
284+
};
285+
Process.Start(psi);
286+
break;
241287
}
242-
Console.WriteLine();
243288
}
244289
}
245290
```
246291

247-
## Download Files Generated by Code Interpreter
248-
249-
Files generated by code interpreter can be found in the Agent message responses. You can download image files generated by code interpreter by iterating through the response's messages and checking for an `ImageFileId`. If that field exists, use the following code:
292+
Asynchronous sample:
250293

251294
```csharp
252-
foreach (MessageContent contentItem in message.Content)
295+
AsyncPageable<ThreadMessage> messages = client.Messages.GetMessagesAsync(
296+
threadId: thread.Id,
297+
order: ListSortOrder.Ascending);
298+
299+
await foreach (ThreadMessage threadMessage in messages)
253300
{
254-
if (!string.IsNullOrEmpty(contentItem.ImageFileId))
301+
foreach (MessageContent content in threadMessage.ContentItems)
255302
{
256-
OpenAIFileInfo imageInfo = await fileClient.GetFileAsync(contentItem.ImageFileId);
257-
BinaryData imageBytes = await fileClient.DownloadFileAsync(contentItem.ImageFileId);
258-
using FileStream stream = File.OpenWrite($"{imageInfo.Filename}.png");
259-
imageBytes.ToStream().CopyTo(stream);
260-
261-
Console.WriteLine($"<image: {imageInfo.Filename}.png>");
303+
switch (content)
304+
{
305+
case MessageTextContent textItem:
306+
Console.WriteLine($"[{threadMessage.Role}]: {textItem.Text}");
307+
break;
308+
case MessageImageFileContent imageFileContent:
309+
Console.WriteLine($"[{threadMessage.Role}]: Image content file ID = {imageFileContent.FileId}");
310+
BinaryData imageContent = await client.Files.GetFileContentAsync(imageFileContent.FileId);
311+
string tempFilePath = Path.Combine(AppContext.BaseDirectory, $"{Guid.NewGuid()}.png");
312+
File.WriteAllBytes(tempFilePath, imageContent.ToArray());
313+
await client.Files.DeleteFileAsync(imageFileContent.FileId);
314+
315+
ProcessStartInfo psi = new()
316+
{
317+
FileName = tempFilePath,
318+
UseShellExecute = true
319+
};
320+
Process.Start(psi);
321+
break;
322+
}
262323
}
263324
}
264325
```
265326

327+
5. Finally, we delete the thread and the agent to clean up the resources created in this sample.
328+
329+
Synchronous sample:
330+
331+
```csharp
332+
client.Threads.DeleteThread(threadId: thread.Id);
333+
client.Administration.DeleteAgent(agentId: agent.Id);
334+
```
335+
336+
Asynchronous sample:
337+
338+
```csharp
339+
await client.Threads.DeleteThreadAsync(threadId: thread.Id);
340+
await client.Administration.DeleteAgentAsync(agentId: agent.Id);
341+
```
342+
343+
266344
:::zone-end
267345

268346
:::zone pivot="javascript"
@@ -470,4 +548,4 @@ curl $AZURE_AI_AGENTS_ENDPOINT/threads/thread_abc123/messages?api-version=2024-1
470548
-H "Authorization: Bearer $AZURE_AI_AGENTS_TOKEN"
471549
```
472550
473-
:::zone-end
551+
:::zone-end

0 commit comments

Comments
 (0)