autogen/dotnet/sample/AutoGen.BasicSamples/Example12_TwoAgent_Fill_Application.cs
Xiaoyun Zhang 600bd3f2fe
Bring Dotnet AutoGen (#924)
* update readme

* update

* update

* update

* update

* update

* update

* add sample project

* revert notebook change back

* update

* update interactive version

* add nuget package

* refactor Message

* update example

* add azure nightly build pipeline

* Set up CI with Azure Pipelines

[skip ci]

* Update nightly-build.yml for Azure Pipelines

* add dotnet interactive package

* add dotnet interactive package

* update pipeline

* add nuget feed back

* remove dotnet-tool feed

* remove dotnet-tool feed comment

* update pipeline

* update build name

* Update nightly-build.yml

* Delete .github/workflows/dotnet-ci.yml

* update

* add working_dir to use step

* add initateChat api

* update oai package

* Update dotnet-build.yml

* Update dotnet-run-openai-test-and-notebooks.yml

* update build workflow

* update build workflow

* update nuget feed

* update nuget feed

* update aoai and sk version

* Update InteractiveService.cs

* add support for GPT 4V

* add DalleAndGPT4V example

* update example

* add user proxy agent

* add readme

* bump version

* update example

* add dotnet interactive hook

* update

* udpate tests

* add website

* update index.md

* add docs

* update doc

* move sk dependency out of core package

* udpate doc

* Update Use-function-call.md

* add type safe function call document

* update doc

* update doc

* add dock

* Update Use-function-call.md

* add GenerateReplyOptions

* remove IChatLLM

* update version

* update doc

* update website

* add sample

* fix link

* add middleware agent

* clean up doc

* bump version

* update doc

* update

* add Other Language

* remove warnings

* add sign.props

* add sign step

* fix pipelien

* auth

* real sign

* disable PR trigger

* update

* disable PR trigger

* use microbuild machine

* update build pipeline to add publish to internal feed

* add internal feed

* fix build pipeline

* add dotnet prefix

* update ci

* add build number

* update run number

* update source

* update token

* update

* remove adding source

* add publish to github package

* try again

* try again

* ask for write pacakge

* disable package when branch is not main

* update

* implement streaming agent

* add test for streaming function call

* update

* fix #1588

* enable PR check for dotnet branch

* add website readme

* only publish to dotnet feed when pushing to dotnet branch

* remove openai-test-and-notebooks workflow

* update readme

* update readme

* update workflow

* update getting-start

* upgrade test and sample proejct to use .net 8

* fix global.json format && make loadFromConfig API internal only before implementing

* update

* add support for LM studio

* add doc

* Update README.md

* add push and workflow_dispatch trigger

* disable PR for main

* add dotnet env

* Update Installation.md

* add nuget

* refer to newtonsoft 13

* update branch to dotnet in docfx

* Update Installation.md

* pull out HumanInputMiddleware and FunctionCallMiddleware

* fix tests

* add link to sample folder

* refactor message

* refactor over IMessage

* add more tests

* add more test

* fix build error

* rename header

* add semantic kernel project

* update sk example

* update dotnet version

* add LMStudio function call example

* rename LLaMAFunctin

* remove dotnet run openai test and notebook workflow

* add FunctionContract and test

* update doc

* add documents

* add workflow

* update

* update sample

* fix warning in test

* reult length can be less then maximumOutputToKeep (#1804)

* merge with main

* add option to retrieve inner agent and middlewares from MiddlewareAgent

* update doc

* adjust namespace

* update readme

* fix test

* use IMessage

* more updates

* update

* fix test

* add comments

* use FunctionContract to replace FunctionDefinition

* move AutoGen contrac to AutoGen.Core

* update installation

* refactor streamingAgent by adding StreamingMessage type

* update sample

* update samples

* update

* update

* add test

* fix test

* bump version

* add openaichat test

* update

* Update Example03_Agent_FunctionCall.cs

* [.Net] improve docs (#1862)

* add doc

* add doc

* add doc

* add doc

* add doc

* add doc

* update

* fix test error

* fix some error

* fix test

* fix test

* add more tests

* edits

---------

Co-authored-by: ekzhu <ekzhu@users.noreply.github.com>

* [.Net] Add fill form example (#1911)

* add form filler example

* update

* fix ci error

* [.Net] Add using AutoGen.Core in source generator (#1983)

* fix using namespace bug in source generator

* remove using in sourcegenerator test

* disable PR test

* Add .idea to .gitignore (#1988)

* [.Net] publish to nuget.org feed (#1987)

* publish to nuget

* update ci

* update dotnet-release

* update release pipeline

* add source

* remove empty symbol package

* update pipeline

* remove tag

* update installation guide

* [.Net] Rename some classes && APIs based on doc review (#1980)

* rename sequential group chat to round robin group chat

* rename to sendInstruction

* rename workflow to graph

* rename some api

* bump version

* move Graph to GroupChat folder

* rename fill application example

* [.Net] Improve package description (#2161)

* add discord link and update package description

* Update getting-start.md

* [.Net] Fix document comment from the most recent AutoGen.Net engineer sync (#2231)

* update

* rename RegisterPrintMessageHook to RegisterPrintMessage

* update website

* update update.md

* fix link error

* [.Net] Enable JsonMode and deterministic output in AutoGen.OpenAI OpenAIChatAgent (#2347)

* update openai version && add sample for json output

* add example in web

* update update.md

* update image url

* [.Net] Add AutoGen.Mistral package (#2330)

* add mstral client

* enable streaming support

* add mistralClientAgent

* add test for function call

* add extension

* add support for toolcall and toolcall result message

* add support for aggregate message

* implement streaming function call

* track (#2471)

* [.Net] add mistral example (#2482)

* update existing examples to use messageCOnnector

* add overview

* add function call document

* add example 14

* add mistral token count usage example

* update version

* Update dotnet-release.yml (#2488)

* update

* revert gitattributes

---------

Co-authored-by: mhensen <mh@webvize.nl>
Co-authored-by: ekzhu <ekzhu@users.noreply.github.com>
Co-authored-by: Krzysztof Kasprowicz <60486987+Krzysztof318@users.noreply.github.com>
2024-04-26 16:21:46 +00:00

200 lines
7.8 KiB
C#

// Copyright (c) Microsoft Corporation. All rights reserved.
// Example11_TwoAgent_Fill_Application.cs
using System.Text;
using AutoGen.OpenAI;
using AutoGen.Core;
using Azure.AI.OpenAI;
using AutoGen.OpenAI.Extension;
namespace AutoGen.BasicSample;
public partial class TwoAgent_Fill_Application
{
private string? name = null;
private string? email = null;
private string? phone = null;
private string? address = null;
private bool? receiveUpdates = null;
[Function]
public async Task<string> SaveProgress(
string name,
string email,
string phone,
string address,
bool? receiveUpdates)
{
this.name = !string.IsNullOrEmpty(name) ? name : this.name;
this.email = !string.IsNullOrEmpty(email) ? email : this.email;
this.phone = !string.IsNullOrEmpty(phone) ? phone : this.phone;
this.address = !string.IsNullOrEmpty(address) ? address : this.address;
this.receiveUpdates = receiveUpdates ?? this.receiveUpdates;
var missingInformationStringBuilder = new StringBuilder();
if (string.IsNullOrEmpty(this.name))
{
missingInformationStringBuilder.AppendLine("Name is missing.");
}
if (string.IsNullOrEmpty(this.email))
{
missingInformationStringBuilder.AppendLine("Email is missing.");
}
if (string.IsNullOrEmpty(this.phone))
{
missingInformationStringBuilder.AppendLine("Phone is missing.");
}
if (string.IsNullOrEmpty(this.address))
{
missingInformationStringBuilder.AppendLine("Address is missing.");
}
if (this.receiveUpdates == null)
{
missingInformationStringBuilder.AppendLine("ReceiveUpdates is missing.");
}
if (missingInformationStringBuilder.Length > 0)
{
return missingInformationStringBuilder.ToString();
}
else
{
return "Application information is saved to database.";
}
}
public static async Task<IAgent> CreateSaveProgressAgent()
{
var gpt3Config = LLMConfiguration.GetAzureOpenAIGPT3_5_Turbo();
var endPoint = gpt3Config.Endpoint ?? throw new Exception("Please set AZURE_OPENAI_ENDPOINT environment variable.");
var apiKey = gpt3Config.ApiKey ?? throw new Exception("Please set AZURE_OPENAI_API_KEY environment variable.");
var openaiClient = new OpenAIClient(new Uri(endPoint), new Azure.AzureKeyCredential(apiKey));
var instance = new TwoAgent_Fill_Application();
var functionCallConnector = new FunctionCallMiddleware(
functions: [instance.SaveProgressFunctionContract],
functionMap: new Dictionary<string, Func<string, Task<string>>>
{
{ instance.SaveProgressFunctionContract.Name, instance.SaveProgressWrapper },
});
var chatAgent = new OpenAIChatAgent(
openAIClient: openaiClient,
name: "application",
modelName: gpt3Config.DeploymentName,
systemMessage: """You are a helpful application form assistant who saves progress while user fills application.""")
.RegisterMessageConnector()
.RegisterMiddleware(functionCallConnector)
.RegisterMiddleware(async (msgs, option, agent, ct) =>
{
var lastUserMessage = msgs.Last() ?? throw new Exception("No user message found.");
var prompt = $"""
Save progress according to the most recent information provided by user.
```user
{lastUserMessage.GetContent()}
```
""";
return await agent.GenerateReplyAsync([lastUserMessage], option, ct);
});
return chatAgent;
}
public static async Task<IAgent> CreateAssistantAgent()
{
var gpt3Config = LLMConfiguration.GetAzureOpenAIGPT3_5_Turbo();
var endPoint = gpt3Config.Endpoint ?? throw new Exception("Please set AZURE_OPENAI_ENDPOINT environment variable.");
var apiKey = gpt3Config.ApiKey ?? throw new Exception("Please set AZURE_OPENAI_API_KEY environment variable.");
var openaiClient = new OpenAIClient(new Uri(endPoint), new Azure.AzureKeyCredential(apiKey));
var chatAgent = new OpenAIChatAgent(
openAIClient: openaiClient,
name: "assistant",
modelName: gpt3Config.DeploymentName,
systemMessage: """You create polite prompt to ask user provide missing information""")
.RegisterMessageConnector()
.RegisterPrintMessage()
.RegisterMiddleware(async (msgs, option, agent, ct) =>
{
var lastReply = msgs.Last() ?? throw new Exception("No reply found.");
var reply = await agent.GenerateReplyAsync(msgs, option, ct);
// if application is complete, exit conversation by sending termination message
if (lastReply.GetContent().Contains("Application information is saved to database."))
{
return new TextMessage(Role.Assistant, GroupChatExtension.TERMINATE, from: agent.Name);
}
else
{
return reply;
}
});
return chatAgent;
}
public static async Task<IAgent> CreateUserAgent()
{
var gpt3Config = LLMConfiguration.GetAzureOpenAIGPT3_5_Turbo();
var endPoint = gpt3Config.Endpoint ?? throw new Exception("Please set AZURE_OPENAI_ENDPOINT environment variable.");
var apiKey = gpt3Config.ApiKey ?? throw new Exception("Please set AZURE_OPENAI_API_KEY environment variable.");
var openaiClient = new OpenAIClient(new Uri(endPoint), new Azure.AzureKeyCredential(apiKey));
var chatAgent = new OpenAIChatAgent(
openAIClient: openaiClient,
name: "user",
modelName: gpt3Config.DeploymentName,
systemMessage: """
You are a user who is filling an application form. Simply provide the information as requested and answer the questions, don't do anything else.
here's some personal information about you:
- name: John Doe
- email: 1234567@gmail.com
- phone: 123-456-7890
- address: 1234 Main St, Redmond, WA 98052
- want to receive update? true
""")
.RegisterMessageConnector()
.RegisterPrintMessage();
return chatAgent;
}
public static async Task RunAsync()
{
var applicationAgent = await CreateSaveProgressAgent();
var assistantAgent = await CreateAssistantAgent();
var userAgent = await CreateUserAgent();
var userToApplicationTransition = Transition.Create(userAgent, applicationAgent);
var applicationToAssistantTransition = Transition.Create(applicationAgent, assistantAgent);
var assistantToUserTransition = Transition.Create(assistantAgent, userAgent);
var workflow = new Graph(
[
userToApplicationTransition,
applicationToAssistantTransition,
assistantToUserTransition,
]);
var groupChat = new GroupChat(
members: [userAgent, applicationAgent, assistantAgent],
workflow: workflow);
var groupChatManager = new GroupChatManager(groupChat);
var initialMessage = await assistantAgent.SendAsync("Generate a greeting meesage for user and start the conversation by asking what's their name.");
var chatHistory = await userAgent.SendAsync(groupChatManager, [initialMessage], maxRound: 30);
var lastMessage = chatHistory.Last();
Console.WriteLine(lastMessage.GetContent());
}
}