Skip to content

Commit

Permalink
Merge branch 'main' into aamirj/sync_nested_chats
Browse files Browse the repository at this point in the history
  • Loading branch information
heyitsaamir authored Aug 8, 2024
2 parents 499c332 + 5732b3e commit 9c57c51
Show file tree
Hide file tree
Showing 17 changed files with 596 additions and 197 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/dotnet-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,24 @@ jobs:
fail-fast: false
matrix:
os: [ ubuntu-latest, macos-latest, windows-latest ]
python-version: ["3.11"]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
lfs: true
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install jupyter and ipykernel
run: |
python -m pip install --upgrade pip
python -m pip install jupyter
python -m pip install ipykernel
- name: list available kernels
run: |
python -m jupyter kernelspec list
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
Expand Down Expand Up @@ -114,6 +127,18 @@ jobs:
- uses: actions/checkout@v4
with:
lfs: true
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Install jupyter and ipykernel
run: |
python -m pip install --upgrade pip
python -m pip install jupyter
python -m pip install ipykernel
- name: list available kernels
run: |
python -m jupyter kernelspec list
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/dotnet-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ jobs:
- uses: actions/checkout@v4
with:
lfs: true
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Install jupyter and ipykernel
run: |
python -m pip install --upgrade pip
python -m pip install jupyter
python -m pip install ipykernel
- name: list available kernels
run: |
python -m jupyter kernelspec list
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
Expand Down
1 change: 1 addition & 0 deletions dotnet/eng/Version.props
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
<MicrosoftASPNETCoreVersion>8.0.4</MicrosoftASPNETCoreVersion>
<GoogleCloudAPIPlatformVersion>3.0.0</GoogleCloudAPIPlatformVersion>
<JsonSchemaVersion>4.3.0.2</JsonSchemaVersion>
<PowershellSDKVersion>7.4.4</PowershellSDKVersion>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,45 @@
#region code_snippet_0_1
using AutoGen.Core;
using AutoGen.DotnetInteractive;
using AutoGen.DotnetInteractive.Extension;
#endregion code_snippet_0_1

namespace AutoGen.BasicSample.CodeSnippet;
public class RunCodeSnippetCodeSnippet
{
public async Task CodeSnippet1()
{
IAgent agent = default;
IAgent agent = new DefaultReplyAgent("agent", "Hello World");

#region code_snippet_1_1
var workingDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
Directory.CreateDirectory(workingDirectory);
var interactiveService = new InteractiveService(installingDirectory: workingDirectory);
await interactiveService.StartAsync(workingDirectory: workingDirectory);
var kernel = DotnetInteractiveKernelBuilder
.CreateDefaultBuilder() // add C# and F# kernels
.Build();
#endregion code_snippet_1_1

#region code_snippet_1_2
// register dotnet code block execution hook to an arbitrary agent
var dotnetCodeAgent = agent.RegisterDotnetCodeBlockExectionHook(interactiveService: interactiveService);
// register middleware to execute code block
var dotnetCodeAgent = agent
.RegisterMiddleware(async (msgs, option, innerAgent, ct) =>
{
var lastMessage = msgs.LastOrDefault();
if (lastMessage == null || lastMessage.GetContent() is null)
{
return await innerAgent.GenerateReplyAsync(msgs, option, ct);
}

if (lastMessage.ExtractCodeBlock("```csharp", "```") is string codeSnippet)
{
// execute code snippet
var result = await kernel.RunSubmitCodeCommandAsync(codeSnippet, "csharp");
return new TextMessage(Role.Assistant, result, from: agent.Name);
}
else
{
// no code block found, invoke next agent
return await innerAgent.GenerateReplyAsync(msgs, option, ct);
}
});

var codeSnippet = @"
```csharp
Expand All @@ -44,5 +64,17 @@ public async Task CodeSnippet1()
```
";
#endregion code_snippet_1_3

#region code_snippet_1_4
var pythonKernel = DotnetInteractiveKernelBuilder
.CreateDefaultBuilder()
.AddPythonKernel(venv: "python3")
.Build();

var pythonCode = """
print('Hello from Python!')
""";
var result = await pythonKernel.RunSubmitCodeCommandAsync(pythonCode, "python3");
#endregion code_snippet_1_4
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using AutoGen.BasicSample;
using AutoGen.Core;
using AutoGen.DotnetInteractive;
using AutoGen.DotnetInteractive.Extension;
using AutoGen.OpenAI;
using FluentAssertions;

Expand All @@ -14,32 +15,13 @@ public static async Task RunAsync()
{
var instance = new Example04_Dynamic_GroupChat_Coding_Task();

// setup dotnet interactive
var workDir = Path.Combine(Path.GetTempPath(), "InteractiveService");
if (!Directory.Exists(workDir))
{
Directory.CreateDirectory(workDir);
}

using var service = new InteractiveService(workDir);
var dotnetInteractiveFunctions = new DotnetInteractiveFunction(service);

var result = Path.Combine(workDir, "result.txt");
if (File.Exists(result))
{
File.Delete(result);
}

await service.StartAsync(workDir, default);
var kernel = DotnetInteractiveKernelBuilder
.CreateDefaultBuilder()
.AddPythonKernel("python3")
.Build();

var gptConfig = LLMConfiguration.GetAzureOpenAIGPT3_5_Turbo();

var helperAgent = new GPTAgent(
name: "helper",
systemMessage: "You are a helpful AI assistant",
temperature: 0f,
config: gptConfig);

var groupAdmin = new GPTAgent(
name: "groupAdmin",
systemMessage: "You are the admin of the group chat",
Expand All @@ -56,8 +38,8 @@ public static async Task RunAsync()
systemMessage: """
You are a manager who takes coding problem from user and resolve problem by splitting them into small tasks and assign each task to the most appropriate agent.
Here's available agents who you can assign task to:
- coder: write dotnet code to resolve task
- runner: run dotnet code from coder
- coder: write python code to resolve task
- runner: run python code from coder
The workflow is as follows:
- You take the coding problem from user
Expand All @@ -83,15 +65,7 @@ You are a manager who takes coding problem from user and resolve problem by spli
Once the coding problem is resolved, summarize each steps and results and send the summary to the user using the following format:
```summary
{
"problem": "{coding problem}",
"steps": [
{
"step": "{step}",
"result": "{result}"
}
]
}
@user, <summary of the task>
```
Your reply must contain one of [task|ask|summary] to indicate the type of your message.
Expand All @@ -110,19 +84,16 @@ Your reply must contain one of [task|ask|summary] to indicate the type of your m
// The nuget agent install nuget packages if there's any.
var coderAgent = new GPTAgent(
name: "coder",
systemMessage: @"You act as dotnet coder, you write dotnet code to resolve task. Once you finish writing code, ask runner to run the code for you.
systemMessage: @"You act as python coder, you write python code to resolve task. Once you finish writing code, ask runner to run the code for you.
Here're some rules to follow on writing dotnet code:
- put code between ```csharp and ```
- When creating http client, use `var httpClient = new HttpClient()`. Don't use `using var httpClient = new HttpClient()` because it will cause error when running the code.
- Try to use `var` instead of explicit type.
- Try avoid using external library, use .NET Core library instead.
- Use top level statement to write code.
- put code between ```python and ```
- Try avoid using external library
- Always print out the result to console. Don't write code that doesn't print out anything.
If you need to install nuget packages, put nuget packages in the following format:
```nuget
nuget_package_name
Use the following format to install pip package:
```python
%pip install <package_name>
```
If your code is incorrect, Fix the error and send the code again.
Expand All @@ -143,10 +114,8 @@ Your reply must contain one of [task|ask|summary] to indicate the type of your m
name: "reviewer",
systemMessage: """
You are a code reviewer who reviews code from coder. You need to check if the code satisfy the following conditions:
- The reply from coder contains at least one code block, e.g ```csharp and ```
- There's only one code block and it's csharp code block
- The code block is not inside a main function. a.k.a top level statement
- The code block is not using declaration when creating http client
- The reply from coder contains at least one code block, e.g ```python and ```
- There's only one code block and it's python code block
You don't check the code style, only check if the code satisfy the above conditions.
Expand All @@ -173,14 +142,32 @@ Your reply must contain one of [task|ask|summary] to indicate the type of your m
// The runner agent will run the code block from coder's reply.
// It runs dotnet code using dotnet interactive service hook.
// It also truncate the output if the output is too long.
var runner = new AssistantAgent(
var runner = new DefaultReplyAgent(
name: "runner",
defaultReply: "No code available, coder, write code please")
.RegisterDotnetCodeBlockExectionHook(interactiveService: service)
.RegisterMiddleware(async (msgs, option, agent, ct) =>
{
var mostRecentCoderMessage = msgs.LastOrDefault(x => x.From == "coder") ?? throw new Exception("No coder message found");
return await agent.GenerateReplyAsync(new[] { mostRecentCoderMessage }, option, ct);

if (mostRecentCoderMessage.ExtractCodeBlock("```python", "```") is string code)
{
var result = await kernel.RunSubmitCodeCommandAsync(code, "python");
// only keep the first 500 characters
if (result.Length > 500)
{
result = result.Substring(0, 500);
}
result = $"""
# [CODE_BLOCK_EXECUTION_RESULT]
{result}
""";

return new TextMessage(Role.Assistant, result, from: agent.Name);
}
else
{
return await agent.GenerateReplyAsync(msgs, option, ct);
}
})
.RegisterPrintMessage();

Expand Down Expand Up @@ -251,18 +238,27 @@ Your reply must contain one of [task|ask|summary] to indicate the type of your m
workflow: workflow);

// task 1: retrieve the most recent pr from mlnet and save it in result.txt
var groupChatManager = new GroupChatManager(groupChat);
await userProxy.SendAsync(groupChatManager, "Retrieve the most recent pr from mlnet and save it in result.txt", maxRound: 30);
File.Exists(result).Should().BeTrue();

// task 2: calculate the 39th fibonacci number
var answer = 63245986;
// clear the result file
File.Delete(result);
var task = """
retrieve the most recent pr from mlnet and save it in result.txt
""";
var chatHistory = new List<IMessage>
{
new TextMessage(Role.Assistant, task)
{
From = userProxy.Name
}
};
await foreach (var message in groupChat.SendAsync(chatHistory, maxRound: 10))
{
if (message.From == admin.Name && message.GetContent().Contains("```summary"))
{
// Task complete!
break;
}
}

var conversationHistory = await userProxy.InitiateChatAsync(groupChatManager, "What's the 39th of fibonacci number? Save the result in result.txt", maxRound: 10);
// check if the result file is created
var result = "result.txt";
File.Exists(result).Should().BeTrue();
var resultContent = File.ReadAllText(result);
resultContent.Should().Contain(answer.ToString());
}
}
Loading

0 comments on commit 9c57c51

Please sign in to comment.