chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
## AutoGen Conversable Agent (v0.2.X)
|
||||
|
||||
Semantic Kernel Python supports running AutoGen Conversable Agents provided in the 0.2.X package.
|
||||
|
||||
### Limitations
|
||||
|
||||
Currently, there are some limitations to note:
|
||||
|
||||
- AutoGen Conversable Agents in Semantic Kernel run asynchronously and do not support streaming of agent inputs or responses.
|
||||
|
||||
### Installation
|
||||
|
||||
Install the `semantic-kernel` package with the `autogen` extra:
|
||||
|
||||
```bash
|
||||
pip install semantic-kernel[autogen]
|
||||
```
|
||||
|
||||
For an example of how to integrate an AutoGen Conversable Agent using the Semantic Kernel Agent abstraction, please refer to [`autogen_conversable_agent_simple_convo.py`](autogen_conversable_agent_simple_convo.py).
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
|
||||
from autogen import ConversableAgent
|
||||
from autogen.coding import LocalCommandLineCodeExecutor
|
||||
|
||||
from semantic_kernel.agents import AutoGenConversableAgent, AutoGenConversableAgentThread
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to use the AutoGenConversableAgent to create a reply from an agent
|
||||
to a message with a code block. The agent executes the code block and replies with the output.
|
||||
|
||||
The sample follows the AutoGen flow outlined here:
|
||||
https://microsoft.github.io/autogen/0.2/docs/tutorial/code-executors#local-execution
|
||||
"""
|
||||
|
||||
|
||||
async def main():
|
||||
thread: AutoGenConversableAgentThread = None
|
||||
|
||||
# Create a temporary directory to store the code files.
|
||||
import os
|
||||
|
||||
# Configure the temporary directory to be where the script is located.
|
||||
temp_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
# Create a local command line code executor.
|
||||
executor = LocalCommandLineCodeExecutor(
|
||||
timeout=10, # Timeout for each code execution in seconds.
|
||||
work_dir=temp_dir, # Use the temporary directory to store the code files.
|
||||
)
|
||||
|
||||
# Create an agent with code executor configuration.
|
||||
code_executor_agent = ConversableAgent(
|
||||
"code_executor_agent",
|
||||
llm_config=False, # Turn off LLM for this agent.
|
||||
code_execution_config={"executor": executor}, # Use the local command line code executor.
|
||||
human_input_mode="ALWAYS", # Always take human input for this agent for safety.
|
||||
)
|
||||
|
||||
autogen_agent = AutoGenConversableAgent(conversable_agent=code_executor_agent)
|
||||
|
||||
message_with_code_block = """This is a message with code block.
|
||||
The code block is below:
|
||||
```python
|
||||
def generate_fibonacci(max_val):
|
||||
a, b = 0, 1
|
||||
fibonacci_numbers = []
|
||||
while a <= max_val:
|
||||
fibonacci_numbers.append(a)
|
||||
a, b = b, a + b
|
||||
return fibonacci_numbers
|
||||
|
||||
if __name__ == "__main__":
|
||||
fib_numbers = generate_fibonacci(101)
|
||||
print(fib_numbers)
|
||||
```
|
||||
This is the end of the message.
|
||||
"""
|
||||
|
||||
async for response in autogen_agent.invoke(messages=message_with_code_block, thread=thread):
|
||||
print(f"# {response.role} - {response.name or '*'}: '{response}'")
|
||||
thread = response.thread
|
||||
|
||||
# Cleanup: Delete the thread and agent
|
||||
await thread.delete() if thread else None
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
from typing import Annotated, Literal
|
||||
|
||||
from autogen import ConversableAgent, register_function
|
||||
|
||||
from semantic_kernel.agents import AutoGenConversableAgent, AutoGenConversableAgentThread
|
||||
from semantic_kernel.contents.function_call_content import FunctionCallContent
|
||||
from semantic_kernel.contents.function_result_content import FunctionResultContent
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to use the AutoGenConversableAgent to create a conversation between two agents
|
||||
where one agent suggests a tool function call and the other agent executes the tool function call.
|
||||
|
||||
In this example, the assistant agent suggests a calculator tool function call to the user proxy agent. The user proxy
|
||||
agent executes the calculator tool function call. The assistant agent and the user proxy agent are created using the
|
||||
ConversableAgent class. The calculator tool function is registered with the assistant agent and the user proxy agent.
|
||||
|
||||
This sample follows the AutoGen flow outlined here:
|
||||
https://microsoft.github.io/autogen/0.2/docs/tutorial/tool-use
|
||||
"""
|
||||
|
||||
|
||||
Operator = Literal["+", "-", "*", "/"]
|
||||
|
||||
|
||||
async def main():
|
||||
def calculator(a: int, b: int, operator: Annotated[Operator, "operator"]) -> int:
|
||||
if operator == "+":
|
||||
return a + b
|
||||
if operator == "-":
|
||||
return a - b
|
||||
if operator == "*":
|
||||
return a * b
|
||||
if operator == "/":
|
||||
return int(a / b)
|
||||
raise ValueError("Invalid operator")
|
||||
|
||||
assistant = ConversableAgent(
|
||||
name="Assistant",
|
||||
system_message="You are a helpful AI assistant. "
|
||||
"You can help with simple calculations. "
|
||||
"Return 'TERMINATE' when the task is done.",
|
||||
# Note: the model "gpt-4o" leads to a "division by zero" error that doesn't occur with "gpt-4o-mini"
|
||||
# or even "gpt-4".
|
||||
llm_config={
|
||||
"config_list": [{"model": os.environ["OPENAI_CHAT_MODEL_ID"], "api_key": os.environ["OPENAI_API_KEY"]}]
|
||||
},
|
||||
)
|
||||
|
||||
# Create a thread for use with the agent.
|
||||
thread: AutoGenConversableAgentThread = None
|
||||
|
||||
# Create a Semantic Kernel AutoGenConversableAgent based on the AutoGen ConversableAgent.
|
||||
assistant_agent = AutoGenConversableAgent(conversable_agent=assistant)
|
||||
|
||||
user_proxy = ConversableAgent(
|
||||
name="User",
|
||||
llm_config=False,
|
||||
is_termination_msg=lambda msg: msg.get("content") is not None and "TERMINATE" in msg["content"],
|
||||
human_input_mode="NEVER",
|
||||
)
|
||||
|
||||
assistant.register_for_llm(name="calculator", description="A simple calculator")(calculator)
|
||||
|
||||
# Register the tool function with the user proxy agent.
|
||||
user_proxy.register_for_execution(name="calculator")(calculator)
|
||||
|
||||
register_function(
|
||||
calculator,
|
||||
caller=assistant, # The assistant agent can suggest calls to the calculator.
|
||||
executor=user_proxy, # The user proxy agent can execute the calculator calls.
|
||||
name="calculator", # By default, the function name is used as the tool name.
|
||||
description="A simple calculator", # A description of the tool.
|
||||
)
|
||||
|
||||
# Create a Semantic Kernel AutoGenConversableAgent based on the AutoGen ConversableAgent.
|
||||
user_proxy_agent = AutoGenConversableAgent(conversable_agent=user_proxy)
|
||||
|
||||
async for response in user_proxy_agent.invoke(
|
||||
thread=thread,
|
||||
recipient=assistant_agent,
|
||||
messages="What is (44232 + 13312 / (232 - 32)) * 5?",
|
||||
max_turns=10,
|
||||
):
|
||||
for item in response.items:
|
||||
match item:
|
||||
case FunctionResultContent(result=r):
|
||||
print(f"# {response.role} - {response.name or '*'}: '{r}'")
|
||||
case FunctionCallContent(function_name=fn, arguments=arguments):
|
||||
print(
|
||||
f"# {response.role} - {response.name or '*'}: Function Name: '{fn}', Arguments: '{arguments}'" # noqa: E501
|
||||
)
|
||||
case _:
|
||||
print(f"# {response.role} - {response.name or '*'}: '{response}'")
|
||||
thread = response.thread
|
||||
|
||||
# Cleanup: Delete the thread and agent
|
||||
await thread.delete() if thread else None
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from autogen import ConversableAgent
|
||||
|
||||
from semantic_kernel.agents import AutoGenConversableAgent, AutoGenConversableAgentThread
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to use the AutoGenConversableAgent to create a conversation between two agents
|
||||
where one agent suggests a joke and the other agent generates a joke.
|
||||
|
||||
The sample follows the AutoGen flow outlined here:
|
||||
https://microsoft.github.io/autogen/0.2/docs/tutorial/introduction#roles-and-conversations
|
||||
"""
|
||||
|
||||
|
||||
async def main():
|
||||
thread: AutoGenConversableAgentThread = None
|
||||
|
||||
cathy = ConversableAgent(
|
||||
"cathy",
|
||||
system_message="Your name is Cathy and you are a part of a duo of comedians.",
|
||||
llm_config={
|
||||
"config_list": [
|
||||
{
|
||||
"model": os.environ["OPENAI_CHAT_MODEL_ID"],
|
||||
"temperature": 0.9,
|
||||
"api_key": os.environ.get("OPENAI_API_KEY"),
|
||||
}
|
||||
]
|
||||
},
|
||||
human_input_mode="NEVER", # Never ask for human input.
|
||||
)
|
||||
|
||||
cathy_autogen_agent = AutoGenConversableAgent(conversable_agent=cathy)
|
||||
|
||||
joe = ConversableAgent(
|
||||
"joe",
|
||||
system_message="Your name is Joe and you are a part of a duo of comedians.",
|
||||
llm_config={
|
||||
"config_list": [
|
||||
{
|
||||
"model": os.environ["OPENAI_CHAT_MODEL_ID"],
|
||||
"temperature": 0.7,
|
||||
"api_key": os.environ.get("OPENAI_API_KEY"),
|
||||
}
|
||||
]
|
||||
},
|
||||
human_input_mode="NEVER", # Never ask for human input.
|
||||
)
|
||||
|
||||
joe_autogen_agent = AutoGenConversableAgent(conversable_agent=joe)
|
||||
|
||||
async for response in cathy_autogen_agent.invoke(
|
||||
recipient=joe_autogen_agent, message="Tell me a joke about the stock market.", thread=thread, max_turns=3
|
||||
):
|
||||
print(f"# {response.role} - {response.name or '*'}: '{response}'")
|
||||
thread = response.thread
|
||||
|
||||
# Cleanup: Delete the thread and agent
|
||||
await thread.delete() if thread else None
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user