diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/CodeInterpreterToolExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/CodeInterpreterToolExtensions.cs
new file mode 100644
index 0000000000..e45fe4c5e5
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/CodeInterpreterToolExtensions.cs
@@ -0,0 +1,64 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System.Collections.Generic;
+using System.Linq;
+using Azure.AI.Agents.Persistent;
+using Microsoft.Shared.Diagnostics;
+
+namespace Microsoft.Bot.ObjectModel;
+
+///
+/// Extension methods for .
+///
+internal static class CodeInterpreterToolExtensions
+{
+ ///
+ /// Creates a from a .
+ ///
+ /// Instance of
+ internal static CodeInterpreterToolDefinition CreateCodeInterpreterToolDefinition(this CodeInterpreterTool tool)
+ {
+ Throw.IfNull(tool);
+
+ return new CodeInterpreterToolDefinition();
+ }
+
+ ///
+ /// Converts a to an .
+ ///
+ /// Instance of
+ /// A new instance configured with the container ID from the tool's extension data.
+ internal static OpenAI.Responses.CodeInterpreterTool CreateCodeInterpreterTool(this CodeInterpreterTool tool)
+ {
+ Throw.IfNull(tool);
+
+ var containerId = tool.ExtensionData?.GetPropertyOrNull(InitializablePropertyPath.Create("containerId"))?.Value;
+ Throw.IfNull(containerId, "The 'containerId' property must be specified in the CodeInterpreterTool's extension data to create a code interpreter tool.");
+
+ return new OpenAI.Responses.CodeInterpreterTool(new OpenAI.Responses.CodeInterpreterToolContainer(containerId));
+ }
+
+ ///
+ /// Collects the file IDs from the extension data of a .
+ ///
+ /// Instance of
+ internal static List? GetFileIds(this CodeInterpreterTool tool)
+ {
+ var fileIds = tool.ExtensionData?.GetPropertyOrNull(InitializablePropertyPath.Create("fileIds"));
+ return fileIds is not null
+ ? [.. fileIds.Values.Select(fileId => fileId.GetPropertyOrNull(InitializablePropertyPath.Create("value"))?.Value)]
+ : null;
+ }
+
+ ///
+ /// Collects the data sources from the extension data of a .
+ ///
+ /// Instance of
+ internal static List? GetDataSources(this CodeInterpreterTool tool)
+ {
+ var dataSources = tool.ExtensionData?.GetPropertyOrNull(InitializablePropertyPath.Create("dataSources"));
+ return dataSources is not null
+ ? dataSources.Values.Select(dataSource => dataSource.CreateDataSource()).ToList()
+ : null;
+ }
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/FileSearchToolExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/FileSearchToolExtensions.cs
new file mode 100644
index 0000000000..e582672f93
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/FileSearchToolExtensions.cs
@@ -0,0 +1,67 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System.Collections.Generic;
+using System.Linq;
+using Azure.AI.Agents.Persistent;
+using Microsoft.Shared.Diagnostics;
+
+namespace Microsoft.Bot.ObjectModel;
+
+///
+/// Extension methods for .
+///
+internal static class FileSearchToolExtensions
+{
+ ///
+ /// Creates a from a .
+ ///
+ /// Instance of
+ internal static FileSearchToolDefinition CreateFileSearchToolDefinition(this FileSearchTool tool)
+ {
+ Throw.IfNull(tool);
+
+ // TODO: Add support for FileSearchToolDefinitionDetails.
+
+ return new FileSearchToolDefinition();
+ }
+
+ ///
+ /// Creates an from a .
+ ///
+ /// Instance of
+ /// A new instance configured with the vector store IDs.
+ internal static OpenAI.Responses.FileSearchTool CreateFileSearchTool(this FileSearchTool tool)
+ {
+ Throw.IfNull(tool);
+
+ return new OpenAI.Responses.FileSearchTool(tool.GetVectorStoreIds());
+ }
+
+ ///
+ /// Get the vector store IDs for the specified .
+ ///
+ /// Instance of
+ internal static List? GetVectorStoreIds(this FileSearchTool tool)
+ {
+ return tool.VectorStoreIds?.LiteralValue.ToList();
+ }
+
+ internal static IList? GetVectorStoreConfigurations(this FileSearchTool tool)
+ {
+ var dataSources = tool.ExtensionData?.GetPropertyOrNull(InitializablePropertyPath.Create("options.configurations"));
+ return dataSources?.Values.Select(value => value.CreateVectorStoreConfiguration()).ToList();
+ }
+
+ internal static VectorStoreConfigurations CreateVectorStoreConfiguration(this RecordDataValue value)
+ {
+ Throw.IfNull(value);
+
+ var storeName = value.GetPropertyOrNull(InitializablePropertyPath.Create("storeName"))?.Value;
+ Throw.IfNullOrEmpty(storeName);
+
+ var dataSources = value.GetDataSources();
+ Throw.IfNull(dataSources);
+
+ return new VectorStoreConfigurations(storeName, new VectorStoreConfiguration(dataSources));
+ }
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/FunctionToolExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/FunctionToolExtensions.cs
new file mode 100644
index 0000000000..73bd9b41b2
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/FunctionToolExtensions.cs
@@ -0,0 +1,67 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System;
+using Azure.AI.Agents.Persistent;
+using Microsoft.Shared.Diagnostics;
+using OpenAI.Responses;
+
+namespace Microsoft.Bot.ObjectModel;
+
+///
+/// Extension methods for .
+///
+public static class FunctionToolExtensions
+{
+ ///
+ /// Creates a from a .
+ ///
+ /// Instance of
+ internal static FunctionToolDefinition CreateFunctionToolDefinition(this InvokeClientTaskAction tool)
+ {
+ Throw.IfNull(tool);
+ Throw.IfNull(tool.Name);
+
+ BinaryData parameters = tool.GetParameters();
+
+ return new FunctionToolDefinition(
+ name: tool.Name,
+ description: tool.Description,
+ parameters: parameters);
+ }
+
+ ///
+ /// Creates a from a .
+ ///
+ /// Instance of
+ /// A new instance configured with the function name, parameters, and description.
+ internal static FunctionTool CreateFunctionTool(this InvokeClientTaskAction tool)
+ {
+ Throw.IfNull(tool);
+ Throw.IfNull(tool.Name);
+
+ BinaryData parameters = tool.GetParameters();
+
+ return new FunctionTool(
+ functionName: tool.Name,
+ functionParameters: parameters,
+ strictModeEnabled: null)
+ {
+ FunctionDescription = tool.Description
+ };
+ }
+
+ ///
+ /// Creates the parameters schema for a .
+ ///
+ /// Instance of
+ internal static BinaryData GetParameters(this InvokeClientTaskAction tool)
+ {
+ Throw.IfNull(tool);
+
+ var parameters = tool.ClientActionInputSchema?.GetSchema().ToString() ?? DefaultSchema;
+
+ return new BinaryData(parameters);
+ }
+
+ private const string DefaultSchema = "{\"type\":\"object\",\"properties\":{},\"additionalProperties\":false}";
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/HostedCodeInterpreterToolExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/HostedCodeInterpreterToolExtensions.cs
new file mode 100644
index 0000000000..da769856dd
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/HostedCodeInterpreterToolExtensions.cs
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using Azure.AI.Agents.Persistent;
+using Microsoft.Bot.ObjectModel;
+using Microsoft.Shared.Diagnostics;
+
+namespace Microsoft.Extensions.AI;
+
+///
+/// Extension methods for .
+///
+internal static class HostedCodeInterpreterToolExtensions
+{
+ ///
+ /// Creates a from a .
+ ///
+ /// Instance of
+ internal static CodeInterpreterToolDefinition CreateHostedCodeInterpreterToolDefinition(this HostedCodeInterpreterTool tool)
+ {
+ Throw.IfNull(tool);
+
+ return new CodeInterpreterToolDefinition();
+ }
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/HostedFileSearchToolExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/HostedFileSearchToolExtensions.cs
new file mode 100644
index 0000000000..846e28f226
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/HostedFileSearchToolExtensions.cs
@@ -0,0 +1,25 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using Azure.AI.Agents.Persistent;
+using Microsoft.Shared.Diagnostics;
+
+namespace Microsoft.Extensions.AI;
+
+///
+/// Extension methods for .
+///
+internal static class HostedFileSearchToolExtensions
+{
+ ///
+ /// Creates a from a .
+ ///
+ /// Instance of
+ internal static FileSearchToolDefinition CreateFileSearchToolDefinition(this HostedFileSearchTool tool)
+ {
+ Throw.IfNull(tool);
+
+ // TODO: Add support for FileSearchToolDefinitionDetails.
+
+ return new FileSearchToolDefinition();
+ }
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/HostedMcpServerToolExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/HostedMcpServerToolExtensions.cs
new file mode 100644
index 0000000000..a879a105bc
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/HostedMcpServerToolExtensions.cs
@@ -0,0 +1,28 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System.Linq;
+using Azure.AI.Agents.Persistent;
+using Microsoft.Shared.Diagnostics;
+
+namespace Microsoft.Extensions.AI;
+
+///
+/// Extension methods for .
+///
+internal static class HostedMcpServerToolExtensions
+{
+ ///
+ /// Creates a from a .
+ ///
+ /// Instance of
+ internal static MCPToolDefinition CreateMcpToolDefinition(this HostedMcpServerTool tool)
+ {
+ Throw.IfNull(tool);
+ Throw.IfNull(tool.ServerName);
+ Throw.IfNull(tool.ServerAddress);
+
+ var definition = new MCPToolDefinition(tool.ServerName, tool.ServerAddress);
+ tool.AllowedTools?.ToList().ForEach(definition.AllowedTools.Add);
+ return definition;
+ }
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/HostedWebSearchToolExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/HostedWebSearchToolExtensions.cs
new file mode 100644
index 0000000000..f13c0ec2d4
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/HostedWebSearchToolExtensions.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using Azure.AI.Agents.Persistent;
+using Microsoft.Shared.Diagnostics;
+
+namespace Microsoft.Extensions.AI;
+
+///
+/// Extension methods for .
+///
+internal static class HostedWebSearchToolExtensions
+{
+ ///
+ /// Creates a from a .
+ ///
+ /// Instance of
+ internal static BingGroundingToolDefinition CreateBingGroundingToolDefinition(this HostedWebSearchTool tool)
+ {
+ Throw.IfNull(tool);
+
+ // TODO: Add support for BingGroundingSearchToolParameters.
+ var parameters = new BingGroundingSearchToolParameters([]);
+
+ return new BingGroundingToolDefinition(parameters);
+ }
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/McpServerToolExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/McpServerToolExtensions.cs
new file mode 100644
index 0000000000..0e74f53e9a
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/McpServerToolExtensions.cs
@@ -0,0 +1,53 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System;
+using Azure.AI.Agents.Persistent;
+using Microsoft.Shared.Diagnostics;
+using OpenAI.Responses;
+
+namespace Microsoft.Bot.ObjectModel;
+
+///
+/// Extension methods for .
+///
+internal static class McpServerToolExtensions
+{
+ ///
+ /// Creates a from a .
+ ///
+ /// Instance of
+ internal static MCPToolDefinition CreateMcpToolDefinition(this McpServerTool tool)
+ {
+ Throw.IfNull(tool);
+ Throw.IfNull(tool.ServerName?.LiteralValue);
+ Throw.IfNull(tool.Connection);
+
+ // TODO: Add support for additional properties
+
+ var connection = tool.Connection as AnonymousConnection ?? throw new ArgumentException($"Only AnonymousConnection is supported for MCP Server Tool connections. Actual connection type: {tool.Connection.GetType().Name}", nameof(tool));
+ var serverUrl = connection.Endpoint?.LiteralValue;
+ Throw.IfNullOrEmpty(serverUrl, nameof(connection.Endpoint));
+
+ return new MCPToolDefinition(tool.ServerName?.LiteralValue, serverUrl);
+ }
+
+ ///
+ /// Creates a from a .
+ ///
+ /// Instance of
+ /// A new instance configured with the server name and URL.
+ internal static McpTool CreateMcpTool(this McpServerTool tool)
+ {
+ Throw.IfNull(tool);
+ Throw.IfNull(tool.ServerName?.LiteralValue);
+ Throw.IfNull(tool.Connection);
+
+ // TODO: Add support for headers
+
+ var connection = tool.Connection as AnonymousConnection ?? throw new ArgumentException("Only AnonymousConnection is supported for MCP Server Tool connections.", nameof(tool));
+ var serverUrl = connection.Endpoint?.LiteralValue;
+ Throw.IfNullOrEmpty(serverUrl, nameof(connection.Endpoint));
+
+ return new McpTool(tool.ServerName?.LiteralValue, serverUrl);
+ }
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/PromptAgentExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/PromptAgentExtensions.cs
new file mode 100644
index 0000000000..3fb7c64c1b
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/PromptAgentExtensions.cs
@@ -0,0 +1,142 @@
+// Copyright (c) Microsoft. All rights reserved.
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Azure.AI.Agents.Persistent;
+using Microsoft.Shared.Diagnostics;
+using OpenAI.Responses;
+
+namespace Microsoft.Bot.ObjectModel;
+
+///
+/// Extension methods for .
+///
+internal static class PromptAgentExtensions
+{
+ ///
+ /// Return the Foundry tool definitions which corresponds with the provided .
+ ///
+ /// Instance of
+ internal static IEnumerable GetToolDefinitions(this GptComponentMetadata promptAgent)
+ {
+ Throw.IfNull(promptAgent);
+
+ return promptAgent.Tools.Select(tool =>
+ {
+ return tool switch
+ {
+ CodeInterpreterTool codeInterpreterTool => codeInterpreterTool.CreateCodeInterpreterToolDefinition(),
+ InvokeClientTaskAction functionTool => functionTool.CreateFunctionToolDefinition(),
+ FileSearchTool fileSearchTool => fileSearchTool.CreateFileSearchToolDefinition(),
+ WebSearchTool webSearchTool => webSearchTool.CreateBingGroundingToolDefinition(),
+ McpServerTool mcpServerTool => mcpServerTool.CreateMcpToolDefinition(),
+ // TODO: Add other tool types as custom tools
+ // AzureAISearch
+ // AzureFunction
+ // OpenApi
+ _ => throw new NotSupportedException($"Unable to create tool definition because of unsupported tool type: {tool.Kind}"),
+ };
+ }).ToList();
+ }
+
+ ///
+ /// Return the Foundry tool resources which corresponds with the provided .
+ ///
+ /// Instance of
+ internal static ToolResources GetToolResources(this GptComponentMetadata promptAgent)
+ {
+ Throw.IfNull(promptAgent);
+
+ var toolResources = new ToolResources();
+
+ var codeInterpreter = promptAgent.GetCodeInterpreterToolResource();
+ if (codeInterpreter is not null)
+ {
+ toolResources.CodeInterpreter = codeInterpreter;
+ }
+
+ var fileSearch = promptAgent.GetFileSearchToolResource();
+ if (fileSearch is not null)
+ {
+ toolResources.FileSearch = fileSearch;
+ }
+
+ // TODO Handle MCP tool resources
+
+ return toolResources;
+ }
+
+ ///
+ /// Returns the Foundry response tools which correspond with the provided .
+ ///
+ /// Instance of .
+ /// A collection of instances corresponding to the tools defined in the agent.
+ internal static IEnumerable GetResponseTools(this GptComponentMetadata promptAgent)
+ {
+ Throw.IfNull(promptAgent);
+
+ return promptAgent.Tools.Select(tool =>
+ {
+ return tool switch
+ {
+ CodeInterpreterTool codeInterpreterTool => codeInterpreterTool.CreateCodeInterpreterTool(),
+ InvokeClientTaskAction functionTool => functionTool.CreateFunctionTool(),
+ FileSearchTool fileSearchTool => fileSearchTool.CreateFileSearchTool(),
+ WebSearchTool webSearchTool => webSearchTool.CreateWebSearchTool(),
+ McpServerTool mcpServerTool => mcpServerTool.CreateMcpTool(),
+ // TODO: Add other tool types as custom tools
+ // AzureAISearch
+ // AzureFunction
+ // OpenApi
+ _ => throw new NotSupportedException($"Unable to create response tool because of unsupported tool type: {tool.Kind}"),
+ };
+ }).ToList();
+ }
+
+ #region private
+ private static CodeInterpreterToolResource? GetCodeInterpreterToolResource(this GptComponentMetadata promptAgent)
+ {
+ Throw.IfNull(promptAgent);
+
+ CodeInterpreterToolResource? resource = null;
+
+ var codeInterpreter = (CodeInterpreterTool?)promptAgent.GetFirstAgentTool();
+ if (codeInterpreter is not null)
+ {
+ var fileIds = codeInterpreter.GetFileIds();
+ var dataSources = codeInterpreter.GetDataSources();
+ if (fileIds is not null || dataSources is not null)
+ {
+ resource = new CodeInterpreterToolResource();
+ fileIds?.ForEach(id => resource.FileIds.Add(id));
+ dataSources?.ForEach(ds => resource.DataSources.Add(ds));
+ }
+ }
+
+ return resource;
+ }
+
+ private static FileSearchToolResource? GetFileSearchToolResource(this GptComponentMetadata promptAgent)
+ {
+ Throw.IfNull(promptAgent);
+
+ var fileSearch = (FileSearchTool?)promptAgent.GetFirstAgentTool();
+ if (fileSearch is not null)
+ {
+ var vectorStoreIds = fileSearch.GetVectorStoreIds();
+ var vectorStores = fileSearch.GetVectorStoreConfigurations();
+ if (vectorStoreIds is not null || vectorStores is not null)
+ {
+ return new FileSearchToolResource(vectorStoreIds, vectorStores);
+ }
+ }
+
+ return null;
+ }
+
+ private static TaskAction? GetFirstAgentTool(this GptComponentMetadata promptAgent)
+ {
+ return promptAgent.Tools.FirstOrDefault(tool => tool is T);
+ }
+ #endregion
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/RecordDataTypeExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/RecordDataTypeExtensions.cs
new file mode 100644
index 0000000000..24c172c888
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/RecordDataTypeExtensions.cs
@@ -0,0 +1,45 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System;
+using Microsoft.Extensions.AI;
+using Microsoft.Shared.Diagnostics;
+
+namespace Microsoft.Bot.ObjectModel;
+
+///
+/// Extension methods for .
+///
+internal static class RecordDataTypeExtensions
+{
+ ///
+ /// Creates a from a .
+ ///
+ /// Instance of
+#pragma warning disable IL2026 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code
+#pragma warning disable IL3050 // Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.
+ internal static BinaryData? AsBinaryData(this RecordDataType recordDataType)
+ {
+ Throw.IfNull(recordDataType);
+
+ if (recordDataType.Properties.Count == 0)
+ {
+ return null;
+ }
+
+ return BinaryData.FromObjectAsJson(
+ new
+ {
+ type = "json_schema",
+ schema =
+ new
+ {
+ type = "object",
+ properties = recordDataType.Properties.AsObjectDictionary(),
+ additionalProperties = false
+ }
+ }
+ );
+ }
+#pragma warning restore IL3050 // Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.
+#pragma warning restore IL2026 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/RecordDataValueExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/RecordDataValueExtensions.cs
new file mode 100644
index 0000000000..a2c4d490d6
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/RecordDataValueExtensions.cs
@@ -0,0 +1,39 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System.Collections.Generic;
+using System.Linq;
+using Azure.AI.Agents.Persistent;
+using Microsoft.Shared.Diagnostics;
+
+namespace Microsoft.Bot.ObjectModel;
+
+///
+/// Extension methods for .
+///
+internal static class RecordDataValueExtensions
+{
+ ///
+ /// Gets the data sources from the specified .
+ ///
+ internal static List? GetDataSources(this RecordDataValue value)
+ {
+ var dataSources = value.GetPropertyOrNull(InitializablePropertyPath.Create("options.data_sources"));
+ return dataSources?.Values.Select(dataSource => dataSource.CreateDataSource()).ToList();
+ }
+
+ ///
+ /// Creates a new instance of using the specified .
+ ///
+ internal static VectorStoreDataSource CreateDataSource(this RecordDataValue value)
+ {
+ Throw.IfNull(value);
+
+ string? assetIdentifier = value.GetPropertyOrNull(InitializablePropertyPath.Create("assetIdentifier"))?.Value;
+ Throw.IfNullOrEmpty(assetIdentifier);
+
+ string? assetType = value.GetPropertyOrNull(InitializablePropertyPath.Create("assetType"))?.Value;
+ Throw.IfNullOrEmpty(assetType);
+
+ return new VectorStoreDataSource(assetIdentifier, new VectorStoreDataSourceAssetType(assetType));
+ }
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/WebSearchToolExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/WebSearchToolExtensions.cs
new file mode 100644
index 0000000000..b0f65442af
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Extensions/WebSearchToolExtensions.cs
@@ -0,0 +1,38 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using Azure.AI.Agents.Persistent;
+using Microsoft.Shared.Diagnostics;
+
+namespace Microsoft.Bot.ObjectModel;
+
+///
+/// Extension methods for .
+///
+internal static class WebSearchToolExtensions
+{
+ ///
+ /// Creates a from a .
+ ///
+ /// Instance of
+ internal static BingGroundingToolDefinition CreateBingGroundingToolDefinition(this WebSearchTool tool)
+ {
+ Throw.IfNull(tool);
+
+ // TODO: Add support for BingGroundingSearchToolParameters.
+ var parameters = new BingGroundingSearchToolParameters([]);
+
+ return new BingGroundingToolDefinition(parameters);
+ }
+
+ ///
+ /// Creates a from a .
+ ///
+ /// Instance of
+ /// A new instance.
+ internal static OpenAI.Responses.WebSearchTool CreateWebSearchTool(this WebSearchTool tool)
+ {
+ Throw.IfNull(tool);
+
+ return new OpenAI.Responses.WebSearchTool();
+ }
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/FoundryAgentFactory.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/FoundryAgentFactory.cs
new file mode 100644
index 0000000000..5d18c7a25c
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/FoundryAgentFactory.cs
@@ -0,0 +1,111 @@
+// Copyright (c) Microsoft. All rights reserved.
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Azure.AI.Agents;
+using Azure.AI.Agents.Persistent;
+using Azure.Core;
+using Microsoft.Bot.ObjectModel;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Shared.Diagnostics;
+
+namespace Microsoft.Agents.AI;
+
+///
+/// Provides an which creates instances of using a .
+///
+public sealed class FoundryAgentFactory : AgentFactory
+{
+ private readonly AgentClient? _agentClient;
+ private readonly TokenCredential? _tokenCredential;
+
+ ///
+ /// Creates a new instance of the class with an associated .
+ ///
+ /// The instance to use for creating agents.
+ /// The instance to use for configuration.
+ public FoundryAgentFactory(AgentClient agentClient, IConfiguration? configuration = null) : base(configuration)
+ {
+ Throw.IfNull(agentClient);
+
+ this._agentClient = agentClient;
+ }
+
+ ///
+ /// Creates a new instance of the class with an associated .
+ ///
+ /// The to use for authenticating requests.
+ /// The instance to use for configuration.
+ public FoundryAgentFactory(TokenCredential tokenCredential, IConfiguration? configuration = null) : base(configuration)
+ {
+ Throw.IfNull(tokenCredential);
+
+ this._tokenCredential = tokenCredential;
+ }
+
+ ///
+ public override async Task TryCreateAsync(GptComponentMetadata promptAgent, CancellationToken cancellationToken = default)
+ {
+ Throw.IfNull(promptAgent);
+
+ var agentClient = this._agentClient ?? this.CreateAgentClient(promptAgent);
+
+ var modelId = promptAgent.Model?.ModelNameHint;
+ if (string.IsNullOrEmpty(modelId))
+ {
+ throw new InvalidOperationException("The model id must be specified in the agent definition model to create a foundry agent.");
+ }
+
+ var modelOptions = promptAgent.Model?.Options;
+
+ var promptAgentDefinition = new PromptAgentDefinition(model: modelId)
+ {
+ Instructions = promptAgent.Instructions?.ToTemplateString(),
+ Temperature = (float?)modelOptions?.Temperature?.LiteralValue,
+ TopP = (float?)modelOptions?.TopP?.LiteralValue,
+ };
+
+ foreach (var tool in promptAgent.GetResponseTools())
+ {
+ promptAgentDefinition.Tools.Add(tool);
+ }
+
+ var agentVersionCreationOptions = new AgentVersionCreationOptions(promptAgentDefinition);
+
+ var metadata = promptAgent.Metadata?.ToDictionary();
+ if (metadata is not null)
+ {
+ foreach (var kvp in metadata)
+ {
+ agentVersionCreationOptions.Metadata.Add(kvp.Key, kvp.Value);
+ }
+ }
+
+ var agentVersion = await agentClient.CreateAgentVersionAsync(agentName: promptAgent.Name, options: agentVersionCreationOptions, cancellationToken: cancellationToken).ConfigureAwait(false);
+
+ return agentClient.GetAIAgent(agentVersion, cancellationToken: cancellationToken);
+ }
+
+ private AgentClient CreateAgentClient(GptComponentMetadata promptAgent)
+ {
+ var externalModel = promptAgent.Model as CurrentModels;
+ var connection = externalModel?.Connection as RemoteConnection;
+ if (connection is not null)
+ {
+ var endpoint = connection.Endpoint?.Eval(this.Engine);
+ if (string.IsNullOrEmpty(endpoint))
+ {
+ throw new InvalidOperationException("The endpoint must be specified in the agent definition model connection to create an AgentClient.");
+ }
+
+ if (this._tokenCredential is null)
+ {
+ throw new InvalidOperationException("A TokenCredential must be registered in the service provider to create an AgentClient.");
+ }
+
+ return new AgentClient(new Uri(endpoint), this._tokenCredential);
+ }
+
+ throw new InvalidOperationException("An AgentClient must be registered in the service provider or a RemoteConnection must be specified in the agent definition model connection to create an AgentClient.");
+ }
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/FoundryPersistentAgentFactory.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/FoundryPersistentAgentFactory.cs
new file mode 100644
index 0000000000..ae9bc7756e
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/FoundryPersistentAgentFactory.cs
@@ -0,0 +1,94 @@
+// Copyright (c) Microsoft. All rights reserved.
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Azure.AI.Agents.Persistent;
+using Azure.Core;
+using Microsoft.Bot.ObjectModel;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Shared.Diagnostics;
+
+namespace Microsoft.Agents.AI;
+
+///
+/// Provides an which creates instances of using a .
+///
+public sealed class FoundryPersistentAgentFactory : AgentFactory
+{
+ private readonly PersistentAgentsClient? _agentClient;
+ private readonly TokenCredential? _tokenCredential;
+
+ ///
+ /// Creates a new instance of the class with an associated .
+ ///
+ /// The instance to use for creating agents.
+ /// The instance to use for configuration.
+ public FoundryPersistentAgentFactory(PersistentAgentsClient agentClient, IConfiguration? configuration = null) : base(configuration)
+ {
+ Throw.IfNull(agentClient);
+
+ this._agentClient = agentClient;
+ }
+
+ ///
+ /// Creates a new instance of the class with an associated .
+ ///
+ /// The to use for authenticating requests.
+ /// The instance to use for configuration.
+ public FoundryPersistentAgentFactory(TokenCredential tokenCredential, IConfiguration? configuration = null) : base(configuration)
+ {
+ Throw.IfNull(tokenCredential);
+
+ this._tokenCredential = tokenCredential;
+ }
+
+ ///
+ public override async Task TryCreateAsync(GptComponentMetadata promptAgent, CancellationToken cancellationToken = default)
+ {
+ Throw.IfNull(promptAgent);
+
+ var agentClient = this._agentClient ?? this.CreatePersistentAgentClient(promptAgent);
+
+ var modelId = promptAgent.Model?.ModelNameHint;
+ if (string.IsNullOrEmpty(modelId))
+ {
+ throw new InvalidOperationException("The model id must be specified in the agent definition model to create a foundry agent.");
+ }
+
+ //var outputSchema = promptAgent.OutputType; TODO: Fix converting RecordDataType to BinaryData
+ var modelOptions = promptAgent.Model?.Options;
+
+ return await agentClient.CreateAIAgentAsync(
+ model: modelId,
+ name: promptAgent.Name,
+ instructions: promptAgent.Instructions?.ToTemplateString(),
+ tools: promptAgent.GetToolDefinitions(),
+ toolResources: promptAgent.GetToolResources(),
+ temperature: (float?)modelOptions?.Temperature?.LiteralValue,
+ topP: (float?)modelOptions?.TopP?.LiteralValue,
+ //responseFormat: outputSchema.AsBinaryData(), TODO: Fix converting RecordDataType to BinaryData
+ metadata: promptAgent.Metadata?.ToDictionary(),
+ cancellationToken: cancellationToken).ConfigureAwait(false);
+ }
+
+ private PersistentAgentsClient CreatePersistentAgentClient(GptComponentMetadata promptAgent)
+ {
+ var externalModel = promptAgent.Model as CurrentModels;
+ var connection = externalModel?.Connection as RemoteConnection;
+ if (connection is not null)
+ {
+ var endpoint = connection.Endpoint?.Eval(this.Engine);
+ if (string.IsNullOrEmpty(endpoint))
+ {
+ throw new InvalidOperationException("The endpoint must be specified in the agent definition model connection to create an PersistentAgentsClient.");
+ }
+ if (this._tokenCredential is null)
+ {
+ throw new InvalidOperationException("A TokenCredential must be registered in the service provider to create an PersistentAgentsClient.");
+ }
+ return new PersistentAgentsClient(endpoint, this._tokenCredential);
+ }
+
+ throw new InvalidOperationException("A PersistentAgentsClient must be registered in the service provider or a FoundryConnection must be specified in the agent definition model connection to create an PersistentAgentsClient.");
+ }
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/JsonSchemaFunctionParameters.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/JsonSchemaFunctionParameters.cs
new file mode 100644
index 0000000000..c406825d5b
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/JsonSchemaFunctionParameters.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System.Collections.Generic;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Microsoft.Extensions.AI;
+
+namespace Microsoft.Agents.AI.Declarative.AzureAI;
+
+///
+/// A class to describe the parameters of an in a JSON Schema friendly way.
+///
+internal sealed class JsonSchemaFunctionParameters
+{
+ ///
+ /// The type of schema which is always "object" when describing function parameters.
+ ///
+ [JsonPropertyName("type")]
+ public string Type => "object";
+
+ ///
+ /// The list of required properties.
+ ///
+ [JsonPropertyName("required")]
+ public List Required { get; set; } = [];
+
+ ///
+ /// A dictionary of properties, keyed by name => JSON Schema.
+ ///
+ [JsonPropertyName("properties")]
+ public Dictionary Properties { get; set; } = [];
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Microsoft.Agents.AI.Declarative.AzureAI.Persistent.csproj b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Microsoft.Agents.AI.Declarative.AzureAI.Persistent.csproj
new file mode 100644
index 0000000000..05705a5675
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/Microsoft.Agents.AI.Declarative.AzureAI.Persistent.csproj
@@ -0,0 +1,52 @@
+
+
+
+ $(ProjectsTargetFrameworks)
+ $(ProjectsDebugTargetFrameworks)
+ preview
+ $(NoWarn);MEAI001;OPENAI001
+
+
+
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+ Microsoft Agent Framework Declarative AzureAI
+ Provides Microsoft Agent Framework support for declarative AzureAI agents.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/OpenAIAgentFactory.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/OpenAIAgentFactory.cs
new file mode 100644
index 0000000000..a598292e75
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/OpenAIAgentFactory.cs
@@ -0,0 +1,183 @@
+// Copyright (c) Microsoft. All rights reserved.
+using System;
+using System.ClientModel;
+using Azure.AI.OpenAI;
+using Azure.Core;
+using Microsoft.Bot.ObjectModel;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using Microsoft.Shared.Diagnostics;
+using OpenAI;
+using OpenAI.Assistants;
+using OpenAI.Chat;
+using OpenAI.Responses;
+
+namespace Microsoft.Agents.AI;
+
+///
+/// Provides an abstract base class.
+///
+public abstract class OpenAIAgentFactory : AgentFactory
+{
+ ///
+ /// Creates a new instance of the class.
+ ///
+ protected OpenAIAgentFactory(IConfiguration? configuration, ILoggerFactory? loggerFactory) : base(configuration)
+ {
+ this.LoggerFactory = loggerFactory;
+ }
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ protected OpenAIAgentFactory(Uri endpoint, TokenCredential tokenCredential, IConfiguration? configuration, ILoggerFactory? loggerFactory) : base(configuration)
+ {
+ Throw.IfNull(endpoint);
+ Throw.IfNull(tokenCredential);
+
+ this._endpoint = endpoint;
+ this._tokenCredential = tokenCredential;
+ this.LoggerFactory = loggerFactory;
+ }
+
+ ///
+ /// Gets the instance used for creating loggers.
+ ///
+ protected ILoggerFactory? LoggerFactory { get; }
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ protected ChatClient? CreateChatClient(GptComponentMetadata promptAgent)
+ {
+ var model = promptAgent.Model as CurrentModels;
+ var provider = model?.Provider?.Value ?? ModelProvider.OpenAI;
+ if (provider == ModelProvider.OpenAI)
+ {
+ return this.CreateOpenAIChatClient(promptAgent);
+ }
+ else if (provider == ModelProvider.AzureOpenAI)
+ {
+ Throw.IfNull(this._endpoint, "A endpoint must be specified to create an Azure OpenAI client");
+ Throw.IfNull(this._tokenCredential, "A token credential must be specified to create an Azure OpenAI client");
+ return CreateAzureOpenAIChatClient(promptAgent, this._endpoint, this._tokenCredential);
+ }
+
+ return null;
+ }
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ protected AssistantClient? CreateAssistantClient(GptComponentMetadata promptAgent)
+ {
+ var model = promptAgent.Model as CurrentModels;
+ var provider = model?.Provider?.Value ?? ModelProvider.OpenAI;
+ if (provider == ModelProvider.OpenAI)
+ {
+ return this.CreateOpenAIAssistantClient(promptAgent);
+ }
+ else if (provider == ModelProvider.AzureOpenAI)
+ {
+ Throw.IfNull(this._endpoint, "The connection endpoint must be specified to create an Azure OpenAI client.");
+ Throw.IfNull(this._tokenCredential, "A token credential must be specified to create an Azure OpenAI client");
+ return CreateAzureOpenAIAssistantClient(promptAgent, this._endpoint, this._tokenCredential);
+ }
+
+ return null;
+ }
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ protected OpenAIResponseClient? CreateResponseClient(GptComponentMetadata promptAgent)
+ {
+ var model = promptAgent.Model as CurrentModels;
+ var provider = model?.Provider?.Value ?? ModelProvider.OpenAI;
+ if (provider == ModelProvider.OpenAI)
+ {
+ return this.CreateOpenAIResponseClient(promptAgent);
+ }
+ else if (provider == ModelProvider.AzureOpenAI)
+ {
+ Throw.IfNull(this._endpoint, "The connection endpoint must be specified to create an Azure OpenAI client.");
+ Throw.IfNull(this._tokenCredential, "A token credential must be specified to create an Azure OpenAI client");
+ return CreateAzureOpenAIResponseClient(promptAgent, this._endpoint, this._tokenCredential);
+ }
+
+ return null;
+ }
+
+ #region private
+ private readonly Uri? _endpoint;
+ private readonly TokenCredential? _tokenCredential;
+
+ private ChatClient CreateOpenAIChatClient(GptComponentMetadata promptAgent)
+ {
+ var modelId = promptAgent.Model?.ModelNameHint;
+ Throw.IfNullOrEmpty(modelId, "The model id must be specified in the agent definition to create an OpenAI agent.");
+
+ return this.CreateOpenAIClient(promptAgent).GetChatClient(modelId);
+ }
+
+ private static ChatClient CreateAzureOpenAIChatClient(GptComponentMetadata promptAgent, Uri endpoint, TokenCredential tokenCredential)
+ {
+ var deploymentName = promptAgent.Model?.ModelNameHint;
+ Throw.IfNullOrEmpty(deploymentName, "The deployment name (using model.id) must be specified in the agent definition to create an Azure OpenAI agent.");
+
+ return new AzureOpenAIClient(endpoint, tokenCredential).GetChatClient(deploymentName);
+ }
+
+ private AssistantClient CreateOpenAIAssistantClient(GptComponentMetadata promptAgent)
+ {
+ var modelId = promptAgent.Model?.ModelNameHint;
+ Throw.IfNullOrEmpty(modelId, "The model id must be specified in the agent definition to create an OpenAI agent.");
+
+ return this.CreateOpenAIClient(promptAgent).GetAssistantClient();
+ }
+
+ private static AssistantClient CreateAzureOpenAIAssistantClient(GptComponentMetadata promptAgent, Uri endpoint, TokenCredential tokenCredential)
+ {
+ var deploymentName = promptAgent.Model?.ModelNameHint;
+ Throw.IfNullOrEmpty(deploymentName, "The deployment name (using model.id) must be specified in the agent definition to create an Azure OpenAI agent.");
+
+ return new AzureOpenAIClient(endpoint, tokenCredential).GetAssistantClient();
+ }
+
+ private OpenAIResponseClient CreateOpenAIResponseClient(GptComponentMetadata promptAgent)
+ {
+ var modelId = promptAgent.Model?.ModelNameHint;
+ Throw.IfNullOrEmpty(modelId, "The model id must be specified in the agent definition to create an OpenAI agent.");
+
+ return this.CreateOpenAIClient(promptAgent).GetOpenAIResponseClient(modelId);
+ }
+
+ private static OpenAIResponseClient CreateAzureOpenAIResponseClient(GptComponentMetadata promptAgent, Uri endpoint, TokenCredential tokenCredential)
+ {
+ var deploymentName = promptAgent.Model?.ModelNameHint;
+ Throw.IfNullOrEmpty(deploymentName, "The deployment name (using model.id) must be specified in the agent definition to create an Azure OpenAI agent.");
+
+ return new AzureOpenAIClient(endpoint, tokenCredential).GetOpenAIResponseClient(deploymentName);
+ }
+
+ private OpenAIClient CreateOpenAIClient(GptComponentMetadata promptAgent)
+ {
+ var model = promptAgent.Model as CurrentModels;
+
+ var keyConnection = model?.Connection as ApiKeyConnection;
+ Throw.IfNull(keyConnection, "A key connection must be specified when create an OpenAI client");
+
+ var apiKey = keyConnection.Key!.Eval(this.Engine);
+ Throw.IfNullOrEmpty(apiKey, "The connection key must be specified in the agent definition to create an OpenAI client.");
+
+ var clientOptions = new OpenAIClientOptions();
+ var endpoint = keyConnection.Endpoint?.Eval(this.Engine);
+ if (!string.IsNullOrEmpty(endpoint))
+ {
+ clientOptions.Endpoint = new Uri(endpoint);
+ }
+
+ return new OpenAIClient(new ApiKeyCredential(apiKey), clientOptions);
+ }
+ #endregion
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/OpenAIAssistantAgentFactory.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/OpenAIAssistantAgentFactory.cs
new file mode 100644
index 0000000000..621736e6dd
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/OpenAIAssistantAgentFactory.cs
@@ -0,0 +1,92 @@
+// Copyright (c) Microsoft. All rights reserved.
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Azure.AI.Agents.Persistent;
+using Azure.Core;
+using Microsoft.Bot.ObjectModel;
+using Microsoft.Extensions.AI;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using Microsoft.Shared.Diagnostics;
+using OpenAI;
+using OpenAI.Assistants;
+
+namespace Microsoft.Agents.AI;
+
+///
+/// Provides an which creates instances of using a .
+///
+public sealed class OpenAIAssistantAgentFactory : OpenAIAgentFactory
+{
+ ///
+ /// Creates a new instance of the class.
+ ///
+ public OpenAIAssistantAgentFactory(IList? functions = null, IConfiguration? configuration = null, ILoggerFactory? loggerFactory = null) : base(configuration, loggerFactory)
+ {
+ this._functions = functions;
+ }
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ public OpenAIAssistantAgentFactory(AssistantClient assistantClient, IList? functions = null, IConfiguration? configuration = null, ILoggerFactory? loggerFactory = null) : base(configuration, loggerFactory)
+ {
+ Throw.IfNull(assistantClient);
+
+ this._assistantClient = assistantClient;
+ this._functions = functions;
+ }
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ public OpenAIAssistantAgentFactory(Uri endpoint, TokenCredential tokenCredential, IList? functions = null, IConfiguration? configuration = null, ILoggerFactory? loggerFactory = null) : base(endpoint, tokenCredential, configuration, loggerFactory)
+ {
+ this._functions = functions;
+ }
+
+ ///
+ public override async Task TryCreateAsync(GptComponentMetadata promptAgent, CancellationToken cancellationToken = default)
+ {
+ Throw.IfNull(promptAgent);
+
+ var model = promptAgent.Model as CurrentModels;
+ var apiType = model?.ApiType;
+ if (apiType?.IsUnknown() == false || apiType?.UnknownValue?.Equals(API_TYPE_ASSISTANTS, StringComparison.OrdinalIgnoreCase) == false)
+ {
+ return null;
+ }
+
+ var options = new ChatClientAgentOptions()
+ {
+ Name = promptAgent.Name,
+ Description = promptAgent.Description,
+ Instructions = promptAgent.Instructions?.ToTemplateString(),
+ ChatOptions = promptAgent.GetChatOptions(this._functions),
+ };
+
+ AssistantClient? assistantClient = this._assistantClient ?? this.CreateAssistantClient(promptAgent);
+ if (assistantClient is not null)
+ {
+ var modelId = promptAgent.Model?.ModelNameHint;
+ Throw.IfNullOrEmpty(modelId, "The model id must be specified in the agent definition to create an OpenAI Assistant.");
+ Throw.IfNullOrEmpty(promptAgent.Instructions?.ToTemplateString(), "The instructions must be specified in the agent definition to create an OpenAI Assistant.");
+
+ return await assistantClient.CreateAIAgentAsync(
+ modelId,
+ options
+ ).ConfigureAwait(false);
+ }
+
+ return null;
+ }
+
+ #region private
+ private readonly AssistantClient? _assistantClient;
+ private readonly IList? _functions;
+
+ private const string API_TYPE_ASSISTANTS = "ASSISTANTS";
+ #endregion
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/OpenAIChatAgentFactory.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/OpenAIChatAgentFactory.cs
new file mode 100644
index 0000000000..f27c8ca6a5
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/OpenAIChatAgentFactory.cs
@@ -0,0 +1,85 @@
+// Copyright (c) Microsoft. All rights reserved.
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Azure.AI.Agents.Persistent;
+using Azure.Core;
+using Microsoft.Bot.ObjectModel;
+using Microsoft.Extensions.AI;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using Microsoft.Shared.Diagnostics;
+using OpenAI.Chat;
+
+namespace Microsoft.Agents.AI;
+
+///
+/// Provides an which creates instances of using a .
+///
+public sealed class OpenAIChatAgentFactory : OpenAIAgentFactory
+{
+ ///
+ /// Creates a new instance of the class.
+ ///
+ public OpenAIChatAgentFactory(IList? functions = null, IConfiguration? configuration = null, ILoggerFactory? loggerFactory = null) : base(configuration, loggerFactory)
+ {
+ this._functions = functions;
+ }
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ public OpenAIChatAgentFactory(ChatClient chatClient, IList? functions = null, IConfiguration? configuration = null, ILoggerFactory? loggerFactory = null) : base(configuration, loggerFactory)
+ {
+ Throw.IfNull(chatClient);
+
+ this._chatClient = chatClient;
+ this._functions = functions;
+ }
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ public OpenAIChatAgentFactory(Uri endpoint, TokenCredential tokenCredential, IList? functions = null, IConfiguration? configuration = null, ILoggerFactory? loggerFactory = null) : base(endpoint, tokenCredential, configuration, loggerFactory)
+ {
+ this._functions = functions;
+ }
+
+ ///
+ public override async Task TryCreateAsync(GptComponentMetadata promptAgent, CancellationToken cancellationToken = default)
+ {
+ Throw.IfNull(promptAgent);
+
+ var model = promptAgent.Model as CurrentModels;
+ var apiType = model?.ApiType;
+ if (apiType?.IsUnknown() == true || apiType?.Value != ModelApiType.Chat)
+ {
+ return null;
+ }
+
+ var options = new ChatClientAgentOptions()
+ {
+ Name = promptAgent.Name,
+ Description = promptAgent.Description,
+ Instructions = promptAgent.Instructions?.ToTemplateString(),
+ ChatOptions = promptAgent.GetChatOptions(this._functions),
+ };
+
+ ChatClient? chatClient = this._chatClient ?? this.CreateChatClient(promptAgent);
+ if (chatClient is not null)
+ {
+ return new ChatClientAgent(
+ chatClient.AsIChatClient(),
+ options,
+ this.LoggerFactory);
+ }
+
+ return null;
+ }
+
+ #region private
+ private readonly ChatClient? _chatClient;
+ private readonly IList? _functions;
+ #endregion
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/OpenAIResponseAgentFactory.cs b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/OpenAIResponseAgentFactory.cs
new file mode 100644
index 0000000000..6da009135d
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Declarative.AzureAI.Persistent/OpenAIResponseAgentFactory.cs
@@ -0,0 +1,85 @@
+// Copyright (c) Microsoft. All rights reserved.
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Azure.AI.Agents.Persistent;
+using Azure.Core;
+using Microsoft.Bot.ObjectModel;
+using Microsoft.Extensions.AI;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using Microsoft.Shared.Diagnostics;
+using OpenAI.Responses;
+
+namespace Microsoft.Agents.AI;
+
+///
+/// Provides an which creates instances of using a .
+///
+public sealed class OpenAIResponseAgentFactory : OpenAIAgentFactory
+{
+ ///
+ /// Creates a new instance of the class.
+ ///
+ public OpenAIResponseAgentFactory(IList? functions = null, IConfiguration? configuration = null, ILoggerFactory? loggerFactory = null) : base(configuration, loggerFactory)
+ {
+ this._functions = functions;
+ }
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ public OpenAIResponseAgentFactory(OpenAIResponseClient responseClient, IList? functions = null, IConfiguration? configuration = null, ILoggerFactory? loggerFactory = null) : base(configuration, loggerFactory)
+ {
+ Throw.IfNull(responseClient);
+
+ this._responseClient = responseClient;
+ this._functions = functions;
+ }
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ public OpenAIResponseAgentFactory(Uri endpoint, TokenCredential tokenCredential, IList? functions = null, IConfiguration? configuration = null, ILoggerFactory? loggerFactory = null) : base(endpoint, tokenCredential, configuration, loggerFactory)
+ {
+ this._functions = functions;
+ }
+
+ ///
+ public override async Task TryCreateAsync(GptComponentMetadata promptAgent, CancellationToken cancellationToken = default)
+ {
+ Throw.IfNull(promptAgent);
+
+ var model = promptAgent.Model as CurrentModels;
+ var apiType = model?.ApiType;
+ if (apiType?.IsUnknown() == true || apiType?.Value != ModelApiType.Responses)
+ {
+ return null;
+ }
+
+ var options = new ChatClientAgentOptions()
+ {
+ Name = promptAgent.Name,
+ Description = promptAgent.Description,
+ Instructions = promptAgent.Instructions?.ToTemplateString(),
+ ChatOptions = promptAgent.GetChatOptions(this._functions),
+ };
+
+ var responseClient = this._responseClient ?? this.CreateResponseClient(promptAgent);
+ if (responseClient is not null)
+ {
+ return new ChatClientAgent(
+ responseClient.AsIChatClient(),
+ options,
+ this.LoggerFactory);
+ }
+
+ return null;
+ }
+
+ #region private
+ private readonly OpenAIResponseClient? _responseClient;
+ private readonly IList? _functions;
+ #endregion
+}