diff --git a/.github/workflows/e2e-nodejs-langchain.yml b/.github/workflows/e2e-nodejs-langchain.yml index 14a904d7..fd88cccc 100644 --- a/.github/workflows/e2e-nodejs-langchain.yml +++ b/.github/workflows/e2e-nodejs-langchain.yml @@ -147,8 +147,9 @@ jobs: --verbosity normal ` --logger "console;verbosity=detailed" ` --logger "trx;LogFileName=test-results-nodejs-langchain.trx" ` - --filter "FullyQualifiedName~BasicConversation|FullyQualifiedName~Notification" + --filter "Category=HTTP" env: + AGENT_URL: http://localhost:${{ env.AGENT_PORT }} TEST_RESULTS_DIR: ${{ runner.temp }}/TestConversations - name: Emit Test Conversations diff --git a/.github/workflows/e2e-nodejs-openai.yml b/.github/workflows/e2e-nodejs-openai.yml index 2f7555cd..366a0f03 100644 --- a/.github/workflows/e2e-nodejs-openai.yml +++ b/.github/workflows/e2e-nodejs-openai.yml @@ -147,8 +147,9 @@ jobs: --verbosity normal ` --logger "console;verbosity=detailed" ` --logger "trx;LogFileName=test-results-nodejs-openai.trx" ` - --filter "FullyQualifiedName~BasicConversation|FullyQualifiedName~Notification" + --filter "Category=HTTP" env: + AGENT_URL: http://localhost:${{ env.AGENT_PORT }} TEST_RESULTS_DIR: ${{ runner.temp }}/TestConversations - name: Emit Test Conversations diff --git a/.github/workflows/e2e-orchestrator.yml b/.github/workflows/e2e-orchestrator.yml index 546acff3..ec6eeccd 100644 --- a/.github/workflows/e2e-orchestrator.yml +++ b/.github/workflows/e2e-orchestrator.yml @@ -122,6 +122,8 @@ jobs: echo "| Node.js LangChain | $NODEJS_LANGCHAIN_ICON | ${{ needs.nodejs-langchain.result }} |" >> $GITHUB_STEP_SUMMARY echo "| .NET Semantic Kernel | $DOTNET_SK_ICON | ${{ needs.dotnet-sk.result }} |" >> $GITHUB_STEP_SUMMARY echo "| .NET Agent Framework | $DOTNET_AF_ICON | ${{ needs.dotnet-af.result }} |" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "> 📦 **SDK Versions**: Click on each sample workflow above to view detailed SDK version information in the step summary." >> $GITHUB_STEP_SUMMARY - name: Post PR Comment if: github.event_name == 'pull_request' @@ -153,6 +155,8 @@ jobs: `| .NET Semantic Kernel | ${dotnetSkIcon} | ${{ needs.dotnet-sk.result }} |`, `| .NET Agent Framework | ${dotnetAfIcon} | ${{ needs.dotnet-af.result }} |`, '', + `> 📦 **SDK Versions**: View the [workflow summary](${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}) for detailed SDK version information.`, + '', `[View full test details](${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID})` ].join('\n'); diff --git a/.github/workflows/update-readme-versions.yml b/.github/workflows/update-readme-versions.yml new file mode 100644 index 00000000..c3a078ee --- /dev/null +++ b/.github/workflows/update-readme-versions.yml @@ -0,0 +1,50 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +name: Update SDK Versions in README + +on: + push: + branches: [main] + paths: + - 'python/**/pyproject.toml' + - 'nodejs/**/package.json' + - 'dotnet/**/*.csproj' + workflow_dispatch: + +permissions: + contents: write + +jobs: + update-versions: + name: Update SDK Versions + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Update README with SDK Versions + shell: pwsh + run: | + ./scripts/Update-ReadmeVersions.ps1 + + - name: Check for Changes + id: check + run: | + if git diff --quiet README.md; then + echo "changed=false" >> $GITHUB_OUTPUT + else + echo "changed=true" >> $GITHUB_OUTPUT + fi + + - name: Commit and Push Changes + if: steps.check.outputs.changed == 'true' + run: | + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git add README.md + git commit -m "docs: Update SDK versions in README [skip ci]" + git push diff --git a/README.md b/README.md index 72eaca34..26005e68 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,63 @@ This repository contains sample agents and prompts for building with the Microso |--------|--------| | Python OpenAI | [![Python OpenAI](https://img.shields.io/github/actions/workflow/status/microsoft/Agent365-Samples/e2e-python-openai.yml?branch=main&label=E2E)](https://github.com/microsoft/Agent365-Samples/actions/workflows/e2e-python-openai.yml) | | Node.js OpenAI | [![Node.js OpenAI](https://img.shields.io/github/actions/workflow/status/microsoft/Agent365-Samples/e2e-nodejs-openai.yml?branch=main&label=E2E)](https://github.com/microsoft/Agent365-Samples/actions/workflows/e2e-nodejs-openai.yml) | +| Node.js LangChain | [![Node.js LangChain](https://img.shields.io/github/actions/workflow/status/microsoft/Agent365-Samples/e2e-nodejs-langchain.yml?branch=main&label=E2E)](https://github.com/microsoft/Agent365-Samples/actions/workflows/e2e-nodejs-langchain.yml) | | .NET Semantic Kernel | [![.NET SK](https://img.shields.io/github/actions/workflow/status/microsoft/Agent365-Samples/e2e-dotnet-semantic-kernel.yml?branch=main&label=E2E)](https://github.com/microsoft/Agent365-Samples/actions/workflows/e2e-dotnet-semantic-kernel.yml) | | .NET Agent Framework | [![.NET AF](https://img.shields.io/github/actions/workflow/status/microsoft/Agent365-Samples/e2e-dotnet-agent-framework.yml?branch=main&label=E2E)](https://github.com/microsoft/Agent365-Samples/actions/workflows/e2e-dotnet-agent-framework.yml) | +## SDK Versions + +The following SDK package versions are used across the samples in this repository. This section is automatically updated when package versions change. + + + +### Microsoft Agents SDK Packages + +| Package | Version | +|---------|---------| +| `@microsoft/agents-activity` | `1.2.2` | +| `@microsoft/agents-hosting` | `1.2.2` | +| `Microsoft.Agents.AI` | `1.0.0-preview.251113.1` | +| `Microsoft.Agents.Authentication.Msal` | `1.3.*-*` | +| `Microsoft.Agents.Hosting.AspNetCore` | `1.3.*-*` | + +### Microsoft Agent 365 SDK Packages + +#### Python +| Package | Version | +|---------|---------| +| `microsoft_agents_a365_notifications` | `0.1.0` | +| `microsoft_agents_a365_observability_core` | `0.1.0` | +| `microsoft_agents_a365_observability_extensions_openai` | `0.1.0` | +| `microsoft_agents_a365_runtime` | `0.1.0` | +| `microsoft_agents_a365_tooling` | `0.1.0` | +| `microsoft_agents_a365_tooling_extensions_openai` | `0.1.0` | +| `microsoft-agents-a365-observability-core` | `0.1.0` | +| `microsoft-agents-a365-observability-hosting` | `0.2.0` | +| `microsoft-agents-a365-tooling` | `0.1.0` | + +#### Node.js +| Package | Version | +|---------|---------| +| `@microsoft/agents-a365-notifications` | `0.1.0-preview.30` | +| `@microsoft/agents-a365-observability` | `0.1.0-preview.30` | +| `@microsoft/agents-a365-observability-extensions-openai` | `0.1.0-preview.30` | +| `@microsoft/agents-a365-observability-hosting` | `0.1.0-preview.64` | +| `@microsoft/agents-a365-runtime` | `0.1.0-preview.30` | +| `@microsoft/agents-a365-tooling` | `0.1.0-preview.30` | +| `@microsoft/agents-a365-tooling-extensions-langchain` | `0.1.0-preview.30` | +| `@microsoft/agents-a365-tooling-extensions-openai` | `0.1.0-preview.30` | + +#### .NET +| Package | Version | +|---------|---------| +| `Microsoft.Agents.A365.Notifications` | `*-beta.*` | +| `Microsoft.Agents.A365.Observability.Extensions.AgentFramework` | `*-beta.*` | +| `Microsoft.Agents.A365.Tooling.Extensions.AgentFramework` | `*-beta.*` | +| `Microsoft.Agents.A365.Tooling.Extensions.SemanticKernel` | `*-beta.*` | + + + > #### Note: > Use the information in this README to contribute to this open-source project. To learn about using this SDK in your projects, refer to the [Microsoft Agent 365 Developer documentation](https://learn.microsoft.com/en-us/microsoft-agent-365/developer/). diff --git a/scripts/Update-ReadmeVersions.ps1 b/scripts/Update-ReadmeVersions.ps1 new file mode 100644 index 00000000..b9d359c9 --- /dev/null +++ b/scripts/Update-ReadmeVersions.ps1 @@ -0,0 +1,309 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +<# +.SYNOPSIS + Updates the README.md with current SDK versions from all samples. + +.DESCRIPTION + This script extracts SDK version information from package.json, pyproject.toml, + and .csproj files across all sample projects and updates a marked section in + the README.md file. + +.PARAMETER ReadmePath + Path to the README.md file (default: README.md in repo root) + +.PARAMETER DryRun + If specified, outputs the new content without modifying the file + +.EXAMPLE + .\Update-ReadmeVersions.ps1 + .\Update-ReadmeVersions.ps1 -DryRun +#> + +param( + [string]$ReadmePath = "README.md", + [switch]$DryRun +) + +$ErrorActionPreference = 'Stop' + +# Define samples to check +$samples = @( + @{ Name = "Python OpenAI"; Path = "python/openai/sample-agent"; Type = "python" } + @{ Name = "Python Claude"; Path = "python/claude/sample-agent"; Type = "python" } + @{ Name = "Node.js OpenAI"; Path = "nodejs/openai/sample-agent"; Type = "nodejs" } + @{ Name = "Node.js LangChain"; Path = "nodejs/langchain/sample-agent"; Type = "nodejs" } + @{ Name = ".NET Semantic Kernel"; Path = "dotnet/semantic-kernel/sample-agent"; Type = "dotnet" } + @{ Name = ".NET Agent Framework"; Path = "dotnet/agent-framework/sample-agent"; Type = "dotnet" } +) + +function Get-PythonVersions { + param([string]$Path) + + $versions = @{} + $pyprojectPath = Join-Path $Path "pyproject.toml" + + if (Test-Path $pyprojectPath) { + $content = Get-Content $pyprojectPath -Raw + + # Extract microsoft-agents packages + $pattern = '(microsoft[-_]agents[-_][a-zA-Z0-9_-]+)\s*[>=<~^]*\s*"?([0-9]+\.[0-9]+\.[0-9]+[^"]*)"?' + $matches = [regex]::Matches($content, $pattern) + + foreach ($match in $matches) { + $pkgName = $match.Groups[1].Value + $version = $match.Groups[2].Value -replace '[",\s]', '' + $versions[$pkgName] = $version + } + + # Try alternate pattern for dependencies section + $depsPattern = '"(microsoft[-_]agents[-_][a-zA-Z0-9_-]+)[>=<~^]*([0-9]+\.[0-9]+\.[0-9]+[^"]*)"' + $depsMatches = [regex]::Matches($content, $depsPattern) + + foreach ($match in $depsMatches) { + $pkgName = $match.Groups[1].Value + $version = $match.Groups[2].Value -replace '[",\s]', '' + if (-not $versions.ContainsKey($pkgName)) { + $versions[$pkgName] = $version + } + } + } + + return $versions +} + +function Get-NodejsVersions { + param([string]$Path) + + $versions = @{} + $packageJsonPath = Join-Path $Path "package.json" + + if (Test-Path $packageJsonPath) { + $packageJson = Get-Content $packageJsonPath -Raw | ConvertFrom-Json + + $allDeps = @{} + if ($packageJson.dependencies) { + $packageJson.dependencies.PSObject.Properties | ForEach-Object { + $allDeps[$_.Name] = $_.Value + } + } + if ($packageJson.devDependencies) { + $packageJson.devDependencies.PSObject.Properties | ForEach-Object { + if (-not $allDeps.ContainsKey($_.Name)) { + $allDeps[$_.Name] = $_.Value + } + } + } + + foreach ($dep in $allDeps.GetEnumerator()) { + if ($dep.Key -like '@microsoft/agents*') { + # Clean version string (remove ^, ~, etc.) + $version = $dep.Value -replace '[\^~>=<]', '' + $versions[$dep.Key] = $version + } + } + } + + return $versions +} + +function Get-DotnetVersions { + param([string]$Path) + + $versions = @{} + $csprojFiles = Get-ChildItem -Path $Path -Filter "*.csproj" -ErrorAction SilentlyContinue + + foreach ($csproj in $csprojFiles) { + [xml]$xml = Get-Content $csproj.FullName + + $packageRefs = $xml.SelectNodes("//PackageReference") + foreach ($pkg in $packageRefs) { + $pkgName = $pkg.GetAttribute("Include") + $pkgVersion = $pkg.GetAttribute("Version") + + if ($pkgName -like 'Microsoft.Agents*') { + $versions[$pkgName] = $pkgVersion + } + } + } + + return $versions +} + +# Collect all versions +$allVersions = @{} + +foreach ($sample in $samples) { + Write-Host "Checking $($sample.Name)..." -ForegroundColor Cyan + + if (-not (Test-Path $sample.Path)) { + Write-Host " Path not found: $($sample.Path)" -ForegroundColor Yellow + continue + } + + $versions = switch ($sample.Type) { + 'python' { Get-PythonVersions -Path $sample.Path } + 'nodejs' { Get-NodejsVersions -Path $sample.Path } + 'dotnet' { Get-DotnetVersions -Path $sample.Path } + } + + if ($versions.Count -gt 0) { + $allVersions[$sample.Name] = @{ + Type = $sample.Type + Versions = $versions + } + + foreach ($v in $versions.GetEnumerator()) { + Write-Host " $($v.Key): $($v.Value)" -ForegroundColor Gray + } + } +} + +# Group packages by category and language +$agentsSdkVersions = @{} +$a365Python = @{} +$a365Nodejs = @{} +$a365Dotnet = @{} + +foreach ($sample in $allVersions.GetEnumerator()) { + $runtime = $sample.Value.Type + + foreach ($pkg in $sample.Value.Versions.GetEnumerator()) { + $pkgName = $pkg.Key + $version = $pkg.Value + + # Determine if it's Agent 365 SDK + $isA365 = $pkgName -match 'a365|A365' + + if ($isA365) { + # Group A365 packages by language + switch ($runtime) { + 'python' { + if (-not $a365Python.ContainsKey($pkgName)) { + $a365Python[$pkgName] = $version + } + } + 'nodejs' { + if (-not $a365Nodejs.ContainsKey($pkgName)) { + $a365Nodejs[$pkgName] = $version + } + } + 'dotnet' { + if (-not $a365Dotnet.ContainsKey($pkgName)) { + $a365Dotnet[$pkgName] = $version + } + } + } + } + else { + # Microsoft Agents SDK (base SDK) + if (-not $agentsSdkVersions.ContainsKey($pkgName)) { + $agentsSdkVersions[$pkgName] = @{ Version = $version; Runtime = $runtime } + } + } + } +} + +# Generate markdown sections +$markdown = @" + +### Microsoft Agents SDK Packages + +| Package | Version | +|---------|---------| +"@ + +# Sort and add Agents SDK packages +$sortedAgentsSdk = $agentsSdkVersions.GetEnumerator() | Sort-Object { $_.Key } +foreach ($pkg in $sortedAgentsSdk) { + $markdown += "`n| ``$($pkg.Key)`` | ``$($pkg.Value.Version)`` |" +} + +$markdown += @" + + +### Microsoft Agent 365 SDK Packages + +#### Python +| Package | Version | +|---------|---------| +"@ + +# Sort and add Python A365 packages +$sortedA365Python = $a365Python.GetEnumerator() | Sort-Object { $_.Key } +foreach ($pkg in $sortedA365Python) { + $markdown += "`n| ``$($pkg.Key)`` | ``$($pkg.Value)`` |" +} + +$markdown += @" + + +#### Node.js +| Package | Version | +|---------|---------| +"@ + +# Sort and add Node.js A365 packages +$sortedA365Nodejs = $a365Nodejs.GetEnumerator() | Sort-Object { $_.Key } +foreach ($pkg in $sortedA365Nodejs) { + $markdown += "`n| ``$($pkg.Key)`` | ``$($pkg.Value)`` |" +} + +$markdown += @" + + +#### .NET +| Package | Version | +|---------|---------| +"@ + +# Sort and add .NET A365 packages +$sortedA365Dotnet = $a365Dotnet.GetEnumerator() | Sort-Object { $_.Key } +foreach ($pkg in $sortedA365Dotnet) { + $markdown += "`n| ``$($pkg.Key)`` | ``$($pkg.Value)`` |" +} + +$markdown += "`n" + +Write-Host "" +Write-Host "Generated SDK Versions Section:" -ForegroundColor Green +Write-Host $markdown + +# Read README and update the section +if (Test-Path $ReadmePath) { + $readmeContent = Get-Content $ReadmePath -Raw + + $startMarker = '' + $endMarker = '' + + if ($readmeContent -match [regex]::Escape($startMarker) -and $readmeContent -match [regex]::Escape($endMarker)) { + # Replace content between markers + $pattern = "(?s)$([regex]::Escape($startMarker)).*?$([regex]::Escape($endMarker))" + $replacement = "$startMarker`n$markdown`n$endMarker" + $newContent = $readmeContent -replace $pattern, $replacement + + if ($DryRun) { + Write-Host "" + Write-Host "=== DRY RUN - Would update README with: ===" -ForegroundColor Yellow + Write-Host $replacement + } + else { + $newContent | Set-Content $ReadmePath -NoNewline + Write-Host "" + Write-Host "README.md updated successfully!" -ForegroundColor Green + } + } + else { + Write-Host "" + Write-Host "ERROR: Could not find SDK version markers in README.md" -ForegroundColor Red + Write-Host "Please add the following markers to README.md:" -ForegroundColor Yellow + Write-Host " $startMarker" + Write-Host " $endMarker" + exit 1 + } +} +else { + Write-Host "ERROR: README.md not found at $ReadmePath" -ForegroundColor Red + exit 1 +}