Compare commits

...

62 Commits

Author SHA1 Message Date
Xiaoyun Zhang ebe099a75f
Merge 0717bf4e91 into 16463a8a98 2024-11-13 10:35:49 -05:00
Mehdi Baneshi 16463a8a98
Update topic-and-subscription.md (#4168) 2024-11-13 10:33:47 -05:00
Victor Dibia b9f7282830
Add visualization of Agent Message Transitions State in AGS (#4148)
* add react-flow

* update tutorial, some ui improvement for agent thread layout

* v1 for interactive viz for agent state

* add Ui visualization of message based transitions

* minor updates

* fix node edges, support visualization of self loops

* improve edges and layout, add support for selector group chat prompt

* minor ui tweaks
2024-11-12 20:29:06 -08:00
Jack Gerrits 913c052a7d
Fix topic name for community samples (#4156) 2024-11-12 16:08:25 -08:00
Ryan Sweet 458d273fc4
Refactoring the services and implementing an in-memory runtime for .NET (#4005)
closes #3950 closes #3702

What this is doing:

I am refactoring the services on the .NET runtime and attempting to clarify the naming and organization.
I added this doc to help capture the naming and concepts.
AgentRuntime / Worker should work similar to the python version and enables running the whole agent system in one process. For remote the system uses the versions of the services in the grpc folder.
lots of other bug fixes/threading cleanup - passing cancellation token throughout
Services update clarifies the naming and roles:

Worker: Hosts the Agents and is a client to the Gateway
Gateway:
-- RPC gateway for the other services APIs
-- Provides an RPC bridge between the workers and the Event Bus
Registry: keeps track of the agents in the system and which events they can handle
AgentState: persistent state for agents
2024-11-12 11:04:59 -08:00
afourney 51b361dfcf
WebSurfer changes - incl move to lazy init. (#4092)
* Move to lazy init.

* Fixed mypy error.

---------

Co-authored-by: Hussein Mozannar <hmozannar@microsoft.com>
2024-11-11 22:31:00 -08:00
afourney e111db9afa
Handle on_reset (#4145) 2024-11-11 20:45:51 -05:00
Mohammad Mazraeh 570471bed7
Add reply chat completion client (#4096)
* initial implementation of reply chat completion client

---------

Signed-off-by: Mohammad Mazraeh <mazraeh.mohammad@gmail.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2024-11-11 15:33:44 -05:00
Gerardo Moreno 3b8d0ddb67
Various Additions to the Documentation (#4139)
* Various docs improvements

* Update python/packages/autogen-core/docs/src/user-guide/core-user-guide/framework/command-line-code-executors.ipynb

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2024-11-11 15:23:25 -05:00
peterychang 0afde6da69
Protobuf serializer (#4137)
* protobuf serialization in python

* remove test code

* clarify TODO
2024-11-11 14:20:15 -05:00
Eric Zhu e27c740961
dev6 (#4129) 2024-11-11 00:48:05 -05:00
Eric Zhu 4786f189bc
Handoff termination and show how to use it for asking user input (#4128)
* Handoff termination and show how to use it for asking user input

* lint
2024-11-11 00:38:52 -05:00
Eric Zhu 9f175089c5
Introduction to Teams for AgentChat (#4120)
* Add teams section

* wip don't merge

* Merge remote-tracking branch 'origin/main' into agentchat-team-tutorial

* update instruction about termination reset

* edit

* more guidline for script
2024-11-10 20:39:06 -08:00
Eric Zhu 5547a6716e
auto reset termination when a run stops (#4126) 2024-11-10 20:19:09 -08:00
Eric Zhu 1cc0f4f7c5
dev5 (#4124) 2024-11-10 21:42:22 -05:00
Eric Zhu 8f7c717149
reset --> on_reset :D (#4121) 2024-11-10 18:28:20 -08:00
Eric Zhu 12becdddb1
Update agentchat tutorial, refactor content (#4118)
Resolves Tutorial Chapter for Custom ChatAgent #4114 -- updated tutorial chapter on agents and custom agents
Update README example to use tool call
Added "Models" section in AgentChat tutorial.
Added place holder for Tutorial Chapter for Swarm #4113.
2024-11-09 19:07:39 -08:00
Victor Dibia 0e985d4b40
v1 of AutoGen Studio on AgentChat (#4097)
* add skeleton worflow manager

* add test notebook

* update test nb

* add sample team spec

* refactor requirements to agentchat and ext

* add base provider to return agentchat agents from json spec

* initial api refactor, update dbmanager

* api refactor

* refactor tests

* ags api tutorial update

* ui refactor

* general refactor

* minor refactor updates

* backend api refaactor

* ui refactor and update

* implement v1 for streaming connection with ui updates

* backend refactor

* ui refactor

* minor ui tweak

* minor refactor and tweaks

* general refactor

* update tests

* sync uv.lock with main

* uv lock update
2024-11-09 14:32:24 -08:00
Eric Zhu f40b0c2730
Add Console function to stream result to pretty print console output (#4115) 2024-11-08 19:02:19 -08:00
Eric Zhu 3f28aa8874
SocietyOfMind agent for nested teams (#4110)
* Initial implementation of SOM agent

* add tests

* edit prompt

* Update prompt

* lint
2024-11-08 16:41:34 -08:00
Eric Zhu 111e69142b
Fix worker sample in core (#4104) 2024-11-08 12:18:07 -08:00
Diego Colombo 621b17ebbe
Simplify publish events in agent (#4093)
* simplify publishing imessage contracts

use new api

complete adoption

remove unused project

more delete

more delete

* rename methods

* formatting

* Add task type that are messages to enable multi-modal tasks. (#4091)

* Add task type that are messages to enable multi-modal tasks.

* fix test

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2024-11-08 14:16:24 +00:00
Eric Zhu 5fa38b0166
Add task type that are messages to enable multi-modal tasks. (#4091)
* Add task type that are messages to enable multi-modal tasks.

* fix test
2024-11-07 21:38:41 -08:00
Eric Zhu 9e388925d4
Initial web surfer implementation in extension (#4071)
* Initial web surfer implementation in extension

* Moved model client to constructor for consistency.

* Fixed uv lock.

* Merge branch 'main' into websurfer

* fix ruff
2024-11-07 16:47:53 -08:00
Eric Zhu 2e3155be2a
AgentChat pause, resume, and reset (#4088)
* AgentChat pause and resume a task
Resolves #3859

* Add

* Update usage

* Update usage

* WIP to address stateful group chat

* Refactor group chat to add reset and flags for running

* documentation
2024-11-07 16:00:35 -08:00
Mark Sze 930e61306a
Update README.md (#4078) 2024-11-06 13:17:00 -08:00
Mahesh Subramanian 2382ff9248
chore(typo): Fixing a typo in the agent identity document (#4070) 2024-11-06 10:07:13 -08:00
Eric Zhu 4be1c9cf76
Update Python version to 0.4.0.dev4 (#4068)
* Update version to dev4
2024-11-05 22:04:37 -08:00
Eric Zhu 5be7ac7b12
Move reset from a message to a command (#4073) 2024-11-05 21:40:46 -08:00
David Luong 378b307623
[.NET] Enable package vulnerable (#4054)
* wip for vulernable package checks

* edit yml build

* Set value to 'true'

* Change NuGetAudit to NuGetAuditMode

* Change NugetAuditMode to direct

---------

Co-authored-by: Xiaoyun Zhang <bigmiao.zhang@gmail.com>
2024-11-05 13:46:39 -05:00
Eric Zhu c3283c64a3
Agentchat refactor (#4062)
* Agentchat refactor

* Move termination stop message to a separate field in task result

* Update quick start example

* Use string stop reason instead of stop message in task result for simpler API

* Use main function
2024-11-05 08:07:49 -08:00
Hussein Mozannar 10987685b9
Update README.md for magentic-one (#4061) 2024-11-04 17:45:59 -08:00
Hussein Mozannar 8603317537
Magentic-One Log Viewer + preview API (#4032)
* update example script with logs dir, add screenshot timestamp

* readme examples update

* add flask app to view magentic_one

* remove copy example

* rename

* changes to magentic one helper

* update test web surfer to delete logs

* magentic_one icons

* fix colors - final log viewer

* fix termination condition

* update coder and log viewer

* timeout time

* make tests pass

* logs dir

* repeated thing

* remove log_viewer, mm web surfer comments

* coder change prompt, edit readmes

* type ignore

* remove logviewer

* add flag for coder agent

* readme

* changes readme

* uv lock

* update readme figures

* not yet

* pointer images
2024-11-04 17:18:46 -08:00
Gerardo Moreno eca8a95c61
Remove isinstance check from FunctionTool (#3987) (#4056)
* Remove isinstance check from FunctionTool (#3987)

* Move __init__ Args to class docstring

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2024-11-04 16:48:57 -08:00
Reuben Bond f40336fda1
Do not exclude Properties or appsettings.json via .gitignore, commit missing files (#4057) 2024-11-04 20:48:46 +01:00
Eric Zhu 16e64c4c10
Rename `model_usage` to `models_usage`. (#4053) 2024-11-04 09:25:53 -08:00
David Luong f46e52e6ff
[.NET] Update version of Microsoft.Extension.Ai & System.Text.Json (#4044)
* Upgrade version of M.E.A.I & STJ

* remove copilot generated comment

* Revert NoWarnDuplicatePackages and remove S.T.J from Directory.Packages.props

---------

Co-authored-by: Xiaoyun Zhang <bigmiao.zhang@gmail.com>
2024-11-04 08:40:53 -05:00
Xiaoyun Zhang 5e0b677acc
[.NET] Create tools from M.E.A.I AIFunctionFactory (#4041)
* add MEAI tool support

* fix format

* update

---------

Co-authored-by: Ryan Sweet <rysweet@microsoft.com>
2024-11-03 09:18:32 -08:00
Eric Zhu 4e5f3ababe
Update version to 0.4.0.dev3 (#4043) 2024-11-01 16:08:09 -07:00
Eric Zhu 4fec22ddc5
Team termination condition sets in the constructor (#4042)
* Termination condition as part of constructor

* Update doc

* Update notebooks
2024-11-01 15:49:37 -07:00
Reuben Bond 7d1857dae6
Clean up the Hello sample, support Aspire 9.0, & fix shutdown in the sample (#4037)
* Wait for acknowledgment when sending message to gRPC channel

* Add CancellationToken parameters to API surface

* Clean up the Hello sample, support Aspire 9.0, & fix shutdown
2024-11-01 15:43:20 -07:00
Eric Zhu 27ea99a485
Add token usage termination (#4035)
* Add token usage termination

* fix test
2024-11-01 15:01:43 -07:00
Eric Zhu ca7caa779d
Add token usage to messages (#4028)
* Add token usage to messages

* small test edit
2024-11-01 13:20:25 -07:00
Reuben Bond e9c16fe22e
Add CancellationToken parameters to API surface (#4036) 2024-11-01 13:17:17 -07:00
Reuben Bond a4901f3ba8
Wait for acknowledgment when sending message to gRPC channel (#4034) 2024-11-01 12:59:50 -07:00
Eric Zhu c3b2597e12
AssistantAgent no longer sends out StopMessage. We use TextMentionTermination("TERMINATE") on the team instead for default setting. (#4030)
* AssistantAgent no longer sends out StopMessage. We use TextMentionTermination("TERMINATE") on the team instead for default setting.

* Fix test
2024-11-01 12:35:26 -07:00
Eric Zhu 173acc6638
Custom selector function for SelectorGroupChat (#4026)
* Custom selector function for SelectorGroupChat

* Update documentation
2024-11-01 09:08:29 -07:00
Eric Zhu 369ffb511b
Remove termination condition from team constructor (#4025)
* Remove termination condition from team constructor

* fix usage
2024-11-01 05:50:20 -07:00
Eric Zhu cff7d842a6
AgentChat streaming API (#4015) 2024-11-01 04:12:43 -07:00
Mohammad Mazraeh 4023454c58
add simple chainlit integration (#3999) 2024-10-31 04:54:24 -07:00
Rohan Thacker 3c63f6f3ef
Corrected typo in get_capabilities in _model_info.py (#4002) 2024-10-30 13:39:45 -07:00
Xiaoyun Zhang 6bea055b26
[.Net] Add a generic `IHandle` interface so AgentRuntime doesn't need to deal with typed handler (#3985)
* add IHandle for object type

* rename handle -> handleObject

* remove duplicate file header setting

* update

* remove AgentId

* fix format
2024-10-30 11:53:37 -07:00
Eric Zhu 3d51ab76ae
Formalize `ChatAgent` response as a dataclass with inner messages (#3990) 2024-10-30 10:27:57 -07:00
Xiaoyun Zhang e63fd17ed5
[.Net] use file-scope (#3997)
* use file-scope

* reformat
2024-10-30 10:05:58 -07:00
Ryan Sweet 51cd5b8d1f
interface inheritance examples (#3989)
changes to AgentBase and HostBuilderExtensions to enable leveraging handlers from composition (interfaces) vs inheritance... see HelloAgents sample for usage

closes #3928
is related to #3925
2024-10-30 09:51:01 -07:00
Eric Zhu 4a49844996
`ChatAgent` declares the types of messages it produces (#3991)
* `ChatAgent` declares the types of messages it produces
2024-10-30 05:32:11 -07:00
Victor Dibia 75b00e76e1
Agentchat move termination (#3992) 2024-10-29 18:37:26 -07:00
Ryan Sweet 0f4dd0cc6d
Agentbase refactor (#3980)
Remove unused code, refactor AgentBase and AgentWorker/Runtime to use interfaces throughout to enable future implementation of alternate runtimes and separation of the gprpc service from Agent Base (for future in-memory version). 
Also adds the missing RegisterAgentResponse methods
2024-10-29 16:59:27 -07:00
Anthony Uphof 87bd1de396
Fix: provide valid Prompt and Completion Token usage counts from create_stream (#3972)
* Fix: `create_stream` to return valid usage token counts
* documentation

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2024-10-29 16:20:03 -07:00
XiaoYun Zhang 0717bf4e91 author -> Microsoft to meet Microsoft policy 2024-10-15 09:00:06 -07:00
Xiaoyun Zhang 71b059b65e
Update MetaInfo.props 2024-10-15 08:51:52 -07:00
Xiaoyun Zhang 1611a4e167
Update dotnet-release.yml 2024-10-15 08:45:27 -07:00
395 changed files with 31414 additions and 17085 deletions

6
.gitattributes vendored
View File

@ -33,10 +33,8 @@
*.tsx text
*.xml text
*.xhtml text diff=html
# Docker
Dockerfile text eol=lf
# Documentation
*.ipynb text
*.markdown text diff=markdown eol=lf
@ -62,7 +60,6 @@ NEWS text eol=lf
readme text eol=lf
*README* text eol=lf
TODO text
# Configs
*.cnf text eol=lf
*.conf text eol=lf
@ -84,8 +81,9 @@ yarn.lock text -diff
browserslist text
Makefile text eol=lf
makefile text eol=lf
# Images
*.png filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text
*.jpeg filter=lfs diff=lfs merge=lfs -text
python/packages/autogen-magentic-one/imgs/autogen-magentic-one-example.png filter=lfs diff=lfs merge=lfs -text
python/packages/autogen-magentic-one/imgs/autogen-magentic-one-agents.png filter=lfs diff=lfs merge=lfs -text

View File

@ -177,11 +177,9 @@ jobs:
source ${{ github.workspace }}/python/.venv/bin/activate
poe gen-proto
working-directory: ./python
- name: Evaluate if there are changes
run: |
if [[ `git status --porcelain` ]]; then
echo "There are changes that need to be generated and commit for the proto files"
git --no-pager diff
exit 1
fi
shell: bash
- name: Check if there are uncommited changes
id: changes
uses: UnicornGlobal/has-changes-action@v1.0.11
- name: Process changes
if: steps.changes.outputs.changed == 1
run: echo "There are changes in the proto files. Please commit them."

View File

@ -35,6 +35,10 @@ jobs:
{ ref: "v0.4.0.dev0", dest-dir: "0.4.0.dev0" },
{ ref: "v0.4.0.dev1", dest-dir: "0.4.0.dev1" },
{ ref: "v0.4.0.dev2", dest-dir: "0.4.0.dev2" },
{ ref: "v0.4.0.dev3", dest-dir: "0.4.0.dev3" },
{ ref: "v0.4.0.dev4", dest-dir: "0.4.0.dev4" },
{ ref: "v0.4.0.dev5", dest-dir: "0.4.0.dev5" },
{ ref: "v0.4.0.dev6", dest-dir: "0.4.0.dev6" },
]
steps:
- name: Checkout

View File

@ -45,6 +45,8 @@ jobs:
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Install .NET Aspire workload
run: dotnet workload install aspire
- name: Restore dependencies
run: |
dotnet restore -bl

View File

@ -101,37 +101,45 @@ We look forward to your contributions!
First install the packages:
```bash
pip install autogen-agentchat==0.4.0.dev2 autogen-ext==0.4.0.dev2
pip install 'autogen-agentchat==0.4.0.dev6' 'autogen-ext[openai]==0.4.0.dev6'
```
The following code uses code execution, you need to have [Docker installed](https://docs.docker.com/engine/install/)
and running on your machine.
The following code uses OpenAI's GPT-4o model and you need to provide your
API key to run.
To use Azure OpenAI models, follow the instruction
[here](https://microsoft.github.io/autogen/dev/user-guide/core-user-guide/cookbook/azure-openai-with-aad-auth.html).
```python
import asyncio
import logging
from autogen_agentchat import EVENT_LOGGER_NAME
from autogen_agentchat.agents import CodeExecutorAgent, CodingAssistantAgent
from autogen_agentchat.logging import ConsoleLogHandler
from autogen_agentchat.teams import RoundRobinGroupChat, StopMessageTermination
from autogen_ext.code_executor.docker_executor import DockerCommandLineCodeExecutor
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.task import Console, TextMentionTermination
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_ext.models import OpenAIChatCompletionClient
logger = logging.getLogger(EVENT_LOGGER_NAME)
logger.addHandler(ConsoleLogHandler())
logger.setLevel(logging.INFO)
# Define a tool
async def get_weather(city: str) -> str:
return f"The weather in {city} is 73 degrees and Sunny."
async def main() -> None:
async with DockerCommandLineCodeExecutor(work_dir="coding") as code_executor:
code_executor_agent = CodeExecutorAgent("code_executor", code_executor=code_executor)
coding_assistant_agent = CodingAssistantAgent(
"coding_assistant", model_client=OpenAIChatCompletionClient(model="gpt-4o", api_key="YOUR_API_KEY")
)
group_chat = RoundRobinGroupChat([coding_assistant_agent, code_executor_agent])
result = await group_chat.run(
task="Create a plot of NVDIA and TSLA stock returns YTD from 2024-01-01 and save it to 'nvidia_tesla_2024_ytd.png'.",
termination_condition=StopMessageTermination(),
)
# Define an agent
weather_agent = AssistantAgent(
name="weather_agent",
model_client=OpenAIChatCompletionClient(
model="gpt-4o-2024-08-06",
# api_key="YOUR_API_KEY",
),
tools=[get_weather],
)
# Define termination condition
termination = TextMentionTermination("TERMINATE")
# Define a team
agent_team = RoundRobinGroupChat([weather_agent], termination_condition=termination)
# Run the team and stream messages to the console
stream = agent_team.run_stream(task="What is the weather in New York?")
await Console(stream)
asyncio.run(main())
```
@ -187,13 +195,13 @@ public class HelloAgent(
{
Message = response
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt).ConfigureAwait(false);
await PublishEventAsync(evt).ConfigureAwait(false);
var goodbye = new ConversationClosed
{
UserId = this.AgentId.Key,
UserMessage = "Goodbye"
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(goodbye).ConfigureAwait(false);
await PublishEventAsync(goodbye).ConfigureAwait(false);
}
public async Task Handle(ConversationClosed item)
{
@ -202,7 +210,7 @@ public class HelloAgent(
{
Message = goodbye
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt).ConfigureAwait(false);
await PublishEventAsync(evt).ConfigureAwait(false);
await Task.Delay(60000);
await App.ShutdownAsync();
}

View File

@ -0,0 +1,26 @@
# AutoGen Services
## Overview
Each AutoGen agent system has one or more Agent Workers and a set of services for managing/supporting the agents. The services and workers can all be hosted in the same process or in a distributed system. When in the same process communication and event delivery is in-memory. When distributed, workers communicate with the service over gRPC. In all cases, events are packaged as CloudEvents. There are multiple options for the backend services:
- In-Memory: the Agent Workers and Services are all hosted in the same process and communicate over in-memory channels. Available for python and .NET.
- Python only: Agent workers communicate with a python hosted service that implements an in-memory message bus and agent registry.
- Micrososft Orleans: a distributed actor system that can host the services and workers, enables distributed state with persistent storage, can leverage multiple event bus types, and cross-language agent communication.
- *Roadmap: support for other languages distributed systems such as dapr or Akka.*
The Services in the system include:
- Worker: Hosts the Agents and is a client to the Gateway
- Gateway:
-- RPC gateway for the other services APIs
-- Provides an RPC bridge between the workers and the Event Bus
-- Message Session state (track message queues/delivery)
- Registry: keeps track of the {agents:agent types}:{Subscription/Topics} in the system and which events they can handle
-- *Roadmap: add lookup api in gateway*
- AgentState: persistent state for agents
- Routing: delivers events to agents based on their subscriptions+topics
-- *Roadmap: add subscription management APIs*
- *Roadmap: Management APIs for the Agent System*
- *Roadmap: Scheduling: manages placement of agents*
- *Roadmap: Discovery: allows discovery of agents and services*

View File

@ -21,7 +21,27 @@
{
"name": "0.4.0.dev2",
"version": "0.4.0.dev2",
"url": "/autogen/0.4.0.dev2/",
"url": "/autogen/0.4.0.dev2/"
},
{
"name": "0.4.0.dev3",
"version": "0.4.0.dev3",
"url": "/autogen/0.4.0.dev3/"
},
{
"name": "0.4.0.dev4",
"version": "0.4.0.dev4",
"url": "/autogen/0.4.0.dev4/"
},
{
"name": "0.4.0.dev5",
"version": "0.4.0.dev5",
"url": "/autogen/0.4.0.dev5/"
},
{
"name": "0.4.0.dev6",
"version": "0.4.0.dev6",
"url": "/autogen/0.4.0.dev6/",
"preferred": true
}
]

View File

@ -193,10 +193,6 @@ csharp_using_directive_placement = outside_namespace:error
csharp_prefer_static_local_function = true:warning
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:warning
# Header template
file_header_template = Copyright (c) Microsoft Corporation. All rights reserved.\n{fileName}
dotnet_diagnostic.IDE0073.severity = error
# enable format error
dotnet_diagnostic.IDE0055.severity = error
@ -221,13 +217,14 @@ dotnet_diagnostic.IDE0161.severity = warning # Use file-scoped namespace
csharp_style_var_elsewhere = true:suggestion # Prefer 'var' everywhere
csharp_prefer_simple_using_statement = true:suggestion
csharp_style_namespace_declarations = block_scoped:silent
csharp_style_namespace_declarations = file_scoped:warning
csharp_style_prefer_method_group_conversion = true:silent
csharp_style_prefer_top_level_statements = true:silent
csharp_style_prefer_primary_constructors = true:suggestion
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_prefer_local_over_anonymous_function = true:suggestion
dotnet_diagnostic.CA2016.severity = suggestion
csharp_prefer_static_anonymous_function = true:suggestion
# disable check for generated code
[*.generated.cs]
@ -556,8 +553,8 @@ dotnet_diagnostic.IDE0060.severity = warning
dotnet_diagnostic.IDE0062.severity = warning
# IDE0073: File header
dotnet_diagnostic.IDE0073.severity = suggestion
file_header_template = Copyright (c) Microsoft. All rights reserved.
dotnet_diagnostic.IDE0073.severity = warning
file_header_template = Copyright (c) Microsoft Corporation. All rights reserved.\n{fileName}
# IDE1006: Required naming style
dotnet_diagnostic.IDE1006.severity = warning
@ -697,6 +694,7 @@ dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_simplified_interpolation = true:suggestion
dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion
dotnet_style_namespace_match_folder = true:suggestion
dotnet_style_qualification_for_method = false:silent
[**/*.g.cs]
generated_code = true

5
dotnet/.gitignore vendored
View File

@ -37,9 +37,6 @@ bld/
# vs code cache
.vscode/
# Properties
Properties/
artifacts/
output/
@ -56,8 +53,6 @@ bld/
[Ll]og/
[Ll]ogs/
appsettings.json
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot

View File

@ -68,6 +68,13 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{243E768F-EA7D-4AF1-B625-0398440BB1AB}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.gitattributes = .gitattributes
.gitignore = .gitignore
Directory.Build.props = Directory.Build.props
Directory.Build.targets = Directory.Build.targets
Directory.Packages.props = Directory.Packages.props
global.json = global.json
NuGet.config = NuGet.config
spelling.dic = spelling.dic
EndProjectSection
EndProject
@ -77,12 +84,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AutoGen.Abstracti
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AutoGen.Extensions.SemanticKernel", "src\Microsoft.AutoGen\Extensions\SemanticKernel\Microsoft.AutoGen.Extensions.SemanticKernel.csproj", "{952827D4-8D4C-4327-AE4D-E8D25811EF35}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AutoGen.Extensions.CloudEvents", "src\Microsoft.AutoGen\Extensions\CloudEvents\Microsoft.AutoGen.Extensions.CloudEvents.csproj", "{21C9EC49-E848-4EAE-932F-0862D44F7A80}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AutoGen.Runtime", "src\Microsoft.AutoGen\Runtime\Microsoft.AutoGen.Runtime.csproj", "{A905E29A-7110-497F-ADC5-2CE2A148FEA0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AutoGen.ServiceDefaults", "src\Microsoft.AutoGen\ServiceDefaults\Microsoft.AutoGen.ServiceDefaults.csproj", "{D7E9D90B-5595-4E72-A90A-6DE20D9AB7AE}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AgentChat", "AgentChat", "{668726B9-77BC-45CF-B576-0F0773BF1615}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoGen.Anthropic.Samples", "samples\AutoGen.Anthropic.Samples\AutoGen.Anthropic.Samples.csproj", "{84020C4A-933A-4693-9889-1B99304A7D76}"
@ -125,7 +126,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AIModelClientHostingExtensi
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sample", "sample", "{686480D7-8FEC-4ED3-9C5D-CEBE1057A7ED}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloAgentState", "samples\Hello\HelloAgentState\HelloAgentState.csproj", "{64EF61E7-00A6-4E5E-9808-62E10993A0E5}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloAgentState", "samples\Hello\HelloAgentState\HelloAgentState.csproj", "{64EF61E7-00A6-4E5E-9808-62E10993A0E5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.ServiceDefaults", "src\Microsoft.AutoGen\Extensions\ServiceDefaults\Microsoft.AutoGen.ServiceDefaults.csproj", "{65059914-5527-4A00-9308-9FAF23D5E85A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Agents.Tests", "test\Microsoft.AutoGen.Agents.Tests\Microsoft.AutoGen.Agents.Tests.csproj", "{394FDAF8-74F9-4977-94A5-3371737EB774}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -257,18 +262,6 @@ Global
{952827D4-8D4C-4327-AE4D-E8D25811EF35}.Debug|Any CPU.Build.0 = Debug|Any CPU
{952827D4-8D4C-4327-AE4D-E8D25811EF35}.Release|Any CPU.ActiveCfg = Release|Any CPU
{952827D4-8D4C-4327-AE4D-E8D25811EF35}.Release|Any CPU.Build.0 = Release|Any CPU
{21C9EC49-E848-4EAE-932F-0862D44F7A80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{21C9EC49-E848-4EAE-932F-0862D44F7A80}.Debug|Any CPU.Build.0 = Debug|Any CPU
{21C9EC49-E848-4EAE-932F-0862D44F7A80}.Release|Any CPU.ActiveCfg = Release|Any CPU
{21C9EC49-E848-4EAE-932F-0862D44F7A80}.Release|Any CPU.Build.0 = Release|Any CPU
{A905E29A-7110-497F-ADC5-2CE2A148FEA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A905E29A-7110-497F-ADC5-2CE2A148FEA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A905E29A-7110-497F-ADC5-2CE2A148FEA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A905E29A-7110-497F-ADC5-2CE2A148FEA0}.Release|Any CPU.Build.0 = Release|Any CPU
{D7E9D90B-5595-4E72-A90A-6DE20D9AB7AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D7E9D90B-5595-4E72-A90A-6DE20D9AB7AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7E9D90B-5595-4E72-A90A-6DE20D9AB7AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7E9D90B-5595-4E72-A90A-6DE20D9AB7AE}.Release|Any CPU.Build.0 = Release|Any CPU
{84020C4A-933A-4693-9889-1B99304A7D76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{84020C4A-933A-4693-9889-1B99304A7D76}.Debug|Any CPU.Build.0 = Debug|Any CPU
{84020C4A-933A-4693-9889-1B99304A7D76}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -341,6 +334,14 @@ Global
{64EF61E7-00A6-4E5E-9808-62E10993A0E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{64EF61E7-00A6-4E5E-9808-62E10993A0E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{64EF61E7-00A6-4E5E-9808-62E10993A0E5}.Release|Any CPU.Build.0 = Release|Any CPU
{65059914-5527-4A00-9308-9FAF23D5E85A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{65059914-5527-4A00-9308-9FAF23D5E85A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{65059914-5527-4A00-9308-9FAF23D5E85A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{65059914-5527-4A00-9308-9FAF23D5E85A}.Release|Any CPU.Build.0 = Release|Any CPU
{394FDAF8-74F9-4977-94A5-3371737EB774}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{394FDAF8-74F9-4977-94A5-3371737EB774}.Debug|Any CPU.Build.0 = Debug|Any CPU
{394FDAF8-74F9-4977-94A5-3371737EB774}.Release|Any CPU.ActiveCfg = Release|Any CPU
{394FDAF8-74F9-4977-94A5-3371737EB774}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -378,9 +379,6 @@ Global
{FD87BD33-4616-460B-AC85-A412BA08BB78} = {18BF8DD7-0585-48BF-8F97-AD333080CE06}
{E0C991D9-0DB8-471C-ADC9-5FB16E2A0106} = {18BF8DD7-0585-48BF-8F97-AD333080CE06}
{952827D4-8D4C-4327-AE4D-E8D25811EF35} = {18BF8DD7-0585-48BF-8F97-AD333080CE06}
{21C9EC49-E848-4EAE-932F-0862D44F7A80} = {18BF8DD7-0585-48BF-8F97-AD333080CE06}
{A905E29A-7110-497F-ADC5-2CE2A148FEA0} = {18BF8DD7-0585-48BF-8F97-AD333080CE06}
{D7E9D90B-5595-4E72-A90A-6DE20D9AB7AE} = {18BF8DD7-0585-48BF-8F97-AD333080CE06}
{668726B9-77BC-45CF-B576-0F0773BF1615} = {686480D7-8FEC-4ED3-9C5D-CEBE1057A7ED}
{84020C4A-933A-4693-9889-1B99304A7D76} = {668726B9-77BC-45CF-B576-0F0773BF1615}
{5777515F-4053-42F9-AF2B-95D8D0F5384A} = {668726B9-77BC-45CF-B576-0F0773BF1615}
@ -402,6 +400,8 @@ Global
{8F7560CF-EEBB-4333-A69F-838CA40FD85D} = {7EB336C2-7C0A-4BC8-80C6-A3173AB8DC45}
{97550E87-48C6-4EBF-85E1-413ABAE9DBFD} = {18BF8DD7-0585-48BF-8F97-AD333080CE06}
{64EF61E7-00A6-4E5E-9808-62E10993A0E5} = {7EB336C2-7C0A-4BC8-80C6-A3173AB8DC45}
{65059914-5527-4A00-9308-9FAF23D5E85A} = {18BF8DD7-0585-48BF-8F97-AD333080CE06}
{394FDAF8-74F9-4977-94A5-3371737EB774} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {93384647-528D-46C8-922C-8DB36A382F0B}

View File

@ -13,6 +13,7 @@
<CSNoWarn>CS1998;CS1591;CS8002;</CSNoWarn>
<SKEXPNoWarn>SKEXP0001;SKEXP0010;SKEXP0020</SKEXPNoWarn>
<NoWarn>$(NoWarn);$(CSNoWarn);$(SKEXPNoWarn);NU5104</NoWarn>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<IsPackable>false</IsPackable>
@ -32,10 +33,6 @@
<NoWarn>$(NoWarn);CA1829</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Text.Json" />
</ItemGroup>
<ItemGroup Condition="'$(IsTestProject)' == 'true'">
<PackageReference Include="ApprovalTests" />
<PackageReference Include="FluentAssertions" />

View File

@ -3,7 +3,9 @@
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<MicrosoftSemanticKernelVersion>1.22.0</MicrosoftSemanticKernelVersion>
<MicrosoftSemanticKernelExperimentalVersion>1.22.0-alpha</MicrosoftSemanticKernelExperimentalVersion>
<MicrosoftExtensionsAIVersion>9.0.0-preview.9.24507.7</MicrosoftExtensionsAIVersion>
<MicrosoftExtensionsAIVersion>9.0.0-preview.9.24525.1</MicrosoftExtensionsAIVersion>
<NuGetAuditMode>direct</NuGetAuditMode>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Aspire.Hosting" Version="9.0.0-rc.1.24511.1" />
@ -61,11 +63,17 @@
<PackageVersion Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="8.2.1" />
<PackageVersion Include="Microsoft.Orleans.Clustering.Cosmos" Version="8.2.0" />
<PackageVersion Include="Microsoft.Orleans.CodeGenerator" Version="8.2.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageVersion>
<PackageVersion Include="Microsoft.Orleans.Core.Abstractions" Version="8.2.0" />
<PackageVersion Include="Microsoft.Orleans.Persistence.Cosmos" Version="8.2.0" />
<PackageVersion Include="Microsoft.Orleans.Reminders" Version="8.2.0" />
<PackageVersion Include="Microsoft.Orleans.Reminders.Cosmos" Version="8.2.0" />
<PackageVersion Include="Microsoft.Orleans.Runtime" Version="8.2.0" />
<PackageVersion Include="Microsoft.Orleans.Sdk" Version="8.2.0" />
<PackageVersion Include="Microsoft.Orleans.Serialization" Version="8.2.0" />
<PackageVersion Include="Microsoft.Orleans.Serialization.Protobuf" Version="8.2.0" />
<PackageVersion Include="Microsoft.Orleans.Server" Version="8.2.0" />
<PackageVersion Include="Microsoft.Orleans.Streaming" Version="8.2.0" />
@ -111,6 +119,5 @@
<PackageVersion Include="Moq" Version="4.20.72" />
<PackageVersion Include="Microsoft.PowerShell.SDK" Version="7.4.5" />
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="8.0.10" />
<PackageVersion Include="System.Text.Json" Version="9.0.0-rc.2.24473.5" />
</ItemGroup>
</Project>
</Project>

View File

@ -2,7 +2,7 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VersionPrefix>0.2.2</VersionPrefix>
<Authors>AutoGen</Authors>
<Authors>Microsoft</Authors>
<PackageProjectUrl>https://microsoft.github.io/autogen-for-net/</PackageProjectUrl>
<RepositoryUrl>https://github.com/microsoft/autogen</RepositoryUrl>
<RepositoryType>git</RepositoryType>

View File

@ -3,7 +3,7 @@
<IsPackable>true</IsPackable>
<!-- Default description and tags. Packages can override. -->
<Authors>AutoGen</Authors>
<Authors>Microsoft</Authors>
<Company>Microsoft</Company>
<Product>AutoGen</Product>
<Description>A programming framework for agentic AI</Description>

View File

@ -15,5 +15,6 @@
<ProjectReference Include="..\..\src\AutoGen\AutoGen.csproj" />
<PackageReference Include="FluentAssertions" />
<PackageReference Include="Microsoft.SemanticKernel.Plugins.Web" />
<PackageReference Include="Microsoft.Extensions.AI" />
</ItemGroup>
</Project>

View File

@ -1,5 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// AgentCodeSnippet.cs
using AutoGen.Core;
namespace AutoGen.BasicSample.CodeSnippet;

View File

@ -1,5 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// UserProxyAgentCodeSnippet.cs
using AutoGen.Core;
namespace AutoGen.BasicSample.CodeSnippet;

View File

@ -6,6 +6,7 @@ using AutoGen.Core;
using AutoGen.OpenAI;
using AutoGen.OpenAI.Extension;
using FluentAssertions;
using Microsoft.Extensions.AI;
/// <summary>
/// This example shows how to add type-safe function call to an agent.
@ -37,13 +38,20 @@ public partial class Example03_Agent_FunctionCall
/// </summary>
/// <param name="price">price, should be an integer</param>
/// <param name="taxRate">tax rate, should be in range (0, 1)</param>
[FunctionAttribute]
[Function]
public async Task<string> CalculateTax(int price, float taxRate)
{
return $"tax is {price * taxRate}";
}
public static async Task RunAsync()
/// <summary>
/// This example shows how to add type-safe function call using AutoGen.SourceGenerator.
/// The SourceGenerator will automatically generate FunctionDefinition and FunctionCallWrapper during compiling time.
///
/// For adding type-safe function call from M.E.A.I tools, please refer to <see cref="ToolCallWithMEAITools"/>.
/// </summary>
/// <returns></returns>
public static async Task ToolCallWithSourceGenerator()
{
var instance = new Example03_Agent_FunctionCall();
var gpt4o = LLMConfiguration.GetOpenAIGPT4o_mini();
@ -101,4 +109,60 @@ public partial class Example03_Agent_FunctionCall
// send aggregate message back to llm to get the final result
var finalResult = await agent.SendAsync(calculateTaxes);
}
/// <summary>
/// This example shows how to add type-safe function call from M.E.A.I tools.
///
/// For adding type-safe function call from source generator, please refer to <see cref="ToolCallWithSourceGenerator"/>.
/// </summary>
public static async Task ToolCallWithMEAITools()
{
var gpt4o = LLMConfiguration.GetOpenAIGPT4o_mini();
var instance = new Example03_Agent_FunctionCall();
AIFunction[] tools = [
AIFunctionFactory.Create(instance.UpperCase),
AIFunctionFactory.Create(instance.ConcatString),
AIFunctionFactory.Create(instance.CalculateTax),
];
var toolCallMiddleware = new FunctionCallMiddleware(tools);
var agent = new OpenAIChatAgent(
chatClient: gpt4o,
name: "agent",
systemMessage: "You are a helpful AI assistant")
.RegisterMessageConnector()
.RegisterStreamingMiddleware(toolCallMiddleware)
.RegisterPrintMessage();
// talk to the assistant agent
var upperCase = await agent.SendAsync("convert to upper case: hello world");
upperCase.GetContent()?.Should().Be("HELLO WORLD");
upperCase.Should().BeOfType<ToolCallAggregateMessage>();
upperCase.GetToolCalls().Should().HaveCount(1);
upperCase.GetToolCalls().First().FunctionName.Should().Be(nameof(UpperCase));
var concatString = await agent.SendAsync("concatenate strings: a, b, c, d, e");
concatString.GetContent()?.Should().Be("a b c d e");
concatString.Should().BeOfType<ToolCallAggregateMessage>();
concatString.GetToolCalls().Should().HaveCount(1);
concatString.GetToolCalls().First().FunctionName.Should().Be(nameof(ConcatString));
var calculateTax = await agent.SendAsync("calculate tax: 100, 0.1");
calculateTax.GetContent().Should().Be("tax is 10");
calculateTax.Should().BeOfType<ToolCallAggregateMessage>();
calculateTax.GetToolCalls().Should().HaveCount(1);
calculateTax.GetToolCalls().First().FunctionName.Should().Be(nameof(CalculateTax));
// parallel function calls
var calculateTaxes = await agent.SendAsync("calculate tax: 100, 0.1; calculate tax: 200, 0.2");
calculateTaxes.GetContent().Should().Be("tax is 10\ntax is 40"); // "tax is 10\n tax is 40
calculateTaxes.Should().BeOfType<ToolCallAggregateMessage>();
calculateTaxes.GetToolCalls().Should().HaveCount(2);
calculateTaxes.GetToolCalls().First().FunctionName.Should().Be(nameof(CalculateTax));
// send aggregate message back to llm to get the final result
var finalResult = await agent.SendAsync(calculateTaxes);
}
}

View File

@ -1,5 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Example06_UserProxyAgent.cs
using AutoGen.Core;
using AutoGen.OpenAI;
using AutoGen.OpenAI.Extension;

View File

@ -1,4 +1,5 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Program.cs
//await Example07_Dynamic_GroupChat_Calculate_Fibonacci.RunAsync();
@ -10,7 +11,8 @@ var allSamples = new List<(string, Func<Task>)>
// When a new sample is created please add them to the allSamples collection
("Assistant Agent", Example01_AssistantAgent.RunAsync),
("Two-agent Math Chat", Example02_TwoAgent_MathChat.RunAsync),
("Agent Function Call", Example03_Agent_FunctionCall.RunAsync),
("Agent Function Call With Source Generator", Example03_Agent_FunctionCall.ToolCallWithSourceGenerator),
("Agent Function Call With M.E.A.I AI Functions", Example03_Agent_FunctionCall.ToolCallWithMEAITools),
("Dynamic Group Chat Coding Task", Example04_Dynamic_GroupChat_Coding_Task.RunAsync),
("DALL-E and GPT4v", Example05_Dalle_And_GPT4V.RunAsync),
("User Proxy Agent", Example06_UserProxyAgent.RunAsync),

View File

@ -1,4 +1,5 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Connect_To_Azure_OpenAI.cs
#region using_statement
using System.ClientModel;

View File

@ -0,0 +1,12 @@
{
"profiles": {
"AutoGen.WebAPI.Sample": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:50675;http://localhost:50676"
}
}
}

View File

@ -1,9 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Runtime\Microsoft.AutoGen.Runtime.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" />
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Agents\Microsoft.AutoGen.Agents.csproj" />
</ItemGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
@ -11,4 +8,8 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" />
</ItemGroup>
</Project>

View File

@ -1,5 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Program.cs
using Microsoft.Extensions.Hosting;
var app = await Microsoft.AutoGen.Runtime.Host.StartAsync(local: true);
var app = await Microsoft.AutoGen.Agents.Host.StartAsync(local: false, useGrpc: true);
await app.WaitForShutdownAsync();

View File

@ -0,0 +1,12 @@
{
"profiles": {
"Backend": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:53071;http://localhost:53072"
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft": "Warning",
"Microsoft.Orleans": "Warning"
}
}
}

View File

@ -1,5 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
@ -10,12 +9,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost"/>
<PackageReference Include="Aspire.Hosting"/>
<PackageReference Include="Aspire.Hosting.AppHost" />
<PackageReference Include="Aspire.Hosting" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Backend\Backend.csproj" />
<ProjectReference Include="..\HelloAgent\HelloAgent.csproj" />
</ItemGroup>
</Project>

View File

@ -1,4 +1,5 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Program.cs
var builder = DistributedApplication.CreateBuilder(args);
var backend = builder.AddProject<Projects.Backend>("backend");

View File

@ -0,0 +1,43 @@
{
"profiles": {
"https": {
"commandName": "Project",
"launchBrowser": true,
"dotnetRunMessages": true,
"applicationUrl": "https://localhost:15887;http://localhost:15888",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
//"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16037",
"DOTNET_DASHBOARD_OTLP_HTTP_ENDPOINT_URL": "https://localhost:16038",
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037",
"DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true"
}
},
"http": {
"commandName": "Project",
"launchBrowser": true,
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:15888",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
//"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16031",
"DOTNET_DASHBOARD_OTLP_HTTP_ENDPOINT_URL": "http://localhost:16032",
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17031",
"DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true",
"ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true"
}
},
"generate-manifest": {
"commandName": "Project",
"dotnetRunMessages": true,
"commandLineArgs": "--publisher manifest --output-path aspire-manifest.json",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development"
}
}
},
"$schema": "https://json.schemastore.org/launchsettings.json"
}

View File

@ -1,16 +1,20 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// HelloAIAgent.cs
using Microsoft.AutoGen.Abstractions;
using Microsoft.AutoGen.Agents;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
namespace Hello;
[TopicSubscription("HelloAgents")]
public class HelloAIAgent(
IAgentContext context,
IAgentRuntime context,
[FromKeyedServices("EventTypes")] EventTypes typeRegistry,
IHostApplicationLifetime hostApplicationLifetime,
IChatClient client) : HelloAgent(
context,
typeRegistry),
typeRegistry,
hostApplicationLifetime),
IHandle<NewMessageReceived>
{
// This Handle supercedes the one in the base class
@ -18,16 +22,10 @@ public class HelloAIAgent(
{
var prompt = "Please write a limerick greeting someone with the name " + item.Message;
var response = await client.CompleteAsync(prompt);
var evt = new Output
{
Message = response.Message.Text
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt).ConfigureAwait(false);
var goodbye = new ConversationClosed
{
UserId = this.AgentId.Key,
UserMessage = "Goodbye"
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(goodbye).ConfigureAwait(false);
var evt = new Output { Message = response.Message.Text };
await PublishMessageAsync(evt).ConfigureAwait(false);
var goodbye = new ConversationClosed { UserId = this.AgentId.Key, UserMessage = "Goodbye" };
await PublishMessageAsync(goodbye).ConfigureAwait(false);
}
}

View File

@ -1,16 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Abstractions\Microsoft.AutoGen.Abstractions.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Agents\Microsoft.AutoGen.Agents.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Runtime\Microsoft.AutoGen.Runtime.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Extensions\AIModelClientHostingExtensions\AIModelClientHostingExtensions.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" />
</ItemGroup>
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
@ -18,4 +6,13 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Abstractions\Microsoft.AutoGen.Abstractions.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Agents\Microsoft.AutoGen.Agents.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Extensions\AIModelClientHostingExtensions\AIModelClientHostingExtensions.csproj" />
</ItemGroup>
</Project>

View File

@ -1,9 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Program.cs
using Hello;
using Microsoft.AspNetCore.Builder;
using Microsoft.AutoGen.Abstractions;
using Microsoft.AutoGen.Agents;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
// send a message to the agent
var builder = WebApplication.CreateBuilder();
@ -32,8 +32,9 @@ namespace Hello
{
[TopicSubscription("HelloAgents")]
public class HelloAgent(
IAgentContext context,
[FromKeyedServices("EventTypes")] EventTypes typeRegistry) : ConsoleAgent(
IAgentRuntime context,
[FromKeyedServices("EventTypes")] EventTypes typeRegistry,
IHostApplicationLifetime hostApplicationLifetime) : ConsoleAgent(
context,
typeRegistry),
ISayHello,
@ -46,14 +47,14 @@ namespace Hello
var evt = new Output
{
Message = response
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt).ConfigureAwait(false);
};
await PublishMessageAsync(evt).ConfigureAwait(false);
var goodbye = new ConversationClosed
{
UserId = this.AgentId.Key,
UserMessage = "Goodbye"
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(goodbye).ConfigureAwait(false);
};
await PublishMessageAsync(goodbye).ConfigureAwait(false);
}
public async Task Handle(ConversationClosed item)
{
@ -61,11 +62,11 @@ namespace Hello
var evt = new Output
{
Message = goodbye
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt).ConfigureAwait(false);
};
await PublishMessageAsync(evt).ConfigureAwait(false);
//sleep30 seconds
await Task.Delay(30000).ConfigureAwait(false);
await AgentsApp.ShutdownAsync().ConfigureAwait(false);
hostApplicationLifetime.StopApplication();
}
public async Task<string> SayHello(string ask)

View File

@ -0,0 +1,12 @@
{
"profiles": {
"HelloAIAgents": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:53139;http://localhost:53140"
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft": "Warning",
"Microsoft.Orleans": "Warning"
}
}
}

View File

@ -1,16 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Abstractions\Microsoft.AutoGen.Abstractions.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Agents\Microsoft.AutoGen.Agents.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Runtime\Microsoft.AutoGen.Runtime.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" />
<PackageReference Include="Aspire.Hosting.AppHost" />
</ItemGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
@ -18,4 +6,13 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" />
<PackageReference Include="Aspire.Hosting.AppHost" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Abstractions\Microsoft.AutoGen.Abstractions.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Agents\Microsoft.AutoGen.Agents.csproj" />
</ItemGroup>
</Project>

View File

@ -1,15 +1,24 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Program.cs
using Microsoft.AutoGen.Abstractions;
using Microsoft.AutoGen.Agents;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
// send a message to the agent
// step 1: create in-memory agent runtime
// step 2: register HelloAgent to that agent runtime
// step 3: start the agent runtime
// step 4: send a message to the agent
// step 5: wait for the agent runtime to shutdown
var app = await AgentsApp.PublishMessageAsync("HelloAgents", new NewMessageReceived
{
Message = "World"
}, local: false);
}, local: true);
await app.WaitForShutdownAsync();
@ -17,28 +26,26 @@ namespace Hello
{
[TopicSubscription("HelloAgents")]
public class HelloAgent(
IAgentContext context,
[FromKeyedServices("EventTypes")] EventTypes typeRegistry) : ConsoleAgent(
IAgentRuntime context, IHostApplicationLifetime hostApplicationLifetime,
[FromKeyedServices("EventTypes")] EventTypes typeRegistry) : AgentBase(
context,
typeRegistry),
ISayHello,
IHandleConsole,
IHandle<NewMessageReceived>,
IHandle<ConversationClosed>
{
public async Task Handle(NewMessageReceived item)
{
var response = await SayHello(item.Message).ConfigureAwait(false);
var evt = new Output
{
Message = response
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt).ConfigureAwait(false);
var evt = new Output { Message = response };
await PublishMessageAsync(evt).ConfigureAwait(false);
var goodbye = new ConversationClosed
{
UserId = this.AgentId.Key,
UserMessage = "Goodbye"
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(goodbye).ConfigureAwait(false);
};
await PublishMessageAsync(goodbye).ConfigureAwait(false);
}
public async Task Handle(ConversationClosed item)
{
@ -46,13 +53,13 @@ namespace Hello
var evt = new Output
{
Message = goodbye
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt).ConfigureAwait(false);
//sleep
await Task.Delay(10000).ConfigureAwait(false);
await AgentsApp.ShutdownAsync().ConfigureAwait(false);
};
await PublishMessageAsync(evt).ConfigureAwait(false);
// Signal shutdown.
hostApplicationLifetime.StopApplication();
}
public async Task<string> SayHello(string ask)
{
var response = $"\n\n\n\n***************Hello {ask}**********************\n\n\n\n";

View File

@ -0,0 +1,12 @@
{
"profiles": {
"HelloAgent": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:53113;http://localhost:53114"
}
}
}

View File

@ -25,11 +25,11 @@ Flow Diagram:
```mermaid
%%{init: {'theme':'forest'}}%%
graph LR;
A[Main] --> |"PublishEvent(NewMessage('World'))"| B{"Handle(NewMessageReceived item)"}
B --> |"PublishEvent(Output('***Hello, World***'))"| C[ConsoleAgent]
A[Main] --> |"PublishEventAsync(NewMessage('World'))"| B{"Handle(NewMessageReceived item)"}
B --> |"PublishEventAsync(Output('***Hello, World***'))"| C[ConsoleAgent]
C --> D{"WriteConsole()"}
B --> |"PublishEvent(ConversationClosed('Goodbye'))"| E{"Handle(ConversationClosed item)"}
B --> |"PublishEvent(Output('***Goodbye***'))"| C
B --> |"PublishEventAsync(ConversationClosed('Goodbye'))"| E{"Handle(ConversationClosed item)"}
B --> |"PublishEventAsync(Output('***Goodbye***'))"| C
E --> F{"Shutdown()"}
```
@ -58,13 +58,13 @@ public class HelloAgent(
{
Message = response
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt).ConfigureAwait(false);
await PublishEventAsync(evt).ConfigureAwait(false);
var goodbye = new ConversationClosed
{
UserId = this.AgentId.Key,
UserMessage = "Goodbye"
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(goodbye).ConfigureAwait(false);
await PublishEventAsync(goodbye).ConfigureAwait(false);
}
```
@ -109,7 +109,6 @@ message ReadmeRequested {
}
```
```xml
<ItemGroup>
<PackageReference Include="Google.Protobuf" />
@ -118,4 +117,4 @@ message ReadmeRequested {
</ItemGroup>
```
You can send messages using the [```Microsoft.AutoGen.Agents.AgentClient``` class](autogen/dotnet/src/Microsoft.AutoGen/Agents/AgentClient.cs). Messages are wrapped in [the CloudEvents specification](https://cloudevents.io) and sent to the event bus.
You can send messages using the [```Microsoft.AutoGen.Agents.AgentWorker``` class](autogen/dotnet/src/Microsoft.AutoGen/Agents/AgentWorker.cs). Messages are wrapped in [the CloudEvents specification](https://cloudevents.io) and sent to the event bus.

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft": "Warning",
"Microsoft.Orleans": "Warning"
}
}
}

View File

@ -1,16 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Abstractions\Microsoft.AutoGen.Abstractions.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Agents\Microsoft.AutoGen.Agents.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Runtime\Microsoft.AutoGen.Runtime.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" />
<PackageReference Include="Aspire.Hosting.AppHost" />
</ItemGroup>
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
@ -18,4 +6,13 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" />
<PackageReference Include="Aspire.Hosting.AppHost" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Abstractions\Microsoft.AutoGen.Abstractions.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Agents\Microsoft.AutoGen.Agents.csproj" />
</ItemGroup>
</Project>

View File

@ -1,15 +1,15 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Program.cs
using System.Text.Json;
using Microsoft.AutoGen.Abstractions;
using Microsoft.AutoGen.Agents;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
// send a message to the agent
var app = await AgentsApp.PublishMessageAsync("HelloAgents", new NewMessageReceived
{
Message = "World"
}, local: false);
}, local: true);
await app.WaitForShutdownAsync();
@ -17,13 +17,15 @@ namespace Hello
{
[TopicSubscription("HelloAgents")]
public class HelloAgent(
IAgentContext context,
[FromKeyedServices("EventTypes")] EventTypes typeRegistry) : ConsoleAgent(
IAgentRuntime context,
IHostApplicationLifetime hostApplicationLifetime,
[FromKeyedServices("EventTypes")] EventTypes typeRegistry) : AgentBase(
context,
typeRegistry),
ISayHello,
IHandleConsole,
IHandle<NewMessageReceived>,
IHandle<ConversationClosed>
IHandle<ConversationClosed>,
IHandle<Shutdown>
{
private AgentState? State { get; set; }
public async Task Handle(NewMessageReceived item)
@ -32,35 +34,58 @@ namespace Hello
var evt = new Output
{
Message = response
}.ToCloudEvent(this.AgentId.Key);
var entry = "We said hello to " + item.Message;
await Store(new AgentState
};
Dictionary<string, string> state = new()
{
{ "data", "We said hello to " + item.Message },
{ "workflow", "Active" }
};
await StoreAsync(new AgentState
{
AgentId = this.AgentId,
TextData = entry
TextData = JsonSerializer.Serialize(state)
}).ConfigureAwait(false);
await PublishEvent(evt).ConfigureAwait(false);
await PublishMessageAsync(evt).ConfigureAwait(false);
var goodbye = new ConversationClosed
{
UserId = this.AgentId.Key,
UserMessage = "Goodbye"
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(goodbye).ConfigureAwait(false);
};
await PublishMessageAsync(goodbye).ConfigureAwait(false);
// send the shutdown message
await PublishMessageAsync(new Shutdown { Message = this.AgentId.Key }).ConfigureAwait(false);
}
public async Task Handle(ConversationClosed item)
{
State = await Read<AgentState>(this.AgentId).ConfigureAwait(false);
var read = State?.TextData ?? "No state data found";
var goodbye = $"{read}\n********************* {item.UserId} said {item.UserMessage} ************************";
State = await ReadAsync<AgentState>(this.AgentId).ConfigureAwait(false);
var state = JsonSerializer.Deserialize<Dictionary<string, string>>(State.TextData) ?? new Dictionary<string, string> { { "data", "No state data found" } };
var goodbye = $"\nState: {state}\n********************* {item.UserId} said {item.UserMessage} ************************";
var evt = new Output
{
Message = goodbye
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt).ConfigureAwait(false);
//sleep
await Task.Delay(10000).ConfigureAwait(false);
await AgentsApp.ShutdownAsync().ConfigureAwait(false);
};
await PublishMessageAsync(evt).ConfigureAwait(true);
state["workflow"] = "Complete";
await StoreAsync(new AgentState
{
AgentId = this.AgentId,
TextData = JsonSerializer.Serialize(state)
}).ConfigureAwait(false);
}
public async Task Handle(Shutdown item)
{
string? workflow = null;
// make sure the workflow is finished
while (workflow != "Complete")
{
State = await ReadAsync<AgentState>(this.AgentId).ConfigureAwait(true);
var state = JsonSerializer.Deserialize<Dictionary<string, string>>(State?.TextData ?? "{}") ?? new Dictionary<string, string>();
workflow = state["workflow"];
await Task.Delay(1000).ConfigureAwait(true);
}
// now we can shut down...
hostApplicationLifetime.StopApplication();
}
public async Task<string> SayHello(string ask)
{
@ -68,8 +93,4 @@ namespace Hello
return response;
}
}
public interface ISayHello
{
public Task<string> SayHello(string ask);
}
}

View File

@ -0,0 +1,12 @@
{
"profiles": {
"HelloAgentState": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:53136;http://localhost:53137"
}
}
}

View File

@ -25,11 +25,11 @@ Flow Diagram:
```mermaid
%%{init: {'theme':'forest'}}%%
graph LR;
A[Main] --> |"PublishEvent(NewMessage('World'))"| B{"Handle(NewMessageReceived item)"}
B --> |"PublishEvent(Output('***Hello, World***'))"| C[ConsoleAgent]
A[Main] --> |"PublishEventAsync(NewMessage('World'))"| B{"Handle(NewMessageReceived item)"}
B --> |"PublishEventAsync(Output('***Hello, World***'))"| C[ConsoleAgent]
C --> D{"WriteConsole()"}
B --> |"PublishEvent(ConversationClosed('Goodbye'))"| E{"Handle(ConversationClosed item)"}
B --> |"PublishEvent(Output('***Goodbye***'))"| C
B --> |"PublishEventAsync(ConversationClosed('Goodbye'))"| E{"Handle(ConversationClosed item)"}
B --> |"PublishEventAsync(Output('***Goodbye***'))"| C
E --> F{"Shutdown()"}
```
@ -58,13 +58,13 @@ public class HelloAgent(
{
Message = response
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt).ConfigureAwait(false);
await PublishEventAsync(evt).ConfigureAwait(false);
var goodbye = new ConversationClosed
{
UserId = this.AgentId.Key,
UserMessage = "Goodbye"
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(goodbye).ConfigureAwait(false);
await PublishEventAsync(goodbye).ConfigureAwait(false);
}
```
@ -117,7 +117,7 @@ message ReadmeRequested {
</ItemGroup>
```
You can send messages using the [```Microsoft.AutoGen.Agents``` class](autogen/dotnet/src/Microsoft.AutoGen/Agents/AgentClient.cs). Messages are wrapped in [the CloudEvents specification](https://cloudevents.io) and sent to the event bus.
You can send messages using the [```Microsoft.AutoGen.Agents.AgentWorker``` class](autogen/dotnet/src/Microsoft.AutoGen/Agents/AgentWorker.cs). Messages are wrapped in [the CloudEvents specification](https://cloudevents.io) and sent to the event bus.
### Managing State

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft": "Warning",
"Microsoft.Orleans": "Warning"
}
}
}

View File

@ -9,8 +9,8 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="../../../src/Microsoft.AutoGen/Runtime/Microsoft.AutoGen.Runtime.csproj" />
<ProjectReference Include="../../../src/Microsoft.AutoGen/ServiceDefaults/Microsoft.AutoGen.ServiceDefaults.csproj" />
<ProjectReference Include="../../../src/Microsoft.AutoGen/Agents/Microsoft.AutoGen.Agents.csproj" />
<ProjectReference Include="../../../src/Microsoft.AutoGen/Extensions/ServiceDefaults/Microsoft.AutoGen.ServiceDefaults.csproj" />
</ItemGroup>
</Project>

View File

@ -1,4 +1,7 @@
using Microsoft.AutoGen.Runtime;
// Copyright (c) Microsoft Corporation. All rights reserved.
// Program.cs
using Microsoft.AutoGen.Agents;
var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();

View File

@ -0,0 +1,12 @@
{
"profiles": {
"DevTeam.AgentHost": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:50670;http://localhost:50673"
}
}
}

View File

@ -7,10 +7,10 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="../../../src/Microsoft.AutoGen/Agents/Microsoft.AutoGen.Agents.csproj" />
<ProjectReference Include="../../../src/Microsoft.AutoGen/ServiceDefaults/Microsoft.AutoGen.ServiceDefaults.csproj" />
<ProjectReference Include="../../../src/Microsoft.AutoGen/Extensions/ServiceDefaults/Microsoft.AutoGen.ServiceDefaults.csproj" />
<ProjectReference Include="..\DevTeam.Shared\DevTeam.Shared.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Extensions\SemanticKernel\Microsoft.AutoGen.Extensions.SemanticKernel.csproj" />
</ItemGroup>

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Developer.cs
using DevTeam.Shared;
using Microsoft.AutoGen.Abstractions;
using Microsoft.AutoGen.Agents;
@ -7,7 +10,7 @@ using Microsoft.SemanticKernel.Memory;
namespace DevTeam.Agents;
[TopicSubscription("devteam")]
public class Dev(IAgentContext context, Kernel kernel, ISemanticTextMemory memory, [FromKeyedServices("EventTypes")] EventTypes typeRegistry, ILogger<Dev> logger)
public class Dev(IAgentRuntime context, Kernel kernel, ISemanticTextMemory memory, [FromKeyedServices("EventTypes")] EventTypes typeRegistry, ILogger<Dev> logger)
: SKAiAgent<DeveloperState>(context, memory, kernel, typeRegistry), IDevelopApps,
IHandle<CodeGenerationRequested>,
IHandle<CodeChainClosed>
@ -21,8 +24,8 @@ public class Dev(IAgentContext context, Kernel kernel, ISemanticTextMemory memor
Repo = item.Repo,
IssueNumber = item.IssueNumber,
Code = code
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt);
};
await PublishMessageAsync(evt);
}
public async Task Handle(CodeChainClosed item)
@ -32,8 +35,8 @@ public class Dev(IAgentContext context, Kernel kernel, ISemanticTextMemory memor
var evt = new CodeCreated
{
Code = lastCode
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt);
};
await PublishMessageAsync(evt);
}
public async Task<string> GenerateCode(string ask)

View File

@ -1,3 +1,5 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// DeveloperPrompts.cs
namespace DevTeam.Agents;
public static class DeveloperSkills

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// DeveloperLead.cs
using DevTeam.Shared;
using Microsoft.AutoGen.Abstractions;
using Microsoft.AutoGen.Agents;
@ -8,7 +11,7 @@ using Microsoft.SemanticKernel.Memory;
namespace DevTeam.Agents;
[TopicSubscription("devteam")]
public class DeveloperLead(IAgentContext context, Kernel kernel, ISemanticTextMemory memory, [FromKeyedServices("EventTypes")] EventTypes typeRegistry, ILogger<DeveloperLead> logger)
public class DeveloperLead(IAgentRuntime context, Kernel kernel, ISemanticTextMemory memory, [FromKeyedServices("EventTypes")] EventTypes typeRegistry, ILogger<DeveloperLead> logger)
: SKAiAgent<DeveloperLeadState>(context, memory, kernel, typeRegistry), ILeadDevelopers,
IHandle<DevPlanRequested>,
IHandle<DevPlanChainClosed>
@ -22,8 +25,8 @@ public class DeveloperLead(IAgentContext context, Kernel kernel, ISemanticTextMe
Repo = item.Repo,
IssueNumber = item.IssueNumber,
Plan = plan
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt);
};
await PublishMessageAsync(evt);
}
public async Task Handle(DevPlanChainClosed item)
@ -33,8 +36,8 @@ public class DeveloperLead(IAgentContext context, Kernel kernel, ISemanticTextMe
var evt = new DevPlanCreated
{
Plan = lastPlan
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt);
};
await PublishMessageAsync(evt);
}
public async Task<string> CreatePlan(string ask)
{

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// DeveloperLeadPrompts.cs
namespace DevTeam.Agents;
public static class DevLeadSkills
{

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// PMPrompts.cs
namespace DevTeam.Agents;
public static class PMSkills
{

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// ProductManager.cs
using DevTeam.Shared;
using Microsoft.AutoGen.Abstractions;
using Microsoft.AutoGen.Agents;
@ -7,7 +10,7 @@ using Microsoft.SemanticKernel.Memory;
namespace DevTeam.Agents;
[TopicSubscription("devteam")]
public class ProductManager(IAgentContext context, Kernel kernel, ISemanticTextMemory memory, [FromKeyedServices("EventTypes")] EventTypes typeRegistry, ILogger<ProductManager> logger)
public class ProductManager(IAgentRuntime context, Kernel kernel, ISemanticTextMemory memory, [FromKeyedServices("EventTypes")] EventTypes typeRegistry, ILogger<ProductManager> logger)
: SKAiAgent<ProductManagerState>(context, memory, kernel, typeRegistry), IManageProducts,
IHandle<ReadmeChainClosed>,
IHandle<ReadmeRequested>
@ -19,8 +22,8 @@ public class ProductManager(IAgentContext context, Kernel kernel, ISemanticTextM
var evt = new ReadmeCreated
{
Readme = lastReadme
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt);
};
await PublishMessageAsync(evt);
}
public async Task Handle(ReadmeRequested item)
@ -32,8 +35,8 @@ public class ProductManager(IAgentContext context, Kernel kernel, ISemanticTextM
Org = item.Org,
Repo = item.Repo,
IssueNumber = item.IssueNumber
}.ToCloudEvent(this.AgentId.Key);
await PublishEvent(evt);
};
await PublishMessageAsync(evt);
}
public async Task<string> CreateReadme(string ask)

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Program.cs
using DevTeam.Agents;
using Microsoft.AutoGen.Agents;
using Microsoft.AutoGen.Extensions.SemanticKernel;

View File

@ -0,0 +1,12 @@
{
"profiles": {
"DevTeam.Agents": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:50669;http://localhost:50671"
}
}
}

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Program.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureProvisioning();

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// AzureGenie.cs
using DevTeam.Backend;
using DevTeam.Shared;
using Microsoft.AutoGen.Abstractions;
@ -6,7 +9,7 @@ using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Memory;
namespace Microsoft.AI.DevTeam;
public class AzureGenie(IAgentContext context, Kernel kernel, ISemanticTextMemory memory, [FromKeyedServices("EventTypes")] EventTypes typeRegistry, IManageAzure azureService)
public class AzureGenie(IAgentRuntime context, Kernel kernel, ISemanticTextMemory memory, [FromKeyedServices("EventTypes")] EventTypes typeRegistry, IManageAzure azureService)
: SKAiAgent<object>(context, memory, kernel, typeRegistry),
IHandle<ReadmeCreated>,
IHandle<CodeCreated>
@ -17,7 +20,7 @@ public class AzureGenie(IAgentContext context, Kernel kernel, ISemanticTextMemor
// TODO: Not sure we need to store the files if we use ACA Sessions
// //var data = item.ToData();
// // await Store(data["org"], data["repo"], data.TryParseLong("parentNumber"), data.TryParseLong("issueNumber"), "readme", "md", "output", data["readme"]);
// await PublishEvent(new Event
// await PublishEventAsync(new Event
// {
// Namespace = item.Namespace,
// Type = nameof(EventTypes.ReadmeStored),
@ -33,7 +36,7 @@ public class AzureGenie(IAgentContext context, Kernel kernel, ISemanticTextMemor
// //var data = item.ToData();
// // await Store(data["org"], data["repo"], data.TryParseLong("parentNumber"), data.TryParseLong("issueNumber"), "run", "sh", "output", data["code"]);
// // await RunInSandbox(data["org"], data["repo"], data.TryParseLong("parentNumber"), data.TryParseLong("issueNumber"));
// await PublishEvent(new Event
// await PublishEventAsync(new Event
// {
// Namespace = item.Namespace,
// Type = nameof(EventTypes.SandboxRunCreated),

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Hubber.cs
using System.Text.Json;
using DevTeam;
using DevTeam.Backend;
@ -9,7 +12,7 @@ using Microsoft.SemanticKernel.Memory;
namespace Microsoft.AI.DevTeam;
public class Hubber(IAgentContext context, Kernel kernel, ISemanticTextMemory memory, [FromKeyedServices("EventTypes")] EventTypes typeRegistry, IManageGithub ghService)
public class Hubber(IAgentRuntime context, Kernel kernel, ISemanticTextMemory memory, [FromKeyedServices("EventTypes")] EventTypes typeRegistry, IManageGithub ghService)
: SKAiAgent<object>(context, memory, kernel, typeRegistry),
IHandle<NewAsk>,
IHandle<ReadmeGenerated>,

View File

@ -1,7 +1,5 @@
// TODO: Reimplement using ACA Sessions
// using DevTeam.Events;
// using Microsoft.AutoGen.Abstractions;
// using Microsoft.AutoGen.Agents;
// Copyright (c) Microsoft Corporation. All rights reserved.
// Sandbox.cs
// namespace DevTeam.Backend;
@ -52,7 +50,7 @@
// if (await _azService.IsSandboxCompleted(sandboxId))
// {
// await _azService.DeleteSandbox(sandboxId);
// await PublishEvent(new Event
// await PublishEventAsync(new Event
// {
// Namespace = this.GetPrimaryKeyString(),
// Type = nameof(GithubFlowEventType.SandboxRunFinished),

View File

@ -29,7 +29,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../../../src/Microsoft.AutoGen/ServiceDefaults/Microsoft.AutoGen.ServiceDefaults.csproj" />
<ProjectReference Include="../../../src/Microsoft.AutoGen/Extensions/ServiceDefaults/Microsoft.AutoGen.ServiceDefaults.csproj" />
<ProjectReference Include="..\DevTeam.Shared\DevTeam.Shared.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Extensions\SemanticKernel\Microsoft.AutoGen.Extensions.SemanticKernel.csproj" />
</ItemGroup>

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Program.cs
using Azure.Identity;
using DevTeam.Backend;
using DevTeam.Options;
@ -23,7 +26,7 @@ builder.AddAgentWorker(builder.Configuration["AGENT_HOST"]!)
//.AddAgent<Sandbox>(nameof(Sandbox))
.AddAgent<Hubber>(nameof(Hubber));
builder.Services.AddSingleton<AgentClient>();
builder.Services.AddSingleton<AgentWorker>();
builder.Services.AddSingleton<WebhookEventProcessor, GithubWebHookProcessor>();
builder.Services.AddSingleton<GithubAuthService>();
builder.Services.AddSingleton<IManageAzure, AzureService>();

View File

@ -0,0 +1,12 @@
{
"profiles": {
"DevTeam.Backend": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:50672;http://localhost:50674"
}
}
}

View File

@ -1,3 +1,5 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// AzureService.cs
using System.Text;
using Azure;

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// GithubAuthService.cs
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// GithubService.cs
using System.Text;
using Azure.Storage.Files.Shares;
using DevTeam.Options;

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// GithubWebHookProcessor.cs
using System.Globalization;
using DevTeam.Shared;
using Microsoft.AutoGen.Abstractions;
@ -10,10 +13,10 @@ using Octokit.Webhooks.Models;
namespace DevTeam.Backend;
public sealed class GithubWebHookProcessor(ILogger<GithubWebHookProcessor> logger, AgentClient client) : WebhookEventProcessor
public sealed class GithubWebHookProcessor(ILogger<GithubWebHookProcessor> logger, AgentWorker client) : WebhookEventProcessor
{
private readonly ILogger<GithubWebHookProcessor> _logger = logger;
private readonly AgentClient _client = client;
private readonly AgentWorker _client = client;
protected override async Task ProcessIssuesWebhookAsync(WebhookHeaders headers, IssuesEvent issuesEvent, IssuesAction action)
{

View File

@ -1,4 +1,5 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// EventExtensions.cs
using System.Globalization;
using Microsoft.AutoGen.Abstractions;

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// DevPlan.cs
namespace DevTeam;
public class DevLeadPlan
{

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// AzureOptions.cs
using System.ComponentModel.DataAnnotations;
namespace DevTeam.Options;

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// GithubOptions.cs
using System.ComponentModel.DataAnnotations;
namespace DevTeam.Options;

View File

@ -1,4 +1,5 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// ParseExtensions.cs
namespace DevTeam;

View File

@ -1,5 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// ChatCompletionRequest.cs
using System.Collections.Generic;
using System.Text.Json.Serialization;

View File

@ -17,6 +17,7 @@
<ItemGroup>
<PackageReference Include="JsonSchema.Net.Generation" />
<PackageReference Include="System.Memory.Data" />
<PackageReference Include="Microsoft.Extensions.AI.Abstractions" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">

View File

@ -1,4 +1,5 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// AgentExtension.cs
using System;
using System.Collections.Generic;

View File

@ -3,6 +3,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
using Microsoft.Extensions.AI;
namespace AutoGen.Core;
@ -22,6 +25,10 @@ public class FunctionAttribute : Attribute
public class FunctionContract
{
private const string NamespaceKey = nameof(Namespace);
private const string ClassNameKey = nameof(ClassName);
/// <summary>
/// The namespace of the function.
/// </summary>
@ -52,6 +59,7 @@ public class FunctionContract
/// <summary>
/// The return type of the function.
/// </summary>
[JsonIgnore]
public Type? ReturnType { get; set; }
/// <summary>
@ -60,6 +68,39 @@ public class FunctionContract
/// Otherwise, the description will be null.
/// </summary>
public string? ReturnDescription { get; set; }
public static implicit operator FunctionContract(AIFunctionMetadata metadata)
{
return new FunctionContract
{
Namespace = metadata.AdditionalProperties.ContainsKey(NamespaceKey) ? metadata.AdditionalProperties[NamespaceKey] as string : null,
ClassName = metadata.AdditionalProperties.ContainsKey(ClassNameKey) ? metadata.AdditionalProperties[ClassNameKey] as string : null,
Name = metadata.Name,
Description = metadata.Description,
Parameters = metadata.Parameters?.Select(p => (FunctionParameterContract)p).ToList(),
ReturnType = metadata.ReturnParameter.ParameterType,
ReturnDescription = metadata.ReturnParameter.Description,
};
}
public static implicit operator AIFunctionMetadata(FunctionContract contract)
{
return new AIFunctionMetadata(contract.Name)
{
Description = contract.Description,
ReturnParameter = new AIFunctionReturnParameterMetadata()
{
Description = contract.ReturnDescription,
ParameterType = contract.ReturnType,
},
AdditionalProperties = new Dictionary<string, object?>
{
[NamespaceKey] = contract.Namespace,
[ClassNameKey] = contract.ClassName,
},
Parameters = [.. contract.Parameters?.Select(p => (AIFunctionParameterMetadata)p)],
};
}
}
public class FunctionParameterContract
@ -79,6 +120,7 @@ public class FunctionParameterContract
/// <summary>
/// The type of the parameter.
/// </summary>
[JsonIgnore]
public Type? ParameterType { get; set; }
/// <summary>
@ -90,4 +132,29 @@ public class FunctionParameterContract
/// The default value of the parameter.
/// </summary>
public object? DefaultValue { get; set; }
// convert to/from FunctionParameterMetadata
public static implicit operator FunctionParameterContract(AIFunctionParameterMetadata metadata)
{
return new FunctionParameterContract
{
Name = metadata.Name,
Description = metadata.Description,
ParameterType = metadata.ParameterType,
IsRequired = metadata.IsRequired,
DefaultValue = metadata.DefaultValue,
};
}
public static implicit operator AIFunctionParameterMetadata(FunctionParameterContract contract)
{
return new AIFunctionParameterMetadata(contract.Name!)
{
DefaultValue = contract.DefaultValue,
Description = contract.Description,
IsRequired = contract.IsRequired,
ParameterType = contract.ParameterType,
HasDefaultValue = contract.DefaultValue != null,
};
}
}

View File

@ -1,4 +1,5 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// GroupChat.cs
using System;
using System.Collections.Generic;

View File

@ -5,8 +5,10 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.AI;
namespace AutoGen.Core;
@ -43,6 +45,19 @@ public class FunctionCallMiddleware : IStreamingMiddleware
this.functionMap = functionMap;
}
/// <summary>
/// Create a new instance of <see cref="FunctionCallMiddleware"/> with a list of <see cref="AIFunction"/>.
/// </summary>
/// <param name="functions">function list</param>
/// <param name="name">optional middleware name. If not provided, the class name <see cref="FunctionCallMiddleware"/> will be used.</param>
public FunctionCallMiddleware(IEnumerable<AIFunction> functions, string? name = null)
{
this.Name = name ?? nameof(FunctionCallMiddleware);
this.functions = functions.Select(f => (FunctionContract)f.Metadata).ToArray();
this.functionMap = functions.Select(f => (f.Metadata.Name, this.AIToolInvokeWrapper(f.InvokeAsync))).ToDictionary(f => f.Name, f => f.Item2);
}
public string? Name { get; }
public async Task<IMessage> InvokeAsync(MiddlewareContext context, IAgent agent, CancellationToken cancellationToken = default)
@ -173,4 +188,20 @@ public class FunctionCallMiddleware : IStreamingMiddleware
return toolCallMsg;
}
}
private Func<string, Task<string>> AIToolInvokeWrapper(Func<IEnumerable<KeyValuePair<string, object?>>?, CancellationToken, Task<object?>> lambda)
{
return async (string args) =>
{
var arguments = JsonSerializer.Deserialize<Dictionary<string, object?>>(args);
var result = await lambda(arguments, CancellationToken.None);
return result switch
{
string s => s,
JsonElement e => e.ToString(),
_ => JsonSerializer.Serialize(result),
};
};
}
}

View File

@ -5,45 +5,44 @@ using System;
using System.Collections.Generic;
using System.Linq;
namespace AutoGen
namespace AutoGen;
public static class LLMConfigAPI
{
public static class LLMConfigAPI
public static IEnumerable<ILLMConfig> GetOpenAIConfigList(
string apiKey,
IEnumerable<string>? modelIDs = null)
{
public static IEnumerable<ILLMConfig> GetOpenAIConfigList(
string apiKey,
IEnumerable<string>? modelIDs = null)
var models = modelIDs ?? new[]
{
var models = modelIDs ?? new[]
{
"gpt-3.5-turbo",
"gpt-3.5-turbo-16k",
"gpt-4",
"gpt-4-32k",
"gpt-4-0613",
"gpt-4-32k-0613",
"gpt-4-1106-preview",
};
"gpt-3.5-turbo",
"gpt-3.5-turbo-16k",
"gpt-4",
"gpt-4-32k",
"gpt-4-0613",
"gpt-4-32k-0613",
"gpt-4-1106-preview",
};
return models.Select(modelId => new OpenAIConfig(apiKey, modelId));
}
return models.Select(modelId => new OpenAIConfig(apiKey, modelId));
}
public static IEnumerable<ILLMConfig> GetAzureOpenAIConfigList(
string endpoint,
string apiKey,
IEnumerable<string> deploymentNames)
{
return deploymentNames.Select(deploymentName => new AzureOpenAIConfig(endpoint, deploymentName, apiKey));
}
public static IEnumerable<ILLMConfig> GetAzureOpenAIConfigList(
string endpoint,
string apiKey,
IEnumerable<string> deploymentNames)
{
return deploymentNames.Select(deploymentName => new AzureOpenAIConfig(endpoint, deploymentName, apiKey));
}
/// <summary>
/// Get a list of LLMConfig objects from a JSON file.
/// </summary>
internal static IEnumerable<ILLMConfig> ConfigListFromJson(
string filePath,
IEnumerable<string>? filterModels = null)
{
// Disable this API from documentation for now.
throw new NotImplementedException();
}
/// <summary>
/// Get a list of LLMConfig objects from a JSON file.
/// </summary>
internal static IEnumerable<ILLMConfig> ConfigListFromJson(
string filePath,
IEnumerable<string>? filterModels = null)
{
// Disable this API from documentation for now.
throw new NotImplementedException();
}
}

View File

@ -1,5 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// LMStudioConfig.cs
using System;
using System.ClientModel;
using OpenAI;

View File

@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// AgentId.cs
namespace Microsoft.AutoGen.Abstractions;
public partial class AgentId
{
public AgentId(string type, string key)
{
Type = type;
Key = key;
}
}

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// ChatHistoryItem.cs
namespace Microsoft.AutoGen.Abstractions;
[Serializable]

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// ChatState.cs
using Google.Protobuf;
namespace Microsoft.AutoGen.Abstractions;

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// ChatUserType.cs
namespace Microsoft.AutoGen.Abstractions;
public enum ChatUserType

View File

@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// IAgentBase.cs
using Google.Protobuf;
namespace Microsoft.AutoGen.Abstractions;
public interface IAgentBase
{
// Properties
AgentId AgentId { get; }
IAgentRuntime Context { get; }
// Methods
Task CallHandler(CloudEvent item);
Task<RpcResponse> HandleRequest(RpcRequest request);
void ReceiveMessage(Message message);
Task StoreAsync(AgentState state, CancellationToken cancellationToken = default);
Task<T> ReadAsync<T>(AgentId agentId, CancellationToken cancellationToken = default) where T : IMessage, new();
ValueTask PublishEventAsync(CloudEvent item, CancellationToken cancellationToken = default);
ValueTask PublishEventAsync(string topic, IMessage evt, CancellationToken cancellationToken = default);
}

View File

@ -0,0 +1,21 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// IAgentRuntime.cs
using System.Diagnostics;
namespace Microsoft.AutoGen.Abstractions;
public interface IAgentRuntime
{
AgentId AgentId { get; }
IAgentBase? AgentInstance { get; set; }
ValueTask StoreAsync(AgentState value, CancellationToken cancellationToken = default);
ValueTask<AgentState> ReadAsync(AgentId agentId, CancellationToken cancellationToken = default);
ValueTask SendResponseAsync(RpcRequest request, RpcResponse response, CancellationToken cancellationToken = default);
ValueTask SendRequestAsync(IAgentBase agent, RpcRequest request, CancellationToken cancellationToken = default);
ValueTask PublishEventAsync(CloudEvent @event, CancellationToken cancellationToken = default);
void Update(Activity? activity, RpcRequest request);
void Update(Activity? activity, CloudEvent cloudEvent);
(string?, string?) GetTraceIDandState(IDictionary<string, string> metadata);
IDictionary<string, string> ExtractMetadata(IDictionary<string, string> metadata);
}

View File

@ -0,0 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// IAgentState.cs
namespace Microsoft.AutoGen.Abstractions;
public interface IAgentState
{
ValueTask<AgentState> ReadStateAsync();
ValueTask<string> WriteStateAsync(AgentState state, string eTag);
}

View File

@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// IAgentWorker.cs
namespace Microsoft.AutoGen.Abstractions;
public interface IAgentWorker
{
ValueTask PublishEventAsync(CloudEvent evt, CancellationToken cancellationToken = default);
ValueTask SendRequestAsync(IAgentBase agent, RpcRequest request, CancellationToken cancellationToken = default);
ValueTask SendResponseAsync(RpcResponse response, CancellationToken cancellationToken = default);
ValueTask StoreAsync(AgentState value, CancellationToken cancellationToken = default);
ValueTask<AgentState> ReadAsync(AgentId agentId, CancellationToken cancellationToken = default);
}

View File

@ -0,0 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// IConnection.cs
namespace Microsoft.AutoGen.Abstractions;
public interface IConnection
{
}

View File

@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// IGateway.cs
namespace Microsoft.AutoGen.Abstractions;
public interface IGateway : IGrainObserver
{
ValueTask<RpcResponse> InvokeRequest(RpcRequest request);
ValueTask BroadcastEvent(CloudEvent evt);
ValueTask StoreAsync(AgentState value);
ValueTask<AgentState> ReadAsync(AgentId agentId);
Task SendMessageAsync(IConnection connection, CloudEvent cloudEvent);
}

View File

@ -1,6 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// IHandle.cs
namespace Microsoft.AutoGen.Abstractions;
public interface IHandle<T>
public interface IHandle
{
Task HandleObject(object item);
}
public interface IHandle<T> : IHandle
{
Task Handle(T item);
}

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// MessageExtensions.cs
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;

View File

@ -20,7 +20,8 @@
<PackageReference Include="Grpc.AspNetCore" />
<PackageReference Include="Grpc.Net.ClientFactory" />
<PackageReference Include="Grpc.Tools" PrivateAssets="All" />
<PackageReference Include="Microsoft.Orleans.Core.Abstractions" />
<PackageReference Include="Microsoft.Orleans.Sdk" />
<PackageReference Include="Microsoft.SemanticKernel" />
</ItemGroup>
</Project>

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// TopicSubscriptionAttribute.cs
namespace Microsoft.AutoGen.Abstractions;
[AttributeUsage(AttributeTargets.All)]

View File

@ -1,4 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// AgentBase.cs
using System.Diagnostics;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Threading.Channels;
@ -8,28 +12,32 @@ using Microsoft.Extensions.Logging;
namespace Microsoft.AutoGen.Agents;
public abstract class AgentBase
public abstract class AgentBase : IAgentBase, IHandle
{
public static readonly ActivitySource s_source = new("AutoGen.Agent");
public AgentId AgentId => _context.AgentId;
private readonly object _lock = new();
private readonly Dictionary<string, TaskCompletionSource<RpcResponse>> _pendingRequests = [];
private readonly Channel<object> _mailbox = Channel.CreateUnbounded<object>();
private readonly IAgentContext _context;
private readonly IAgentRuntime _context;
public string Route { get; set; } = "base";
protected internal AgentId AgentId => _context.AgentId;
protected internal ILogger Logger => _context.Logger;
protected internal IAgentContext Context => _context;
protected internal ILogger<AgentBase> _logger;
public IAgentRuntime Context => _context;
protected readonly EventTypes EventTypes;
protected AgentBase(IAgentContext context, EventTypes eventTypes)
protected AgentBase(
IAgentRuntime context,
EventTypes eventTypes,
ILogger<AgentBase>? logger = null)
{
_context = context;
context.AgentInstance = this;
this.EventTypes = eventTypes;
_logger = logger ?? LoggerFactory.Create(builder => { }).CreateLogger<AgentBase>();
Completion = Start();
}
internal Task Completion { get; }
internal Task Start()
@ -53,8 +61,7 @@ public abstract class AgentBase
}
}
}
internal void ReceiveMessage(Message message) => _mailbox.Writer.TryWrite(message);
public void ReceiveMessage(Message message) => _mailbox.Writer.TryWrite(message);
private async Task RunMessagePump()
{
@ -66,7 +73,7 @@ public abstract class AgentBase
switch (message)
{
case Message msg:
await HandleRpcMessage(msg).ConfigureAwait(false);
await HandleRpcMessage(msg, new CancellationToken()).ConfigureAwait(false);
break;
default:
throw new InvalidOperationException($"Unexpected message '{message}'.");
@ -74,12 +81,11 @@ public abstract class AgentBase
}
catch (Exception ex)
{
_context.Logger.LogError(ex, "Error processing message.");
_logger.LogError(ex, "Error processing message.");
}
}
}
private async Task HandleRpcMessage(Message msg)
protected internal async Task HandleRpcMessage(Message msg, CancellationToken cancellationToken = default)
{
switch (msg.MessageCase)
{
@ -90,17 +96,17 @@ public abstract class AgentBase
static ((AgentBase Agent, CloudEvent Item) state) => state.Agent.CallHandler(state.Item),
(this, msg.CloudEvent),
activity,
msg.CloudEvent.Type).ConfigureAwait(false);
msg.CloudEvent.Type, cancellationToken).ConfigureAwait(false);
}
break;
case Message.MessageOneofCase.Request:
{
var activity = this.ExtractActivity(msg.Request.Method, msg.Request.Metadata);
await this.InvokeWithActivityAsync(
static ((AgentBase Agent, RpcRequest Request) state) => state.Agent.OnRequestCore(state.Request),
static ((AgentBase Agent, RpcRequest Request) state) => state.Agent.OnRequestCoreAsync(state.Request),
(this, msg.Request),
activity,
msg.Request.Method).ConfigureAwait(false);
msg.Request.Method, cancellationToken).ConfigureAwait(false);
}
break;
case Message.MessageOneofCase.Response:
@ -108,14 +114,14 @@ public abstract class AgentBase
break;
}
}
protected async Task Store(AgentState state)
public async Task StoreAsync(AgentState state, CancellationToken cancellationToken = default)
{
await _context.Store(state).ConfigureAwait(false);
await _context.StoreAsync(state, cancellationToken).ConfigureAwait(false);
return;
}
protected async Task<T> Read<T>(AgentId agentId) where T : IMessage, new()
public async Task<T> ReadAsync<T>(AgentId agentId, CancellationToken cancellationToken = default) where T : IMessage, new()
{
var agentstate = await _context.Read(agentId).ConfigureAwait(false);
var agentstate = await _context.ReadAsync(agentId, cancellationToken).ConfigureAwait(false);
return agentstate.FromAgentState<T>();
}
private void OnResponseCore(RpcResponse response)
@ -132,8 +138,7 @@ public abstract class AgentBase
completion.SetResult(response);
}
private async Task OnRequestCore(RpcRequest request)
private async Task OnRequestCoreAsync(RpcRequest request, CancellationToken cancellationToken = default)
{
RpcResponse response;
@ -145,8 +150,7 @@ public abstract class AgentBase
{
response = new RpcResponse { Error = ex.Message };
}
await _context.SendResponseAsync(request, response).ConfigureAwait(false);
await _context.SendResponseAsync(request, response, cancellationToken).ConfigureAwait(false);
}
protected async Task<RpcResponse> RequestAsync(AgentId target, string method, Dictionary<string, string> parameters)
@ -170,7 +174,7 @@ public abstract class AgentBase
activity?.SetTag("peer.service", target.ToString());
var completion = new TaskCompletionSource<RpcResponse>(TaskCreationOptions.RunContinuationsAsynchronously);
Context.DistributedContextPropagator.Inject(activity, request.Metadata, static (carrier, key, value) => ((IDictionary<string, string>)carrier!)[key] = value);
_context.Update(activity, request);
await this.InvokeWithActivityAsync(
static async ((AgentBase Agent, RpcRequest Request, TaskCompletionSource<RpcResponse>) state) =>
{
@ -193,37 +197,91 @@ public abstract class AgentBase
return await completion.Task.ConfigureAwait(false);
}
protected async ValueTask PublishEvent(CloudEvent item)
public async ValueTask PublishMessageAsync<T>(T message, string? source = null, CancellationToken token = default) where T : IMessage
{
var activity = s_source.StartActivity($"PublishEvent '{item.Type}'", ActivityKind.Client, Activity.Current?.Context ?? default);
var src = string.IsNullOrWhiteSpace(source) ? this.AgentId.Key : source;
var evt = message.ToCloudEvent(src);
await PublishEventAsync(evt, token).ConfigureAwait(false);
}
public async ValueTask PublishEventAsync(CloudEvent item, CancellationToken cancellationToken = default)
{
var activity = s_source.StartActivity($"PublishEventAsync '{item.Type}'", ActivityKind.Client, Activity.Current?.Context ?? default);
activity?.SetTag("peer.service", $"{item.Type}/{item.Source}");
var completion = new TaskCompletionSource<CloudEvent>(TaskCreationOptions.RunContinuationsAsynchronously);
// TODO: fix activity
Context.DistributedContextPropagator.Inject(activity, item.Metadata, static (carrier, key, value) => ((IDictionary<string, string>)carrier!)[key] = value);
_context.Update(activity, item);
await this.InvokeWithActivityAsync(
static async ((AgentBase Agent, CloudEvent Event, TaskCompletionSource<CloudEvent>) state) =>
static async ((AgentBase Agent, CloudEvent Event) state) =>
{
await state.Agent._context.PublishEventAsync(state.Event).ConfigureAwait(false);
},
(this, item, completion),
(this, item),
activity,
item.Type).ConfigureAwait(false);
item.Type, cancellationToken).ConfigureAwait(false);
}
public Task CallHandler(CloudEvent item)
{
// Only send the event to the handler if the agent type is handling that type
if (EventTypes.EventsMap[GetType()].Contains(item.Type))
// foreach of the keys in the EventTypes.EventsMap[] if it contains the item.type
foreach (var key in EventTypes.EventsMap.Keys)
{
var payload = item.ProtoData.Unpack(EventTypes.TypeRegistry);
var convertedPayload = Convert.ChangeType(payload, EventTypes.Types[item.Type]);
var genericInterfaceType = typeof(IHandle<>).MakeGenericType(EventTypes.Types[item.Type]);
var methodInfo = genericInterfaceType.GetMethod(nameof(IHandle<object>.Handle)) ?? throw new InvalidOperationException($"Method not found on type {genericInterfaceType.FullName}");
return methodInfo.Invoke(this, [payload]) as Task ?? Task.CompletedTask;
if (EventTypes.EventsMap[key].Contains(item.Type))
{
var payload = item.ProtoData.Unpack(EventTypes.TypeRegistry);
var convertedPayload = Convert.ChangeType(payload, EventTypes.Types[item.Type]);
var genericInterfaceType = typeof(IHandle<>).MakeGenericType(EventTypes.Types[item.Type]);
MethodInfo methodInfo;
try
{
// check that our target actually implements this interface, otherwise call the default static
if (genericInterfaceType.IsAssignableFrom(this.GetType()))
{
methodInfo = genericInterfaceType.GetMethod(nameof(IHandle<object>.Handle), BindingFlags.Public | BindingFlags.Instance)
?? throw new InvalidOperationException($"Method not found on type {genericInterfaceType.FullName}");
return methodInfo.Invoke(this, [payload]) as Task ?? Task.CompletedTask;
}
else
{
// The error here is we have registered for an event that we do not have code to listen to
throw new InvalidOperationException($"No handler found for event '{item.Type}'; expecting IHandle<{item.Type}> implementation.");
}
}
catch (Exception ex)
{
_logger.LogError(ex, $"Error invoking method {nameof(IHandle<object>.Handle)}");
throw; // TODO: ?
}
}
}
return Task.CompletedTask;
}
protected virtual Task<RpcResponse> HandleRequest(RpcRequest request) => Task.FromResult(new RpcResponse { Error = "Not implemented" });
public Task<RpcResponse> HandleRequest(RpcRequest request) => Task.FromResult(new RpcResponse { Error = "Not implemented" });
//TODO: should this be async and cancellable?
public virtual Task HandleObject(object item)
{
// get all Handle<T> methods
var handleTMethods = this.GetType().GetMethods().Where(m => m.Name == "Handle" && m.GetParameters().Length == 1).ToList();
// get the one that matches the type of the item
var handleTMethod = handleTMethods.FirstOrDefault(m => m.GetParameters()[0].ParameterType == item.GetType());
// if we found one, invoke it
if (handleTMethod != null)
{
return (Task)handleTMethod.Invoke(this, [item])!;
}
// otherwise, complain
throw new InvalidOperationException($"No handler found for type {item.GetType().FullName}");
}
public async ValueTask PublishEventAsync(string topic, IMessage evt, CancellationToken cancellationToken = default)
{
await PublishEventAsync(evt.ToCloudEvent(topic), cancellationToken).ConfigureAwait(false);
}
}

View File

@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// AgentBaseExtensions.cs
using System.Diagnostics;
namespace Microsoft.AutoGen.Agents;
@ -6,17 +9,8 @@ public static class AgentBaseExtensions
{
public static Activity? ExtractActivity(this AgentBase agent, string activityName, IDictionary<string, string> metadata)
{
Activity? activity = null;
agent.Context.DistributedContextPropagator.ExtractTraceIdAndState(metadata,
static (object? carrier, string fieldName, out string? fieldValue, out IEnumerable<string>? fieldValues) =>
{
var metadata = (IDictionary<string, string>)carrier!;
fieldValues = null;
metadata.TryGetValue(fieldName, out fieldValue);
},
out var traceParent,
out var traceState);
Activity? activity;
(var traceParent, var traceState) = agent.Context.GetTraceIDandState(metadata);
if (!string.IsNullOrEmpty(traceParent))
{
if (ActivityContext.TryParse(traceParent, traceState, isRemote: true, out ActivityContext parentContext))
@ -37,12 +31,7 @@ public static class AgentBaseExtensions
activity.TraceStateString = traceState;
}
var baggage = agent.Context.DistributedContextPropagator.ExtractBaggage(metadata, static (object? carrier, string fieldName, out string? fieldValue, out IEnumerable<string>? fieldValues) =>
{
var metadata = (IDictionary<string, string>)carrier!;
fieldValues = null;
metadata.TryGetValue(fieldName, out fieldValue);
});
var baggage = agent.Context.ExtractMetadata(metadata);
if (baggage is not null)
{
@ -60,7 +49,7 @@ public static class AgentBaseExtensions
return activity;
}
public static async Task InvokeWithActivityAsync<TState>(this AgentBase agent, Func<TState, Task> func, TState state, Activity? activity, string methodName)
public static async Task InvokeWithActivityAsync<TState>(this AgentBase agent, Func<TState, Task> func, TState state, Activity? activity, string methodName, CancellationToken cancellationToken = default)
{
if (activity is not null && activity.StartTimeUtc == default)
{

View File

@ -1,46 +0,0 @@
using System.Diagnostics;
using Google.Protobuf;
using Microsoft.AutoGen.Abstractions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace Microsoft.AutoGen.Agents;
public sealed class AgentClient(ILogger<AgentClient> logger, AgentWorkerRuntime runtime, DistributedContextPropagator distributedContextPropagator,
[FromKeyedServices("EventTypes")] EventTypes eventTypes)
: AgentBase(new ClientContext(logger, runtime, distributedContextPropagator), eventTypes)
{
public async ValueTask PublishEventAsync(CloudEvent evt) => await PublishEvent(evt);
public async ValueTask<RpcResponse> SendRequestAsync(AgentId target, string method, Dictionary<string, string> parameters) => await RequestAsync(target, method, parameters);
public async ValueTask PublishEventAsync(string topic, IMessage evt)
{
await PublishEventAsync(evt.ToCloudEvent(topic)).ConfigureAwait(false);
}
private sealed class ClientContext(ILogger<AgentClient> logger, AgentWorkerRuntime runtime, DistributedContextPropagator distributedContextPropagator) : IAgentContext
{
public AgentId AgentId { get; } = new AgentId("client", Guid.NewGuid().ToString());
public AgentBase? AgentInstance { get; set; }
public ILogger Logger { get; } = logger;
public DistributedContextPropagator DistributedContextPropagator { get; } = distributedContextPropagator;
public async ValueTask PublishEventAsync(CloudEvent @event)
{
await runtime.PublishEvent(@event).ConfigureAwait(false);
}
public async ValueTask SendRequestAsync(AgentBase agent, RpcRequest request)
{
await runtime.SendRequest(AgentInstance!, request).ConfigureAwait(false);
}
public async ValueTask SendResponseAsync(RpcRequest request, RpcResponse response)
{
await runtime.SendResponse(response).ConfigureAwait(false);
}
public ValueTask Store(AgentState value)
{
throw new NotImplementedException();
}
public ValueTask<AgentState> Read(AgentId agentId)
{
throw new NotImplementedException();
}
}
}

View File

@ -1,36 +0,0 @@
using System.Diagnostics;
using Microsoft.AutoGen.Abstractions;
using Microsoft.Extensions.Logging;
namespace Microsoft.AutoGen.Agents;
internal sealed class AgentContext(AgentId agentId, AgentWorkerRuntime runtime, ILogger<AgentBase> logger, DistributedContextPropagator distributedContextPropagator) : IAgentContext
{
private readonly AgentWorkerRuntime _runtime = runtime;
public AgentId AgentId { get; } = agentId;
public ILogger Logger { get; } = logger;
public AgentBase? AgentInstance { get; set; }
public DistributedContextPropagator DistributedContextPropagator { get; } = distributedContextPropagator;
public async ValueTask SendResponseAsync(RpcRequest request, RpcResponse response)
{
response.RequestId = request.RequestId;
await _runtime.SendResponse(response);
}
public async ValueTask SendRequestAsync(AgentBase agent, RpcRequest request)
{
await _runtime.SendRequest(agent, request);
}
public async ValueTask PublishEventAsync(CloudEvent @event)
{
await _runtime.PublishEvent(@event);
}
public async ValueTask Store(AgentState value)
{
await _runtime.Store(value);
}
public async ValueTask<AgentState> Read(AgentId agentId)
{
return await _runtime.Read(agentId);
}
}

View File

@ -1,15 +0,0 @@
using RpcAgentId = Microsoft.AutoGen.Abstractions.AgentId;
namespace Microsoft.AutoGen.Agents;
public sealed record class AgentId(string Type, string Key)
{
public static implicit operator RpcAgentId(AgentId agentId) => new()
{
Type = agentId.Type,
Key = agentId.Key
};
public static implicit operator AgentId(RpcAgentId agentId) => new(agentId.Type, agentId.Key);
public override string ToString() => $"{Type}/{Key}";
}

Some files were not shown because too many files have changed in this diff Show More