Skip to content

Commit c081932

Browse files
authored
Merge branch 'main' into gagb-docs
2 parents a84f9de + 51d4a10 commit c081932

File tree

154 files changed

+5257
-3447
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

154 files changed

+5257
-3447
lines changed

.github/workflows/codeql.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,26 @@ jobs:
6161
- name: Checkout repository
6262
uses: actions/checkout@v4
6363

64+
- name: Set up Python
65+
uses: actions/setup-python@v5
66+
with:
67+
python-version: 3.11
68+
- name: Install jupyter and ipykernel
69+
run: |
70+
python -m pip install --upgrade pip
71+
python -m pip install jupyter
72+
python -m pip install ipykernel
73+
- name: list available kernels
74+
run: |
75+
python -m jupyter kernelspec list
76+
- uses: astral-sh/setup-uv@v3
77+
with:
78+
enable-cache: true
79+
- run: uv sync --locked --all-extras
80+
working-directory: ./python
81+
- name: Prepare python venv
82+
run: |
83+
source ${{ github.workspace }}/python/.venv/bin/activate
6484
# Initializes the CodeQL tools for scanning.
6585
- name: Initialize CodeQL
6686
uses: github/codeql-action/init@v3

.github/workflows/docs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ jobs:
4141
{ ref: "v0.4.0.dev6", dest-dir: "0.4.0.dev6" },
4242
{ ref: "v0.4.0.dev7", dest-dir: "0.4.0.dev7" },
4343
{ ref: "v0.4.0.dev8", dest-dir: "0.4.0.dev8" },
44+
{ ref: "v0.4.0.dev9", dest-dir: "0.4.0.dev9" },
4445
]
4546
steps:
4647
- name: Checkout

.github/workflows/dotnet-build.yml

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,18 @@ jobs:
7676
- name: list available kernels
7777
run: |
7878
python -m jupyter kernelspec list
79-
- name: Setup .NET
79+
- uses: astral-sh/setup-uv@v3
80+
with:
81+
enable-cache: true
82+
- run: uv sync --locked --all-extras
83+
working-directory: ./python
84+
- name: Prepare python venv
85+
run: |
86+
source ${{ github.workspace }}/python/.venv/bin/activate
87+
- name: Setup .NET 8.0
8088
uses: actions/setup-dotnet@v4
8189
with:
8290
dotnet-version: '8.0.x'
83-
- name: Install .NET Aspire workload
84-
run: dotnet workload install aspire
8591
- name: Restore dependencies
8692
run: |
8793
# dotnet nuget add source --name dotnet-tool https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json --configfile NuGet.config
@@ -96,7 +102,57 @@ jobs:
96102
echo "Build AutoGen"
97103
dotnet build --no-restore --configuration Release -bl /p:SignAssembly=true
98104
- name: Unit Test
99-
run: dotnet test --no-build -bl --configuration Release
105+
run: dotnet test --no-build -bl --configuration Release --filter type=!integration
106+
107+
integration-test:
108+
strategy:
109+
fail-fast: true
110+
matrix:
111+
os: [ ubuntu-latest]
112+
version: [ net8.0 ]
113+
needs: build
114+
defaults:
115+
run:
116+
working-directory: dotnet
117+
runs-on: ${{ matrix.os }}
118+
steps:
119+
- uses: actions/checkout@v4
120+
with:
121+
lfs: true
122+
- uses: astral-sh/setup-uv@v3
123+
with:
124+
enable-cache: true
125+
- uses: actions/setup-python@v5
126+
with:
127+
python-version: "3.11"
128+
- run: uv sync --locked --all-extras
129+
working-directory: ./python
130+
- name: Prepare python venv
131+
run: |
132+
source ${{ github.workspace }}/python/.venv/bin/activate
133+
- name: Setup .NET 9.0
134+
uses: actions/setup-dotnet@v4
135+
with:
136+
dotnet-version: '9.0.x'
137+
- name: Install Temp Global.JSON
138+
run: |
139+
echo "{\"sdk\": {\"version\": \"9.0.101\"}}" > global.json
140+
- name: Install .NET Aspire workload
141+
run: dotnet workload install aspire
142+
- name: Install dev certs
143+
run: dotnet --version && dotnet dev-certs https --trust
144+
- name: Restore dependencies
145+
run: |
146+
dotnet restore -bl
147+
- name: Build
148+
run: |
149+
echo "Build AutoGen"
150+
dotnet build --no-restore --configuration Release -bl /p:SignAssembly=true
151+
- name: Integration Test
152+
run: dotnet --version && dotnet test --no-build -bl --configuration Release --filter type=integration
153+
- name: Restore the global.json
154+
run: rm global.json && git checkout -- global.json
155+
100156
aot-test: # this make sure the AutoGen.Core is aot compatible
101157
strategy:
102158
fail-fast: false # ensures the entire test matrix is run, even if one permutation fails
@@ -147,9 +203,17 @@ jobs:
147203
- name: list available kernels
148204
run: |
149205
python -m jupyter kernelspec list
150-
- name: Setup .NET
206+
- uses: astral-sh/setup-uv@v3
207+
with:
208+
enable-cache: true
209+
- uses: actions/setup-python@v5
210+
with:
211+
python-version: "3.11"
212+
213+
- name: Setup .NET 8.0
151214
uses: actions/setup-dotnet@v4
152215
with:
216+
dotnet-version: '8.0.x'
153217
global-json-file: dotnet/global.json
154218
- name: Restore dependencies
155219
run: |
@@ -159,7 +223,7 @@ jobs:
159223
echo "Build AutoGen"
160224
dotnet build --no-restore --configuration Release -bl /p:SignAssembly=true
161225
- name: OpenAI Test
162-
run: dotnet test --no-build -bl --configuration Release
226+
run: dotnet test --no-build -bl --configuration Release --filter type!=integration
163227
env:
164228
AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
165229
AZURE_OPENAI_ENDPOINT: ${{ secrets.AZURE_OPENAI_ENDPOINT }}

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ We will update verion numbers according to the following rules:
4949

5050
1. Create a PR that updates the version numbers across the codebase ([example](https://github.com/microsoft/autogen/pull/4359))
5151
2. The docs CI will fail for the PR, but this is expected and will be resolved in the next step
52-
2. After merging the PR, create and push a tag that corresponds to the new verion. For example, for `0.4.0.dev8`:
53-
- `git tag 0.4.0.dev8 && git push origin 0.4.0.dev8`
52+
2. After merging the PR, create and push a tag that corresponds to the new verion. For example, for `0.4.0.dev9`:
53+
- `git tag 0.4.0.dev9 && git push origin 0.4.0.dev9`
5454
3. Restart the docs CI by finding the failed [job corresponding to the `push` event](https://github.com/microsoft/autogen/actions/workflows/docs.yml) and restarting all jobs
5555
4. Run [this](https://github.com/microsoft/autogen/actions/workflows/single-python-package.yml) workflow for each of the packages that need to be released and get an approval for the release for it to run
5656

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
[![Twitter](https://img.shields.io/twitter/url/https/twitter.com/cloudposse.svg?style=social&label=Follow%20%40pyautogen)](https://twitter.com/pyautogen) [![LinkedIn](https://img.shields.io/badge/LinkedIn-Company?style=flat&logo=linkedin&logoColor=white)](https://www.linkedin.com/company/105812540)
77
[![GitHub Discussions](https://img.shields.io/badge/Discussions-Q%26A-green?logo=github)](https://github.com/microsoft/autogen/discussions) [![0.2 Docs](https://img.shields.io/badge/Docs-0.2-blue)](https://microsoft.github.io/autogen/0.2/) [![0.4 Docs](https://img.shields.io/badge/Docs-0.4-blue)](https://microsoft.github.io/autogen/dev/)
8-
[![PyPi autogen-core](https://img.shields.io/badge/PyPi-autogen--core-blue?logo=pypi)](https://pypi.org/project/autogen-core/0.4.0.dev8/) [![PyPi autogen-agentchat](https://img.shields.io/badge/PyPi-autogen--agentchat-blue?logo=pypi)](https://pypi.org/project/autogen-agentchat/0.4.0.dev8/) [![PyPi autogen-ext](https://img.shields.io/badge/PyPi-autogen--ext-blue?logo=pypi)](https://pypi.org/project/autogen-ext/0.4.0.dev8/)
8+
[![PyPi autogen-core](https://img.shields.io/badge/PyPi-autogen--core-blue?logo=pypi)](https://pypi.org/project/autogen-core/0.4.0.dev9/) [![PyPi autogen-agentchat](https://img.shields.io/badge/PyPi-autogen--agentchat-blue?logo=pypi)](https://pypi.org/project/autogen-agentchat/0.4.0.dev9/) [![PyPi autogen-ext](https://img.shields.io/badge/PyPi-autogen--ext-blue?logo=pypi)](https://pypi.org/project/autogen-ext/0.4.0.dev9/)
99

1010
</div>
1111

@@ -105,7 +105,7 @@ We look forward to your contributions!
105105
First install the packages:
106106

107107
```bash
108-
pip install 'autogen-agentchat==0.4.0.dev8' 'autogen-ext[openai]==0.4.0.dev8'
108+
pip install 'autogen-agentchat==0.4.0.dev9' 'autogen-ext[openai]==0.4.0.dev9'
109109
```
110110

111111
The following code uses OpenAI's GPT-4o model and you need to provide your

docs/switcher.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,12 @@
5151
{
5252
"name": "0.4.0.dev8",
5353
"version": "0.4.0.dev8",
54-
"url": "/autogen/0.4.0.dev8/",
54+
"url": "/autogen/0.4.0.dev8/"
55+
},
56+
{
57+
"name": "0.4.0.dev9",
58+
"version": "0.4.0.dev9",
59+
"url": "/autogen/0.4.0.dev9/",
5560
"preferred": true
5661
}
5762
]

dotnet/AutoGen.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AutoGen.Extension
132132
EndProject
133133
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AutoGen.Agents.Tests", "test\Microsoft.AutoGen.Agents.Tests\Microsoft.AutoGen.Agents.Tests.csproj", "{394FDAF8-74F9-4977-94A5-3371737EB774}"
134134
EndProject
135+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Integration.Tests", "test\Microsoft.AutoGen.Integration.Tests\Microsoft.AutoGen.Integration.Tests.csproj", "{D04C6153-8EAF-4E54-9852-52CEC1BE8D31}"
136+
EndProject
135137
Global
136138
GlobalSection(SolutionConfigurationPlatforms) = preSolution
137139
Debug|Any CPU = Debug|Any CPU
@@ -342,6 +344,10 @@ Global
342344
{394FDAF8-74F9-4977-94A5-3371737EB774}.Debug|Any CPU.Build.0 = Debug|Any CPU
343345
{394FDAF8-74F9-4977-94A5-3371737EB774}.Release|Any CPU.ActiveCfg = Release|Any CPU
344346
{394FDAF8-74F9-4977-94A5-3371737EB774}.Release|Any CPU.Build.0 = Release|Any CPU
347+
{D04C6153-8EAF-4E54-9852-52CEC1BE8D31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
348+
{D04C6153-8EAF-4E54-9852-52CEC1BE8D31}.Debug|Any CPU.Build.0 = Debug|Any CPU
349+
{D04C6153-8EAF-4E54-9852-52CEC1BE8D31}.Release|Any CPU.ActiveCfg = Release|Any CPU
350+
{D04C6153-8EAF-4E54-9852-52CEC1BE8D31}.Release|Any CPU.Build.0 = Release|Any CPU
345351
EndGlobalSection
346352
GlobalSection(SolutionProperties) = preSolution
347353
HideSolutionNode = FALSE
@@ -402,6 +408,7 @@ Global
402408
{64EF61E7-00A6-4E5E-9808-62E10993A0E5} = {7EB336C2-7C0A-4BC8-80C6-A3173AB8DC45}
403409
{65059914-5527-4A00-9308-9FAF23D5E85A} = {18BF8DD7-0585-48BF-8F97-AD333080CE06}
404410
{394FDAF8-74F9-4977-94A5-3371737EB774} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64}
411+
{D04C6153-8EAF-4E54-9852-52CEC1BE8D31} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64}
405412
EndGlobalSection
406413
GlobalSection(ExtensibilityGlobals) = postSolution
407414
SolutionGuid = {93384647-528D-46C8-922C-8DB36A382F0B}

dotnet/Directory.Packages.props

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<ItemGroup>
1616
<PackageVersion Include="Aspire.Hosting" Version="9.0.0" />
1717
<PackageVersion Include="Aspire.Hosting.Python" Version="9.0.0" />
18+
<PackageVersion Include="Aspire.Hosting.Testing" Version="9.0.0" />
1819
<PackageVersion Include="AspNetCore.Authentication.ApiKey" Version="8.0.1" />
1920
<PackageVersion Include="Aspire.Azure.AI.OpenAI" Version="8.0.1-preview.8.24267.1" />
2021
<PackageVersion Include="Aspire.Hosting.AppHost" Version="9.0.0" />
@@ -31,12 +32,17 @@
3132
<PackageVersion Include="Azure.ResourceManager.ContainerInstance" Version="1.2.1" />
3233
<PackageVersion Include="Azure.Storage.Files.Shares" Version="12.21.0" />
3334
<PackageVersion Include="CloudNative.CloudEvents.SystemTextJson" Version="2.7.1" />
35+
<PackageVersion Include="GitHubActionsTestLogger" Version="2.4.1">
36+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
37+
<PrivateAssets>all</PrivateAssets>
38+
</PackageVersion>
3439
<PackageVersion Include="Grpc.AspNetCore" Version="2.67.0" />
3540
<PackageVersion Include="Grpc.Core" Version="2.46.6" />
3641
<PackageVersion Include="Grpc.Net.ClientFactory" Version="2.67.0" />
3742
<PackageVersion Include="Grpc.Tools" Version="2.67.0" />
3843
<PackageVersion Include="Grpc.Net.Client" Version="2.65.0" />
3944
<PackageVersion Include="Google.Protobuf" Version="3.28.3" />
45+
<PackageVersion Include="MartinCostello.Logging.XUnit" Version="0.4.0" />
4046
<PackageVersion Include="Microsoft.AspNetCore.App" Version="8.0.4" />
4147
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="8.0.8" />
4248
<PackageVersion Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.22.0" />
@@ -54,6 +60,7 @@
5460
<PackageVersion Include="Microsoft.Extensions.Configuration.UserSecrets" Version="$(MicrosoftExtensionConfiguration)" />
5561
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionDependencyInjection)" />
5662
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="$(MicrosoftExtensionDependencyInjection)" />
63+
<PackageVersion Include="Microsoft.Extensions.Diagnostics.Testing" Version="9.0.0" />
5764
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
5865
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="9.0.0" />
5966
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionLogging)" />
@@ -118,5 +125,6 @@
118125
<PackageVersion Include="Moq" Version="4.20.72" />
119126
<PackageVersion Include="Microsoft.PowerShell.SDK" Version="7.4.5" />
120127
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="8.0.11" />
128+
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
121129
</ItemGroup>
122-
</Project>
130+
</Project>
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// HelloAppHostIntegrationTests.cs
3+
4+
using System.Text.Json;
5+
using Xunit.Abstractions;
6+
7+
namespace Microsoft.AutoGen.Integration.Tests;
8+
9+
public class HelloAppHostIntegrationTests(ITestOutputHelper testOutput)
10+
{
11+
[Theory, Trait("type", "integration")]
12+
[MemberData(nameof(AppHostAssemblies))]
13+
public async Task AppHostRunsCleanly(string appHostPath)
14+
{
15+
var appHost = await DistributedApplicationTestFactory.CreateAsync(appHostPath, testOutput);
16+
await using var app = await appHost.BuildAsync().WaitAsync(TimeSpan.FromSeconds(15));
17+
18+
await app.StartAsync().WaitAsync(TimeSpan.FromSeconds(120));
19+
await app.WaitForResourcesAsync().WaitAsync(TimeSpan.FromSeconds(120));
20+
21+
app.EnsureNoErrorsLogged();
22+
await app.StopAsync().WaitAsync(TimeSpan.FromSeconds(15));
23+
}
24+
25+
[Theory, Trait("type", "integration")]
26+
[MemberData(nameof(TestEndpoints))]
27+
public async Task AppHostLogsHelloAgentE2E(TestEndpoints testEndpoints)
28+
{
29+
var appHostName = testEndpoints.AppHost!;
30+
var appHostPath = $"{appHostName}.dll";
31+
var appHost = await DistributedApplicationTestFactory.CreateAsync(appHostPath, testOutput);
32+
await using var app = await appHost.BuildAsync().WaitAsync(TimeSpan.FromSeconds(15));
33+
34+
await app.StartAsync().WaitAsync(TimeSpan.FromSeconds(120));
35+
await app.WaitForResourcesAsync().WaitAsync(TimeSpan.FromSeconds(120));
36+
if (testEndpoints.WaitForResources?.Count > 0)
37+
{
38+
// Wait until each resource transitions to the required state
39+
var timeout = TimeSpan.FromMinutes(5);
40+
foreach (var (ResourceName, TargetState) in testEndpoints.WaitForResources)
41+
{
42+
await app.WaitForResource(ResourceName, TargetState).WaitAsync(timeout);
43+
}
44+
}
45+
//sleep 5 seconds to make sure the app is running
46+
await Task.Delay(5000);
47+
app.EnsureNoErrorsLogged();
48+
app.EnsureLogContains("HelloAgents said Goodbye");
49+
app.EnsureLogContains("Wild Hello from Python!");
50+
51+
await app.StopAsync().WaitAsync(TimeSpan.FromSeconds(15));
52+
}
53+
public static TheoryData<string> AppHostAssemblies()
54+
{
55+
var appHostAssemblies = GetSamplesAppHostAssemblyPaths();
56+
var theoryData = new TheoryData<string, bool>();
57+
return new(appHostAssemblies.Select(p => Path.GetRelativePath(AppContext.BaseDirectory, p)));
58+
}
59+
60+
public static TheoryData<TestEndpoints> TestEndpoints() =>
61+
new([
62+
new TestEndpoints("Hello.AppHost", new() {
63+
{ "backend", ["/"] }
64+
}),
65+
]);
66+
67+
private static IEnumerable<string> GetSamplesAppHostAssemblyPaths()
68+
{
69+
// All the AppHost projects are referenced by this project so we can find them by looking for all their assemblies in the base directory
70+
return Directory.GetFiles(AppContext.BaseDirectory, "*.AppHost.dll")
71+
.Where(fileName => !fileName.EndsWith("Aspire.Hosting.AppHost.dll", StringComparison.OrdinalIgnoreCase));
72+
}
73+
}
74+
75+
public class TestEndpoints : IXunitSerializable
76+
{
77+
// Required for deserialization
78+
public TestEndpoints() { }
79+
80+
public TestEndpoints(string appHost, Dictionary<string, List<string>> resourceEndpoints)
81+
{
82+
AppHost = appHost;
83+
ResourceEndpoints = resourceEndpoints;
84+
}
85+
86+
public string? AppHost { get; set; }
87+
88+
public List<ResourceWait>? WaitForResources { get; set; }
89+
90+
public Dictionary<string, List<string>>? ResourceEndpoints { get; set; }
91+
92+
public void Deserialize(IXunitSerializationInfo info)
93+
{
94+
AppHost = info.GetValue<string>(nameof(AppHost));
95+
WaitForResources = JsonSerializer.Deserialize<List<ResourceWait>>(info.GetValue<string>(nameof(WaitForResources)));
96+
ResourceEndpoints = JsonSerializer.Deserialize<Dictionary<string, List<string>>>(info.GetValue<string>(nameof(ResourceEndpoints)));
97+
}
98+
99+
public void Serialize(IXunitSerializationInfo info)
100+
{
101+
info.AddValue(nameof(AppHost), AppHost);
102+
info.AddValue(nameof(WaitForResources), JsonSerializer.Serialize(WaitForResources));
103+
info.AddValue(nameof(ResourceEndpoints), JsonSerializer.Serialize(ResourceEndpoints));
104+
}
105+
106+
public override string? ToString() => $"{AppHost} ({ResourceEndpoints?.Count ?? 0} resources)";
107+
108+
public class ResourceWait(string resourceName, string targetState)
109+
{
110+
public string ResourceName { get; } = resourceName;
111+
112+
public string TargetState { get; } = targetState;
113+
114+
public void Deconstruct(out string resourceName, out string targetState)
115+
{
116+
resourceName = ResourceName;
117+
targetState = TargetState;
118+
}
119+
}
120+
}

0 commit comments

Comments
 (0)