FLt}4A~6~8JU<2^;y{e!~Fgg;Xlkz
z(7^HYYx|iY8^Fkzk(t?uj+uj%m5#+gpPf#R1zSDl82@38
z!k=A!Kbv$5nK?S}G5&`+{JRFs|MhA4*FiQk`0vAF>tt{F_pgJY0fW&$O~f5O&kNJv
zvutR0)B0I$rfH4l#WeEeX)_p6Om-W5Revb
z^5s0G+LbQrE%%ogD_UB%tdGE(*V$e>2yx=rt-7CYe*-GX$!>I$Y==9ZSmXy5K(E|g*;eYOyL}IIF!eMVHH8Pod
zIebsZKRFpY;ML$?UNt5(cbAa4TX3V>Z7M={cQV0wmliSuS|E>EuA2h|Nl$VD{LqMX
zEwz>C67bS>xSZFa4XN5lMZH|@u4;Ex)B_b2uFkG%cU9B_6&0?|uFATruuqoB9zAyH$9*bXBZ2vT)Y3Clb>vyf6AB%8gt^0M9ZCr-~8gw
z(H%}{*S_qmoZg9a}TV~ChLNp;~l#~k($eqy6vsoFUZ@*n-|8L
z=X;iBVoP%mEzR#AoS7b+>l&Q3Ez}@MH5*6ba&9u1dLIZC*^5@^@0Q
zC}SGD#XEPE$P@)8hD~M|@NlSH#+VKncFJW!$Oe+BI?PL3IfJ44gn?}lCPVe9vWn_c
zWdq9;fpt0bi_I3u_=7l9okLoZa+_7tfK^g1(-=eT!chauxQunVj>kh*I371e5HgjJ
zX@pECWCkHKu?!x(qB#T)5V4GyYn91Qjutcy7yeH~E_b1)fmFxca98w3Xh)%5gf4B;&KEBBRC-T!MX$o
zBRCX-17ajp9}#mgYCp&0Ybdb4*YNJvLJyHy|#jqgW3#QJlk70c)$g
z4Xzr%i)1L4;t&qmV@HsI-ze&4(veu)O1qps-_{{S{jX0Rg)D!Obfyp$!xLWvqT;r;
tt_Qna&aFsUb~*nK+dRE#YYMVVf=Qm-$*ez@Z!
literal 0
HcmV?d00001
diff --git a/dotnet/samples/GettingStarted/Steps/Step03_ChatClientAgent_UsingCodeInterpreterTools.cs b/dotnet/samples/GettingStarted/Steps/Step03_ChatClientAgent_UsingCodeInterpreterTools.cs
index dcd2250a8b..a968ac6ef7 100644
--- a/dotnet/samples/GettingStarted/Steps/Step03_ChatClientAgent_UsingCodeInterpreterTools.cs
+++ b/dotnet/samples/GettingStarted/Steps/Step03_ChatClientAgent_UsingCodeInterpreterTools.cs
@@ -3,9 +3,9 @@
using System.Text;
using Azure.AI.Agents.Persistent;
using Azure.Identity;
+using Microsoft.Extensions.AI;
using Microsoft.Extensions.AI.Agents;
using Microsoft.Shared.Samples;
-using OpenAI.Assistants;
using OpenAI.Files;
namespace Steps;
@@ -21,8 +21,10 @@ public sealed class Step03_ChatClientAgent_UsingCodeInterpreterTools(ITestOutput
[InlineData(ChatClientProviders.OpenAIAssistant)]
public async Task RunningWithFileReferenceAsync(ChatClientProviders provider)
{
- var codeInterpreterTool = new NewHostedCodeInterpreterTool();
- codeInterpreterTool.FileIds.Add(await UploadFileAsync("Resources/groceries.txt", provider));
+ var codeInterpreterTool = new NewHostedCodeInterpreterTool()
+ {
+ Inputs = [new HostedFileContent(await UploadFileAsync("Resources/groceries.txt", provider))]
+ };
var agentOptions = new ChatClientAgentOptions(
name: "HelpfulAssistant",
@@ -51,9 +53,9 @@ public sealed class Step03_ChatClientAgent_UsingCodeInterpreterTools(ITestOutput
assistantOutput.Append(update.Text);
}
- if (update.RawRepresentation is not null)
+ if (update.RawRepresentation is ChatResponseUpdate chatUpdate && chatUpdate.RawRepresentation is not null)
{
- codeInterpreterOutput.Append(GetCodeInterpreterOutput(update.RawRepresentation, provider));
+ codeInterpreterOutput.Append(GetCodeInterpreterOutput(chatUpdate.RawRepresentation, provider));
}
}
diff --git a/dotnet/samples/GettingStarted/Steps/Step04_ChatClientAgent_UsingFileSearchTools.cs b/dotnet/samples/GettingStarted/Steps/Step04_ChatClientAgent_UsingFileSearchTools.cs
new file mode 100644
index 0000000000..7cb8f78a1d
--- /dev/null
+++ b/dotnet/samples/GettingStarted/Steps/Step04_ChatClientAgent_UsingFileSearchTools.cs
@@ -0,0 +1,136 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System.Text;
+using Azure.AI.Agents.Persistent;
+using Azure.Identity;
+using Microsoft.Extensions.AI;
+using Microsoft.Extensions.AI.Agents;
+using Microsoft.Shared.Samples;
+using OpenAI.Files;
+using OpenAI.VectorStores;
+
+namespace Steps;
+
+///
+/// Demonstrates how to use with file search tools and file references.
+/// Shows uploading files to different providers and using them with file search capabilities to retrieve and analyze information from documents.
+///
+public sealed class Step04_ChatClientAgent_UsingFileSearchTools(ITestOutputHelper output) : AgentSample(output)
+{
+ [Theory]
+ [InlineData(ChatClientProviders.AzureAIAgentsPersistent)]
+ [InlineData(ChatClientProviders.OpenAIAssistant)]
+ public async Task RunningWithFileReferenceAsync(ChatClientProviders provider)
+ {
+ // Upload a file to the specified provider.
+ var fileId = await UploadFileAsync("Resources/employees.pdf", provider);
+
+ // Create a vector store for the uploaded file to enable file search capabilities.
+ var vectorStoreId = await CreateVectorStoreAsync([fileId], provider);
+
+ // Create a file search tool that can access the vector store.
+ var fileSearchTool = new NewHostedFileSearchTool()
+ {
+ Inputs = [new HostedVectorStoreContent(vectorStoreId)],
+ };
+
+ var agentOptions = new ChatClientAgentOptions
+ {
+ Name = "FileSearchAssistant",
+ Instructions = "You are a helpful assistant that can search through uploaded documents to answer questions. Use the file search tool to find relevant information from the uploaded files.",
+ ChatOptions = new() { Tools = [fileSearchTool] }
+ };
+
+ // Create the server-side agent Id when applicable (depending on the provider).
+ agentOptions.Id = await base.AgentCreateAsync(provider, agentOptions);
+
+ using var chatClient = base.GetChatClient(provider, agentOptions);
+
+ ChatClientAgent agent = new(chatClient, agentOptions);
+
+ var thread = agent.GetNewThread();
+
+ // Prompt which allows to verify that the file search functionality works correctly with the uploaded document.
+ const string Prompt = "Who is the youngest employee?";
+
+ var assistantOutput = new StringBuilder();
+
+ await foreach (var update in agent.RunStreamingAsync(Prompt, thread))
+ {
+ if (!string.IsNullOrWhiteSpace(update.Text))
+ {
+ assistantOutput.Append(update.Text);
+ }
+ }
+
+ Console.WriteLine("Assistant Output:");
+ Console.WriteLine(assistantOutput.ToString());
+
+ // Clean up the server-side agent after use when applicable (depending on the provider).
+ await base.AgentCleanUpAsync(provider, agent, thread);
+ }
+
+ #region private
+
+ ///
+ /// Uploads a file to the specified chat client provider and returns the file ID.
+ ///
+ /// Path to the file to be uploaded.
+ /// The chat client provider to use for uploading the file.
+ /// The ID of the uploaded file.
+ ///
+ private async Task UploadFileAsync(string filePath, ChatClientProviders provider)
+ {
+ switch (provider)
+ {
+ case ChatClientProviders.OpenAIAssistant:
+ var fileClient = new OpenAIFileClient(TestConfiguration.OpenAI.ApiKey);
+ OpenAIFile openAIFileInfo = await fileClient.UploadFileAsync(filePath, FileUploadPurpose.Assistants);
+
+ return openAIFileInfo.Id;
+ case ChatClientProviders.AzureAIAgentsPersistent:
+ var persistentAgentsClient = new PersistentAgentsClient(TestConfiguration.AzureAI.Endpoint, new AzureCliCredential());
+ PersistentAgentFileInfo persistentAgentFileInfo = await persistentAgentsClient.Files.UploadFileAsync(filePath, PersistentAgentFilePurpose.Agents);
+
+ return persistentAgentFileInfo.Id;
+
+ default:
+ throw new NotSupportedException($"Client provider {provider} is not supported.");
+ }
+ }
+
+ private Task CreateVectorStoreAsync(IEnumerable fileIds, ChatClientProviders provider)
+ {
+ switch (provider)
+ {
+ case ChatClientProviders.OpenAIAssistant:
+ return CreateVectorStoreOpenAIAssistantAsync(fileIds);
+ case ChatClientProviders.AzureAIAgentsPersistent:
+ return CreateVectorStoreAzureAIAgentsPersistentAsync(fileIds);
+ default:
+ throw new NotSupportedException($"Client provider {provider} is not supported.");
+ }
+ }
+
+ private async Task CreateVectorStoreOpenAIAssistantAsync(IEnumerable fileIds)
+ {
+ var vectorStoreClient = new VectorStoreClient(TestConfiguration.OpenAI.ApiKey);
+ VectorStoreCreationOptions options = new();
+ foreach (var fileId in fileIds)
+ {
+ options.FileIds.Add(fileId);
+ }
+
+ var vectorStore = await vectorStoreClient.CreateVectorStoreAsync(waitUntilCompleted: true, options);
+ return vectorStore.VectorStoreId;
+ }
+
+ private async Task CreateVectorStoreAzureAIAgentsPersistentAsync(IEnumerable fileIds)
+ {
+ var client = new PersistentAgentsClient(TestConfiguration.AzureAI.Endpoint, new AzureCliCredential());
+ var vectorStore = await client.VectorStores.CreateVectorStoreAsync(fileIds);
+ return vectorStore.Value.Id;
+ }
+
+ #endregion
+}