name: generate-code-cs
description: "Generate the code from typespec for C#. Parameter: C# SDK repository root location ."
Basic information
The C# repository root location is provided by src, which contains all the source codes. The src/Generated folder contains generated code; the folder Custom contains the code customizations. Please review the references/customization.md for more information on code customization. The typespec repository, used for code generation is located at https://github.com/Azure/azure-rest-api-specs.git. Please use the branch provided by user, if it is not provided use feature/foundry-release.
Updating the code
- Take the latest commit hash from this branch and set it in
commitfield in three files:/sdk/ai/Azure.AI.Projects.Agents/tsp-location.yaml, /sdk/ai/Azure.AI.Projects/tsp-location.yaml and /sdk/ai/Azure.AI.Extensions.OpenAI/tsp-location.yaml. - After the files are modified, remove the directory
\eng\common\tsp-client\node_modules if present. - Generate code for the first package. This command may fail with EPERM error.
cd <cs_root>/sdk/ai/Azure.AI.Projects.Agents
dotnet build /t:GenerateCode
cd <cs_root>/sdk/ai/Azure.AI.Projects.Agents
dotnet build /t:GenerateCode
If the EPERM error has happened, run the next code and make sure it passes:
cd ../Azure.AI.Extensions.OpenAI
npm exec --prefix <cs_root>\eng\common/tsp-client --no -- tsp-client update --no-prompt --output-dir<cs_root>\sdk\ai\Azure.AI.Projects.Agents\src/../
cd ../Azure.AI.Extensions.OpenAI
npm exec --prefix <cs_root>\eng\common/tsp-client --no -- tsp-client update --no-prompt --output-dir<cs_root>\sdk\ai\Azure.AI.Projects.Agents\src/../
- Generate code using the script below.
cd ../Azure.AI.Extensions.OpenAI
npm exec --prefix <cs_root>\eng\common/tsp-client --no -- tsp-client update --no-prompt --output-dir<cs_root>\sdk\ai\Azure.AI.Extensions.OpenAI\src/../
cd ../Azure.AI.Projects
npm exec --prefix <cs_root>\eng\common/tsp-client --no -- tsp-client update --no-prompt --output-dir<cs_root>\sdk\ai\Azure.AI.Projects\src/../
cd <cs_root>/sdk/ai/Azure.AI.Projects.Agents
dotnet build /t:GenerateCode
cd ../Azure.AI.Extensions.OpenAI
npm exec --prefix <cs_root>\eng\common/tsp-client --no -- tsp-client update --no-prompt --output-dir<cs_root>\sdk\ai\Azure.AI.Extensions.OpenAI\src/../
cd ../Azure.AI.Projects
npm exec --prefix <cs_root>\eng\common/tsp-client --no -- tsp-client update --no-prompt --output-dir<cs_root>\sdk\ai\Azure.AI.Projects\src/../
Post processing
- For each package, check that it compiles without errors (replace
by Azure.AI.Projects,Azure.AI.Extensions.OpenAIorAzure.AI.Projects.Agents):
cd <cs_root>/sdk/ai/<package>
dotnet build /t:GenerateCode
cd <cs_root>/sdk/ai/<package>
dotnet build /t:GenerateCode
- If there are any errors, customize the code so that it compiles.
Azure.AI.Projects.Agentspackage after code generation may get new tool classes, inherited fromTool. The same classes will be generated inAzure.AI.Extensions.OpenAIprojects. If that is the case, add into the file<cs_root>/sdk/ai/Azure.AI.Extensions.OpenAI/src/Custom.CodeGenStubs.Tools.csentries to rename the generated tool classes and their parameters so that they haveResponsesprefix. For example, if the classFabricIQPreviewToolwas added, add the next entries:
[CodeGenType("FabricIQPreviewTool")] public partial class ResponsesFabricIQPreviewTool { }
[CodeGenType("FabricIQPreviewToolParameters")] public partial class ResponsesFabricIQPreviewToolParameters { }
Order the entries in the file alphabetically; do not remove the entries already present.
4. Make sure that all projects build without errors by running dotnet build inside the project folder.
5. Update the API-view by running the script (replace Azure.AI.Projects, Azure.AI.Extensions.OpenAI or Azure.AI.Projects.Agents):
cd <cs_root>
eng\scripts\Export-API.ps1 ai\<package>
cd <cs_root>
eng\scripts\Export-API.ps1 ai\<package>
Sample generation
- Provide the summary of changes.
- If there were significant changes in the code, please provide the samples as explained below.
A C# sample consists of two parts: the source code in the folder
Asynchronous Sample
#if SNIPPET
var projectEndpoint = System.Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT");
var modelDeploymentName = System.Environment.GetEnvironmentVariable("FOUNDRY_MODEL_NAME");
#else
var projectEndpoint = TestEnvironment.FOUNDRY_PROJECT_ENDPOINT;
var modelDeploymentName = TestEnvironment.FOUNDRY_MODEL_NAME;
#endif
AIProjectClient projectClient = new(endpoint: new Uri(projectEndpoint), tokenProvider: new DefaultAzureCredential());
DeclarativeAgentDefinition agentDefinition = new(model: modelDeploymentName)
{
Instructions = "You are a prompt agent."
};
ProjectsAgentVersion agentVersion1 = await projectClient.AgentAdministrationClient.CreateAgentVersionAsync(
agentName: "myAgent1",
options: new(agentDefinition));
Synchronous Sample
#if SNIPPET
var projectEndpoint = System.Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT");
var modelDeploymentName = System.Environment.GetEnvironmentVariable("FOUNDRY_MODEL_NAME");
#else
var projectEndpoint = TestEnvironment.FOUNDRY_PROJECT_ENDPOINT;
var modelDeploymentName = TestEnvironment.FOUNDRY_MODEL_NAME;
#endif
AIProjectClient projectClient = new(endpoint: new Uri(projectEndpoint), tokenProvider: new DefaultAzureCredential());
DeclarativeAgentDefinition agentDefinition = new(model: modelDeploymentName)
{
Instructions = "You are a prompt agent."
};
ProjectsAgentVersion agentVersion1 = projectClient.AgentAdministrationClient.CreateAgentVersion(
agentName: "myAgent1",
options: new(agentDefinition));
The code needs to be logically split into blocks, whose usage should be explained in .md file. Each block is marked in the source code as follows:
#region Snippet:Sample_FunctionFoo_MySampl_Async
public async Task Foo()
{
await Task.Delay(1000);
Console.WriteLine("Hello world!")
}
#endregion
These blocks will be rendered in the .md file code block based on the region name (it will be done by automation):
public async Task Foo()
{
await Task.Delay(1000);
Console.WriteLine("Hello world!")
}
If the code block has sync and async counterpart, please create code block for each of them. Provide the short explanation for each code block. Please make sure that there is one-to-one consistency between C# regions and .md file code blocks.
To make sure that it is so, call the script (replace Azure.AI.Projects, Azure.AI.Extensions.OpenAI or Azure.AI.Projects.Agents):
cd <cs_root>
eng\scripts\Update-Snippets.ps1 ai\<package>
cd <cs_root>
eng\scripts\Update-Snippets.ps1 ai\<package>
Updating changelog
Get the differences by running
cd <cs_root>
git diff
cd <cs_root>
git diff
Figure out, which classes are public facing and based on that populate the latest section of Release History. Append the found changes to the ### Features Added, ### Breaking Changes, ### Bugs Fixed or ### Other Changes section. It is also possible to add ### Sample Updates section or append data to it. Do not modify the header, denoting version and release date, for example ## 2.1.0-beta.2 (Unreleased).
[Optional] Create a pull request
Prompt user if the PR is required. If it is not, go to the section "Package generation".
Get the user's github alias by running
gh api user --jq .login.Stash the changes and make sure to use the latest main branch.
git stash git checkout main git pull origin maingit stash git checkout main git pull origin mainCreate a branch and apply stashed changes; replace <user_alias> by user github alias from step 2. Replace <commit> by the commit hash from the typespec.
git checkout -b <user_alias>/code_generation_<commit> git stash applygit checkout -b <user_alias>/code_generation_<commit> git stash applyAdd all new files by running
git addand modified files bygit add -u.Commit changes with the short summary of added features as a comment
git commit -m "new features"Create a pull request by calling
gh pr create --title "<title>" --body "<changelog> --assignee @me"; replace <title> and <changelog> by short PR title and the changes from the changelog, we have generated in "Updating changelog" section.
[Optional] Create an alpha package release
- Prompt user if alpha package release is required. If it is not, go to the section "Package generation".
- Check the next prerequisites:
- azure-cli must be installed and present in the path (please check by running
az az pipelines show --id 7296 --organization https://dev.azure.com/azure-sdk/ --project internal). - User needs to have a permission to access (check by running
curl https://dev.azure.com/azure-sdk/internal/_artifacts/feed/azure-sdk-for-net-pr)
- azure-cli must be installed and present in the path (please check by running
- Run the pipeline
az pipelines run --id 7296 --organization https://dev.azure.com/azure-sdk/ --project internal --branch nirovins/fix_pipelines --variables "SetDevVersion=true" --open; replace the <branch> by the branch from "Create a pull request" section.
Package generation
After everything is ready, please generate the packages for all <package> i.e. (replace <package> by Azure.AI.Projects, Azure.AI.Extensions.OpenAI or Azure.AI.Projects.Agents).
cd <cs_root>/sdk/ai/<package>
dotnet pack
cd <cs_root>/sdk/ai/<package>
dotnet pack
Provide the location of each package in the summary and provide the simple instruction on installation.
If the alpha package was released to Azure (in section "Create an alpha package release"), please add to the instructions command to add a new NuGet repository to the project. dotnet nuget add source https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-net/nuget/v3/index.json