Skip to content

Commit 17cceb2

Browse files
committed
[onkark][develop] [onkark][rebased] Autogen Integration
Signed-off-by: Onkar Kulkarni <onkark@synopsys.com>
1 parent 771bb19 commit 17cceb2

File tree

24 files changed

+2966
-10843
lines changed

24 files changed

+2966
-10843
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<!--
2+
SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
SPDX-License-Identifier: Apache-2.0
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
<!-- path-check-skip-file -->
18+
19+
# AutoGen Framework Example
20+
21+
A minimal example using Microsoft's AutoGen framework showcasing a multi-agent weather and time information system where agents collaborate through AutoGen's conversation system to provide accurate weather and time data for specified cities.
22+
23+
## Key Features
24+
25+
- **AutoGen Framework Integration:** Demonstrates NeMo Agent Toolkit support for Microsoft's AutoGen framework alongside other frameworks like LangChain/LangGraph and Semantic Kernel.
26+
- **Multi-Agent Collaboration:** Shows two specialized agents working together - a WeatherAndTimeAgent for data retrieval and a FinalResponseAgent for response formatting.
27+
- **MCP Server Integration:** Demonstrates how NAT can interact with MCP (Model Context Protocol) servers to provide time information through external services.
28+
- **Tool Integration:** Showcases integration of both local tools (weather updates) and remote tools (MCP time service) within the AutoGen framework.
29+
- **Round-Robin Group Chat:** Uses AutoGen's RoundRobinGroupChat for structured agent communication with termination conditions.
30+
31+
## Installation and Setup
32+
33+
If you have not already done so, follow the instructions in the [Install Guide](../../../docs/source/quick-start/installing.md#install-from-source) to create the development environment and install NeMo Agent Toolkit.
34+
35+
### Install this Workflow
36+
37+
From the root directory of the NAT library, run the following commands:
38+
39+
```bash
40+
uv pip install -e examples/getting_started/simple_calculator # required to run the current_datetime MCP tool used in example workflow.
41+
uv pip install -e examples/frameworks/nat_autogen_demo
42+
```
43+
44+
### Export required ENV variables
45+
If you have not already done so, follow the [Obtaining API Keys](../../../docs/source/quick-start/installing.md#obtaining-api-keys) instructions to obtain API keys.
46+
47+
For OpenAI Export these:
48+
- OPENAI_MODEL_NAME
49+
- OPENAI_API_KEY
50+
- OPENAI_API_BASE
51+
52+
### Run the Workflow
53+
54+
#### Set up the MCP server
55+
This example demonstrates how NAT can interact with MCP servers on behalf of AutoGen agents.
56+
57+
First run the MCP server with this command:
58+
59+
```bash
60+
nat mcp serve --config_file examples/getting_started/simple_calculator/configs/config.yml --tool_names current_datetime
61+
```
62+
63+
Then run the workflow with the NAT CLI:
64+
65+
```bash
66+
nat run --config_file examples/frameworks/nat_autogen_demo/configs/config.yml --input "What is the weather and time in New York today?"
67+
```
68+
69+
### Expected output
70+
71+
```console
72+
2025-10-07 14:34:28,122 - nat.cli.commands.start - INFO - Starting NAT from config file: 'examples/frameworks/nat_autogen_demo/configs/config.yml'
73+
2025-10-07 14:34:30,285 - mcp.client.streamable_http - INFO - Received session ID: 652a05b6646c4ddb945cf2adf0b3ec18
74+
Received session ID: 652a05b6646c4ddb945cf2adf0b3ec18
75+
2025-10-07 14:34:30,287 - mcp.client.streamable_http - INFO - Negotiated protocol version: 2025-06-18
76+
Negotiated protocol version: 2025-06-18
77+
78+
Configuration Summary:
79+
--------------------
80+
Workflow Type: autogen_team
81+
Number of Functions: 1
82+
Number of Function Groups: 0
83+
Number of LLMs: 1
84+
Number of Embedders: 0
85+
Number of Memory: 0
86+
Number of Object Stores: 0
87+
Number of Retrievers: 0
88+
Number of TTC Strategies: 0
89+
Number of Authentication Providers: 0
90+
91+
2025-10-07 14:34:30,301 - nat.observability.exporter_manager - INFO - Started exporter 'otelcollector'
92+
2025-10-07 14:34:46,704 - nat.front_ends.console.console_front_end_plugin - INFO -
93+
.
94+
.
95+
.
96+
<snipped for brevity>
97+
.
98+
.
99+
.
100+
--------------------------------------------------
101+
Workflow Result:
102+
['New York weather: Sunny, around 25°C (77°F).\nCurrent local time in New York: 5:34 PM EDT (UTC−4) on October 7, 2025.\n\nAPPROVE']
103+
--------------------------------------------------
104+
105+
--------------------------------------------------
106+
Workflow Result:
107+
['New York weather: Sunny, around 25°C (77°F).\nCurrent local time in New York: 5:34 PM EDT (UTC−4) on October 7, 2025.\n\nAPPROVE']
108+
--------------------------------------------------
109+
110+
```
111+
112+
## Architecture
113+
114+
The AutoGen workflow consists of two main agents:
115+
116+
1. **WeatherAndTimeAgent**: Retrieves weather and time information using tools
117+
- Uses the `weather_update_tool` for current weather conditions
118+
- Connects to MCP server for accurate time information
119+
- Responds with "DONE" when task is completed
120+
121+
2. **FinalResponseAgent**: Formats and presents the final response
122+
- Consolidates information from other agents
123+
- Provides clear, concise answers to user queries
124+
- Terminates the conversation with "APPROVE".
125+
126+
The agents communicate through AutoGen's RoundRobinGroupChat system, which manages the conversation flow and ensures proper termination when the task is complete.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
general:
17+
front_end:
18+
_type: console
19+
cors:
20+
allow_origins: ["*"]
21+
telemetry:
22+
logging:
23+
console:
24+
_type: console
25+
level: debug
26+
tracing:
27+
otelcollector:
28+
_type: otelcollector
29+
endpoint: ${OTEL_ENDPOINT:-http://localhost:6006/v1/traces}
30+
project: nat_autogen_demo
31+
32+
llms:
33+
openai_llm:
34+
_type: openai
35+
model_name: ${OPENAI_MODEL_NAME:-gpt-5}
36+
api_key: ${OPENAI_API_KEY}
37+
base_url: ${OPENAI_API_BASE}
38+
39+
functions:
40+
weather_update_tool:
41+
_type: nat_autogen_demo/weather_update_autogen
42+
description: "Get the current weather for a specified city"
43+
44+
workflow:
45+
_type: autogen_team
46+
llm_name: openai_llm
47+
description: "To get the current weather and time in a specific city"
48+
tool_names: [weather_update_tool]
49+
query_processing_agent_name: WeatherAndTimeAgent
50+
query_processing_agent_instructions: |
51+
You are an agent that provides the current weather and time information.
52+
When asked about the weather, provide the current weather conditions.
53+
When asked about the time, provide the current local time.
54+
If asked about anything else, respond with 'I can only provide weather and time information.'
55+
Once you are done, reply with the text 'DONE'.
56+
final_response_agent_name: FinalResponseAgent
57+
final_response_agent_instructions: |
58+
You are the final response agent.
59+
Your role is to provide a concise and clear answer based on the information provided by other agents.
60+
Once you are done, reply with the final answer and then say 'APPROVE'.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[build-system]
2+
build-backend = "setuptools.build_meta"
3+
requires = ["setuptools >= 64", "setuptools-scm>=8"]
4+
5+
[tool.setuptools_scm]
6+
git_describe_command = "git describe --long --first-parent"
7+
root = "../../.."
8+
9+
[project]
10+
name = "nat_autogen_demo"
11+
dynamic = ["version"]
12+
dependencies = [
13+
"nvidia-nat[autogen]~=1.4",
14+
]
15+
requires-python = ">=3.11,<3.14"
16+
description = "AutoGen Workflow Example"
17+
keywords = ["ai", "rag", "agents", "autogen", "multi-agent"]
18+
classifiers = ["Programming Language :: Python"]
19+
20+
[tool.uv.sources]
21+
nvidia-nat = { path = "../../..", editable = true }
22+
23+
[project.entry-points.'nat.components']
24+
nat_autogen_demo = "nat_autogen_demo.register"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
import logging
17+
from collections.abc import AsyncGenerator
18+
19+
from pydantic import Field
20+
21+
from nat.builder.builder import Builder
22+
from nat.builder.framework_enum import LLMFrameworkEnum
23+
from nat.builder.function_info import FunctionInfo
24+
from nat.cli.register_workflow import register_function
25+
from nat.data_models.component_ref import LLMRef
26+
from nat.data_models.function import FunctionBaseConfig
27+
28+
logger = logging.getLogger(__name__)
29+
30+
31+
class AutoGenFunctionConfig(FunctionBaseConfig, name="autogen_team"):
32+
"""Configuration for AutoGen Agent workflow."""
33+
34+
llm_name: LLMRef = Field(description="The LLM model to use with AutoGen agents.")
35+
tool_names: list[str] = Field(default_factory=list, description="List of tool names to be used by the agents.")
36+
mcp_server_url: str = Field(
37+
default="http://0.0.0.0:9901/mcp",
38+
description="URL for the MCP time server.",
39+
)
40+
query_processing_agent_name: str = Field(description="Name of the query processing agent")
41+
query_processing_agent_instructions: str = Field(description="Instructions for the query processing agent")
42+
final_response_agent_name: str = Field(description="Name of the final response agent")
43+
final_response_agent_instructions: str = Field(description="Instructions for the final response agent")
44+
45+
46+
@register_function(config_type=AutoGenFunctionConfig, framework_wrappers=[LLMFrameworkEnum.AUTOGEN])
47+
async def autogen_team(config: AutoGenFunctionConfig, builder: Builder) -> AsyncGenerator[FunctionInfo, None]:
48+
"""
49+
AutoGen multi-agent workflow that demonstrates collaborative agents in a team.
50+
The agents communicate through AutoGen's conversation system to produce output.
51+
52+
Args:
53+
config (AutoGenFunctionConfig): Configuration for the workflow.
54+
builder (Builder): The NAT workflow builder to access registered components.
55+
56+
Yields:
57+
AsyncGenerator[FunctionInfo, None]: Yields a FunctionInfo object encapsulating the workflow.
58+
"""
59+
60+
from autogen_agentchat.agents import AssistantAgent
61+
from autogen_agentchat.conditions import TextMentionTermination
62+
from autogen_agentchat.teams import RoundRobinGroupChat
63+
from autogen_ext.tools.mcp import StreamableHttpMcpToolAdapter
64+
from autogen_ext.tools.mcp import StreamableHttpServerParams
65+
66+
try:
67+
llm_client = await builder.get_llm(config.llm_name, wrapper_type=LLMFrameworkEnum.AUTOGEN)
68+
tools = await builder.get_tools(config.tool_names, wrapper_type=LLMFrameworkEnum.AUTOGEN)
69+
70+
time_server_params = StreamableHttpServerParams(
71+
url=config.mcp_server_url,
72+
headers={"Content-Type": "application/json"},
73+
timeout=30,
74+
)
75+
adapter = await StreamableHttpMcpToolAdapter.from_server_params(time_server_params, "current_datetime")
76+
tools.append(adapter)
77+
78+
query_processing_agent = AssistantAgent(name=config.query_processing_agent_name,
79+
model_client=llm_client,
80+
tools=tools,
81+
system_message=config.query_processing_agent_instructions)
82+
final_response_agent = AssistantAgent(name=config.final_response_agent_name,
83+
model_client=llm_client,
84+
system_message=config.final_response_agent_instructions)
85+
86+
team = RoundRobinGroupChat(participants=[query_processing_agent, final_response_agent],
87+
termination_condition=TextMentionTermination("APPROVE"))
88+
89+
async def _autogen_team_workflow(user_input: str) -> str:
90+
"""Execute the workflow with the given input.
91+
92+
Args:
93+
user_input (str): User's query
94+
95+
Returns:
96+
str: The final response generated by the team.
97+
"""
98+
try:
99+
result = await team.run(task=user_input)
100+
101+
if hasattr(result, 'messages') and result.messages:
102+
return result.messages[-1].content
103+
else:
104+
return "The workflow finished but no output was generated."
105+
106+
except Exception as e:
107+
logger.exception("Error in AutoGen workflow")
108+
return f"Error occurred during AutoGen workflow: {e!s}"
109+
110+
# Yield the function info
111+
yield FunctionInfo.create(single_fn=_autogen_team_workflow)
112+
113+
except GeneratorExit:
114+
logger.info("AutoGen workflow exited early")
115+
except Exception as _e:
116+
logger.exception("Failed to initialize AutoGen workflow")
117+
raise
118+
finally:
119+
logger.debug("AutoGen workflow cleanup completed")
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
from . import autogen_team # noqa: F401 # pylint: disable=W0611 #imported for side effects (registration)
17+
from . import weather_update_tool # noqa: F401 # pylint: disable=W0611 #imported for side effects (registration)

0 commit comments

Comments
 (0)