Skip to content

Commit 3424764

Browse files
committed
code cleanup
using bedrock added readme
1 parent d4a0fc5 commit 3424764

File tree

7 files changed

+186
-133
lines changed

7 files changed

+186
-133
lines changed

examples/movie-production/movie-production-demo.py

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,24 @@
1-
from dotenv import load_dotenv
2-
import streamlit as st
3-
load_dotenv()
4-
import os
51
import uuid
6-
import os
72
import asyncio
3+
import streamlit as st
4+
import os
85
from search_web import tool_handler
9-
from tool import Tool, ToolResult
6+
from tool import Tool
107
from multi_agent_orchestrator.orchestrator import MultiAgentOrchestrator, OrchestratorConfig
118
from multi_agent_orchestrator.agents import (
12-
AnthropicAgent, AnthropicAgentOptions,
13-
AgentResponse
9+
AgentResponse,
10+
BedrockLLMAgent,
11+
BedrockLLMAgentOptions
1412
)
1513
from multi_agent_orchestrator.types import ConversationMessage
1614
from multi_agent_orchestrator.classifiers import ClassifierResult
17-
from supervisor import SupervisorMode, SupervisorModeOptions
15+
from supervisor_agent import SupervisorAgent, SupervisorAgentOptions
1816

1917
# Set up the Streamlit app
2018
st.title("AI Movie Production Demo 🎬")
2119
st.caption("Bring your movie ideas to life with the teams of script writing and casting AI agents")
2220

2321

24-
# Get Anthropic API key from user
25-
anthropic_api_key = st.text_input("Enter Anthropic API Key to access Claude Sonnet 3.5", type="password", value=os.getenv('ANTHROPIC_API_KEY', None))
26-
2722
search_web_tool = Tool(name='search_web',
2823
description='Search Web for information',
2924
properties={
@@ -34,8 +29,8 @@
3429
},
3530
required=['query'])
3631

37-
script_writer_agent = AnthropicAgent(AnthropicAgentOptions(
38-
api_key=os.getenv('ANTHROPIC_API_KEY', None),
32+
script_writer_agent = BedrockLLMAgent(BedrockLLMAgentOptions(
33+
model_id='us.anthropic.claude-3-sonnet-20240229-v1:0',
3934
name="ScriptWriterAgent",
4035
description="""\
4136
You are an expert screenplay writer. Given a movie idea and genre,
@@ -47,8 +42,8 @@
4742
3. Ensure the script aligns with the specified genre and target audience
4843
"""))
4944

50-
casting_director_agent = AnthropicAgent(AnthropicAgentOptions(
51-
api_key=os.getenv('ANTHROPIC_API_KEY', None),
45+
casting_director_agent = BedrockLLMAgent(BedrockLLMAgentOptions(
46+
model_id='anthropic.claude-3-haiku-20240307-v1:0',
5247
name="CastingDirectorAgent",
5348
description="""\
5449
You are a talented casting director. Given a script outline and character descriptions,\
@@ -63,15 +58,15 @@
6358
""",
6459

6560
tool_config={
66-
'tool': [search_web_tool.to_claude_format()],
61+
'tool': [search_web_tool.to_bedrock_format()],
6762
'toolMaxRecursions': 20,
6863
'useToolHandler': tool_handler
6964
},
7065
save_chat=False
7166
))
7267

73-
movie_producer_supervisor = AnthropicAgent(AnthropicAgentOptions(
74-
api_key=os.getenv('ANTHROPIC_API_KEY', None),
68+
movie_producer_supervisor = BedrockLLMAgent(BedrockLLMAgentOptions(
69+
model_id='us.anthropic.claude-3-5-sonnet-20241022-v2:0',
7570
name='MovieProducerAgent',
7671
description="""
7772
Experienced movie producer overseeing script and casting.
@@ -85,7 +80,7 @@
8580
""",
8681
))
8782

88-
supervisor = SupervisorMode(SupervisorModeOptions(
83+
supervisor = SupervisorAgent(SupervisorAgentOptions(
8984
supervisor=movie_producer_supervisor,
9085
team=[script_writer_agent, casting_director_agent],
9186
trace=True
143 KB
Loading
52.5 KB
Loading
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
## 🎬 AI Movie Production Agent
2+
This Streamlit app is an AI-powered movie production assistant that helps bring your movie ideas to life using Claude 3 on Amazon BedrocK. It automates the process of script writing and casting, allowing you to create compelling movie concepts with ease.
3+
4+
![image](./movie-production.png)
5+
![image](./movie-production-result.png)
6+
7+
### Features
8+
- Generates script outlines based on your movie idea, genre, and target audience
9+
- Suggests suitable actors for main roles, considering their past performances and current availability
10+
- Provides a concise movie concept overview
11+
12+
### How to get Started?
13+
14+
1. Clone the GitHub repository
15+
16+
```bash
17+
git clone https://github.com/awslabs/multi-agent-orchestrator.git
18+
```
19+
2. Install the required dependencies:
20+
21+
```bash
22+
cd examples/movie-production
23+
pip install -r requirements.txt
24+
```
25+
3. Get your AWS Credentials
26+
27+
4. Run the Streamlit App
28+
```bash
29+
streamlit run movie-production-demo.py
30+
```
31+
32+
### How it Works?
33+
34+
The AI Movie Production Agent utilizes three main components:
35+
- **ScriptWriterAgent**: Develops a compelling script outline with character descriptions and key plot points based on the given movie idea and genre.
36+
- **CastingDirectorAgent**: Suggests suitable actors for the main roles, considering their past performances and current availability by making web search using a tool.
37+
- **MovieProducerAgent**: Oversees the entire process, coordinating between the ScriptWriter and CastingDirector, and providing a concise movie concept overview.
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
serpapi
2-
google-search-results
1+
multi-agent-orchestrator
2+
streamlit
3+
duckduckgo-search
Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import json
21
from typing import Any
32
from tool import ToolResult
4-
from multi_agent_orchestrator.types import ParticipantRole
5-
3+
from multi_agent_orchestrator.types import ParticipantRole, ConversationMessage
4+
from multi_agent_orchestrator.utils.logger import Logger
65
from duckduckgo_search import DDGS
76

87
async def tool_handler(response: Any, conversation: list[dict[str, Any]],) -> Any:
@@ -14,18 +13,18 @@ async def tool_handler(response: Any, conversation: list[dict[str, Any]],) -> An
1413

1514
for block in content_blocks:
1615
# Determine if it's a tool use block based on platform
17-
tool_use_block = block if block.type == "tool_use" else None
16+
tool_use_block = block.get('toolUse') if "toolUse" in block else None
1817
if not tool_use_block:
1918
continue
2019

21-
tool_name = (tool_use_block.name)
20+
tool_name = (tool_use_block.get('name'))
2221

2322
tool_id = (
24-
tool_use_block.id
23+
tool_use_block.get('toolUseId')
2524
)
2625

2726
# Get input based on platform
28-
input_data = (tool_use_block.input)
27+
input_data = (tool_use_block.get('input'))
2928

3029
# Process the tool use
3130
if (tool_name == "search_web"):
@@ -37,15 +36,12 @@ async def tool_handler(response: Any, conversation: list[dict[str, Any]],) -> An
3736
tool_result = ToolResult(tool_id, result)
3837

3938
# Format according to platform
40-
formatted_result = (tool_result.to_anthropic_format())
39+
formatted_result = (tool_result.to_bedrock_format())
4140

4241
tool_results.append(formatted_result)
4342

44-
# Create and return appropriate message format
45-
return {
46-
'role': ParticipantRole.USER.value,
47-
'content': tool_results
48-
}
43+
# Create and return appropriate message format
44+
return ConversationMessage(role=ParticipantRole.USER.value, content=tool_results)
4945

5046
def search_web(query: str, num_results: int = 2) -> str:
5147
"""
@@ -56,23 +52,17 @@ def search_web(query: str, num_results: int = 2) -> str:
5652
num_results(int): The number of results to return.
5753
5854
Returns:
59-
str: The search results from Google.
60-
Keys:
61-
- 'search_results': List of organic search results.
62-
- 'recipes_results': List of recipes search results.
63-
- 'shopping_results': List of shopping search results.
64-
- 'knowledge_graph': The knowledge graph.
65-
- 'related_questions': List of related questions.
55+
str: The search results from DDG.
6656
"""
6757

6858
try:
6959

70-
print(f"Searching DDG for: {query}")
60+
Logger.info(f"Searching DDG for: {query}")
7161

7262
search = DDGS().text(query, max_results=num_results)
7363
return ('\n'.join(result.get('body','') for result in search))
7464

7565

7666
except Exception as e:
77-
print(f"Error searching for the query {query}: {e}")
67+
Logger.error(f"Error searching for the query {query}: {e}")
7868
return f"Error searching for the query {query}: {e}"

0 commit comments

Comments
 (0)