Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
cornelcroi committed Sep 7, 2024
2 parents 7bf0f31 + e4d437d commit f346799
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 34 deletions.
52 changes: 26 additions & 26 deletions docs/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions docs/src/content/docs/deployment/demo-web-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ In the screen recording below, we demonstrate an extended version of the demo ap
- **Health Agent**: A Bedrock LLM Agent focused on addressing health-related queries

Watch as the system seamlessly switches context between diverse topics, from booking flights to checking weather, solving math problems, and providing health information.
Notice how the appropriate agent is selected for each query, maintaining coherence even with brief follow-up inputs.
Notice how the appropriate agent is selected for each query, maintaining coherence even with brief follow-up inputs.

The demo highlights the system's ability to handle complex, multi-turn conversations while preserving context and leveraging specialized agents across various domains.

Expand All @@ -38,7 +38,7 @@ Follow these steps to deploy the demo chat web application:

1. **Clone the Repository** (if you haven't already):
```
git clone https://github.com/your-repo/multi-agent-orchestrator.git
git clone https://github.com/awslabs/multi-agent-orchestrator.git
cd multi-agent-orchestrator
```

Expand Down Expand Up @@ -80,7 +80,7 @@ Follow these steps to deploy the demo chat web application:
CDK will show you a summary of the changes and ask for confirmation. Type 'y' and press Enter to proceed.

8. **Note the Outputs**:
After deployment, CDK will display outputs including the URL of your deployed web app and the user pool ID.
After deployment, CDK will display outputs including the URL of your deployed web app and the user pool ID.
Save the URL and the user pool Id.

9. **Create a user in Amazon Cognito user pool**:
Expand Down
16 changes: 16 additions & 0 deletions examples/python-demo/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import json
import sys

from tools import weather_tool

from multi_agent_orchestrator.orchestrator import MultiAgentOrchestrator, OrchestratorConfig
from multi_agent_orchestrator.agents import (BedrockLLMAgent,
BedrockLLMAgentOptions,
Expand Down Expand Up @@ -74,6 +76,20 @@ def custom_output_payload_decoder(response: Dict[str, Any]) -> Any:
))
orchestrator.add_agent(tech_agent)

# Add some agents
weather_agent = BedrockLLMAgent(BedrockLLMAgentOptions(
name="Weather Agent",
streaming=False,
description="Specialized agent for giving weather condition from a city.",
tool_config={
'tool':weather_tool.weather_tool_description,
'toolMaxRecursions': 5,
'useToolHandler': weather_tool.weather_tool_handler
}
))
weather_agent.set_system_prompt(weather_tool.weather_tool_prompt)
orchestrator.add_agent(weather_agent)

USER_ID = "user123"
SESSION_ID = str(uuid.uuid4())

Expand Down
105 changes: 105 additions & 0 deletions examples/python-demo/tools/weather_tool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import requests
from requests.exceptions import RequestException
from typing import List, Dict, Any
from multi_agent_orchestrator.types import ConversationMessage, ParticipantRole


weather_tool_description = [{
"toolSpec": {
"name": "Weather_Tool",
"description": "Get the current weather for a given location, based on its WGS84 coordinates.",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"latitude": {
"type": "string",
"description": "Geographical WGS84 latitude of the location.",
},
"longitude": {
"type": "string",
"description": "Geographical WGS84 longitude of the location.",
},
},
"required": ["latitude", "longitude"],
}
},
}
}]

weather_tool_prompt = """
You are a weather assistant that provides current weather data for user-specified locations using only
the Weather_Tool, which expects latitude and longitude. Infer the coordinates from the location yourself.
If the user provides coordinates, infer the approximate location and refer to it in your response.
To use the tool, you strictly apply the provided tool specification.
- Explain your step-by-step process, and give brief updates before each step.
- Only use the Weather_Tool for data. Never guess or make up information.
- Repeat the tool use for subsequent requests if necessary.
- If the tool errors, apologize, explain weather is unavailable, and suggest other options.
- Report temperatures in °C (°F) and wind in km/h (mph). Keep weather reports concise. Sparingly use
emojis where appropriate.
- Only respond to weather queries. Remind off-topic users of your purpose.
- Never claim to search online, access external data, or use tools besides Weather_Tool.
- Complete the entire process until you have all required data before sending the complete response.
"""


async def weather_tool_handler(response: ConversationMessage, conversation: List[Dict[str, Any]]):
response_content_blocks = response.content

# Initialize an empty list of tool results
tool_results = []

if not response_content_blocks:
raise ValueError("No content blocks in response")

for content_block in response_content_blocks:
if "text" in content_block:
# Handle text content if needed
pass

if "toolUse" in content_block:
tool_use_block = content_block["toolUse"]
tool_use_name = tool_use_block.get("name")

if tool_use_name == "Weather_Tool":
response = await fetch_weather_data(tool_use_block["input"])
tool_results.append({
"toolResult": {
"toolUseId": tool_use_block["toolUseId"],
"content": [{"json": {"result": response}}],
}
})
print(response)

# Embed the tool results in a new user message
message = ConversationMessage(
role=ParticipantRole.USER.value,
content=tool_results)

# Append the new message to the ongoing conversation
conversation.append(message)

async def fetch_weather_data(input_data):
"""
Fetches weather data for the given latitude and longitude using the Open-Meteo API.
Returns the weather data or an error message if the request fails.
:param input_data: The input data containing the latitude and longitude.
:return: The weather data or an error message.
"""
endpoint = "https://api.open-meteo.com/v1/forecast"
latitude = input_data.get("latitude")
longitude = input_data.get("longitude", "")
params = {"latitude": latitude, "longitude": longitude, "current_weather": True}

try:
response = requests.get(endpoint, params=params)
weather_data = {"weather_data": response.json()}
response.raise_for_status()
return weather_data
except RequestException as e:
return e.response.json()
except Exception as e:
return {"error": type(e), "message": str(e)}
2 changes: 1 addition & 1 deletion python/setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = multi_agent_orchestrator
version = 0.0.10
version = 0.0.11
author = Anthony Bernabeu, Corneliu Croitoru
author_email = [email protected], [email protected]
description = Multi-agent orchestrator framework
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ async def process_request(
chat_history: List[ConversationMessage],
additional_params: Optional[Dict[str, str]] = None
) -> Union[ConversationMessage, AsyncIterable[Any]]:
user_message =ConversationMessage(

user_message = ConversationMessage(
role=ParticipantRole.USER.value,
content=[{'text': input_text}]
)
Expand Down Expand Up @@ -114,7 +114,7 @@ async def process_request(
converse_cmd["guardrailConfig"] = self.guardrail_config

if self.tool_config:
converse_cmd["toolConfig"] = self.tool_config["tool"]
converse_cmd["toolConfig"] = {'tools': self.tool_config["tool"]}

if self.tool_config:
continue_with_tools = True
Expand All @@ -132,7 +132,7 @@ async def process_request(
final_message = bedrock_response

max_recursions -= 1
converse_cmd['messages'] = conversation
converse_cmd['messages'] = conversation_to_dict(conversation)

return final_message

Expand Down

0 comments on commit f346799

Please sign in to comment.