You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

MiddlewareTest.cs 5.5 kB

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>
2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // MiddlewareTest.cs
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text.Json;
  7. using System.Threading.Tasks;
  8. using Azure.AI.OpenAI;
  9. using FluentAssertions;
  10. using Xunit;
  11. namespace AutoGen.Tests;
  12. public partial class MiddlewareTest
  13. {
  14. [Function]
  15. public async Task<string> Echo(string message)
  16. {
  17. return $"[FUNC] {message}";
  18. }
  19. [Fact]
  20. public async Task HumanInputMiddlewareTestAsync()
  21. {
  22. var agent = new EchoAgent("echo");
  23. var neverAskUserInputMW = new HumanInputMiddleware(mode: HumanInputMode.NEVER);
  24. var neverInputAgent = agent.RegisterMiddleware(neverAskUserInputMW);
  25. var reply = await neverInputAgent.SendAsync("hello");
  26. reply.GetContent()!.Should().Be("hello");
  27. reply.From.Should().Be("echo");
  28. var alwaysAskUserInputMW = new HumanInputMiddleware(
  29. mode: HumanInputMode.ALWAYS,
  30. getInput: () => "input");
  31. var alwaysInputAgent = agent.RegisterMiddleware(alwaysAskUserInputMW);
  32. reply = await alwaysInputAgent.SendAsync("hello");
  33. reply.GetContent()!.Should().Be("input");
  34. reply.From.Should().Be("echo");
  35. // test auto mode
  36. // if the reply from echo is not terminate message, return the original reply
  37. var autoAskUserInputMW = new HumanInputMiddleware(
  38. mode: HumanInputMode.AUTO,
  39. isTermination: async (messages, ct) => messages.Last()?.GetContent() == "terminate",
  40. getInput: () => "input",
  41. exitKeyword: "exit");
  42. var autoInputAgent = agent.RegisterMiddleware(autoAskUserInputMW);
  43. reply = await autoInputAgent.SendAsync("hello");
  44. reply.GetContent()!.Should().Be("hello");
  45. // if the reply from echo is terminate message, asking user for input
  46. reply = await autoInputAgent.SendAsync("terminate");
  47. reply.GetContent()!.Should().Be("input");
  48. // if the reply from echo is terminate message, and user input is exit, return the TERMINATE message
  49. autoAskUserInputMW = new HumanInputMiddleware(
  50. mode: HumanInputMode.AUTO,
  51. isTermination: async (messages, ct) => messages.Last().GetContent() == "terminate",
  52. getInput: () => "exit",
  53. exitKeyword: "exit");
  54. autoInputAgent = agent.RegisterMiddleware(autoAskUserInputMW);
  55. reply = await autoInputAgent.SendAsync("terminate");
  56. reply.IsGroupChatTerminateMessage().Should().BeTrue();
  57. }
  58. [Fact]
  59. public async Task FunctionCallMiddlewareTestAsync()
  60. {
  61. var agent = new EchoAgent("echo");
  62. var args = new EchoSchema { message = "hello" };
  63. var argsJson = JsonSerializer.Serialize(args) ?? throw new InvalidOperationException("Failed to serialize args");
  64. var functionCall = new FunctionCall("echo", argsJson);
  65. var functionCallAgent = agent.RegisterMiddleware(async (messages, options, agent, ct) =>
  66. {
  67. if (options?.Functions is null)
  68. {
  69. return await agent.GenerateReplyAsync(messages, options, ct);
  70. }
  71. return new ToolCallMessage(functionCall.Name, functionCall.Arguments, from: agent.Name);
  72. });
  73. // test 1
  74. // middleware should invoke function call if the message is a function call message
  75. var mw = new FunctionCallMiddleware(
  76. functionMap: new Dictionary<string, Func<string, Task<string>>> { { "echo", EchoWrapper } });
  77. var testAgent = agent.RegisterMiddleware(mw);
  78. var functionCallMessage = new ToolCallMessage(functionCall.Name, functionCall.Arguments, from: "user");
  79. var reply = await testAgent.SendAsync(functionCallMessage);
  80. reply.Should().BeOfType<ToolCallResultMessage>();
  81. reply.GetContent()!.Should().Be("[FUNC] hello");
  82. reply.From.Should().Be("echo");
  83. // test 2
  84. // middleware should invoke function call if agent reply is a function call message
  85. mw = new FunctionCallMiddleware(
  86. functions: [this.EchoFunctionContract],
  87. functionMap: new Dictionary<string, Func<string, Task<string>>> { { "echo", EchoWrapper } });
  88. testAgent = functionCallAgent.RegisterMiddleware(mw);
  89. reply = await testAgent.SendAsync("hello");
  90. reply.GetContent()!.Should().Be("[FUNC] hello");
  91. reply.From.Should().Be("echo");
  92. // test 3
  93. // middleware should return original reply if the reply from agent is not a function call message
  94. mw = new FunctionCallMiddleware(
  95. functionMap: new Dictionary<string, Func<string, Task<string>>> { { "echo", EchoWrapper } });
  96. testAgent = agent.RegisterMiddleware(mw);
  97. reply = await testAgent.SendAsync("hello");
  98. reply.GetContent()!.Should().Be("hello");
  99. reply.From.Should().Be("echo");
  100. // test 4
  101. // middleware should return an error message if the function name is not available when invoking the function from previous agent reply
  102. mw = new FunctionCallMiddleware(
  103. functionMap: new Dictionary<string, Func<string, Task<string>>> { { "echo2", EchoWrapper } });
  104. testAgent = agent.RegisterMiddleware(mw);
  105. reply = await testAgent.SendAsync(functionCallMessage);
  106. reply.GetContent()!.Should().Be("Function echo is not available. Available functions are: echo2");
  107. }
  108. }