support for more llm models + refined streamlit UI
This commit is contained in:
parent
f33f147783
commit
a681894465
3 changed files with 81 additions and 68 deletions
|
|
@ -1,16 +1,31 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import streamlit as st
|
import streamlit as st
|
||||||
from browser_use import Agent, SystemPrompt
|
from browser_use import Agent, SystemPrompt
|
||||||
from langchain_google_genai import ChatGoogleGenerativeAI
|
|
||||||
from langchain_openai import ChatOpenAI
|
from langchain_openai import ChatOpenAI
|
||||||
from langchain_anthropic import ChatAnthropic
|
from langchain_anthropic import ChatAnthropic
|
||||||
|
from langchain_core.messages import HumanMessage
|
||||||
import re
|
import re
|
||||||
|
|
||||||
async def generate_meme(query: str, api_key: str) -> None:
|
async def generate_meme(query: str, model_choice: str, api_key: str) -> None:
|
||||||
llm = ChatAnthropic(
|
# Initialize the appropriate LLM based on user selection
|
||||||
model="claude-3-5-sonnet-20241022",
|
if model_choice == "Claude":
|
||||||
api_key=api_key
|
llm = ChatAnthropic(
|
||||||
)
|
model="claude-3-5-sonnet-20241022",
|
||||||
|
api_key=api_key
|
||||||
|
)
|
||||||
|
elif model_choice == "Deepseek":
|
||||||
|
llm = ChatOpenAI(
|
||||||
|
base_url='https://api.deepseek.com/v1',
|
||||||
|
model='deepseek-chat',
|
||||||
|
api_key=api_key,
|
||||||
|
temperature=0.3
|
||||||
|
)
|
||||||
|
else: # OpenAI
|
||||||
|
llm = ChatOpenAI(
|
||||||
|
model="gpt-4o",
|
||||||
|
api_key=api_key,
|
||||||
|
temperature=0.0
|
||||||
|
)
|
||||||
|
|
||||||
task_description = (
|
task_description = (
|
||||||
"You are a meme generator expert. You are given a query and you need to generate a meme for it.\n"
|
"You are a meme generator expert. You are given a query and you need to generate a meme for it.\n"
|
||||||
|
|
@ -29,7 +44,8 @@ async def generate_meme(query: str, api_key: str) -> None:
|
||||||
task=task_description,
|
task=task_description,
|
||||||
llm=llm,
|
llm=llm,
|
||||||
max_actions_per_step=5,
|
max_actions_per_step=5,
|
||||||
max_failures=25
|
max_failures=25,
|
||||||
|
use_vision=(model_choice != "Deepseek")
|
||||||
)
|
)
|
||||||
|
|
||||||
history = await agent.run()
|
history = await agent.run()
|
||||||
|
|
@ -41,42 +57,74 @@ async def generate_meme(query: str, api_key: str) -> None:
|
||||||
url_match = re.search(r'https://imgflip\.com/i/(\w+)', final_result)
|
url_match = re.search(r'https://imgflip\.com/i/(\w+)', final_result)
|
||||||
if url_match:
|
if url_match:
|
||||||
meme_id = url_match.group(1)
|
meme_id = url_match.group(1)
|
||||||
# Convert to direct image URL format
|
|
||||||
return f"https://i.imgflip.com/{meme_id}.jpg"
|
return f"https://i.imgflip.com/{meme_id}.jpg"
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
st.title("AI Meme Generator - Browser Use")
|
# Custom CSS styling
|
||||||
|
|
||||||
|
|
||||||
|
st.title("🤖 AI Meme Generator - Browser Use Web Agent")
|
||||||
st.info("This AI browser agent does browser automation to generate memes based on your input with browser use. Please enter your API key and describe the meme you want to generate.")
|
st.info("This AI browser agent does browser automation to generate memes based on your input with browser use. Please enter your API key and describe the meme you want to generate.")
|
||||||
|
|
||||||
# Configuration Settings
|
# Sidebar configuration
|
||||||
with st.sidebar:
|
with st.sidebar:
|
||||||
st.header("⚙️ Configuration Settings")
|
st.markdown('<p class="sidebar-header">⚙️ Model Configuration</p>', unsafe_allow_html=True)
|
||||||
api_key = st.text_input("Enter your Claude API Key", type="password")
|
|
||||||
|
# Model selection
|
||||||
|
model_choice = st.selectbox(
|
||||||
|
"Select AI Model",
|
||||||
|
["Claude", "Deepseek", "OpenAI"],
|
||||||
|
index=0,
|
||||||
|
help="Choose which LLM to use for meme generation"
|
||||||
|
)
|
||||||
|
|
||||||
|
# API key input based on model selection
|
||||||
|
api_key = ""
|
||||||
|
if model_choice == "Claude":
|
||||||
|
api_key = st.text_input("Claude API Key", type="password",
|
||||||
|
help="Get your API key from https://console.anthropic.com")
|
||||||
|
elif model_choice == "Deepseek":
|
||||||
|
api_key = st.text_input("Deepseek API Key", type="password",
|
||||||
|
help="Get your API key from https://platform.deepseek.com")
|
||||||
|
else:
|
||||||
|
api_key = st.text_input("OpenAI API Key", type="password",
|
||||||
|
help="Get your API key from https://platform.openai.com")
|
||||||
|
|
||||||
# Main content area
|
# Main content area
|
||||||
st.markdown('<p style="font-size: 20px; font-weight: bold;">🎨 Describe the Meme You Want to Generate</p>', unsafe_allow_html=True)
|
st.markdown('<p class="header-text">🎨 Describe Your Meme Concept</p>', unsafe_allow_html=True)
|
||||||
query = st.text_input("Enter your meme idea (e.g., 'Ilya's SSI quietly looking at the OpenAI vs Deepseek debate while diligently working on ASI')", "")
|
|
||||||
|
|
||||||
if st.button("Generate Meme"):
|
query = st.text_input(
|
||||||
if api_key and query:
|
"Meme Idea Input",
|
||||||
with st.spinner("🤖 Generating your meme... This might take a minute"):
|
placeholder="Example: 'Ilya's SSI quietly looking at the OpenAI vs Deepseek debate while diligently working on ASI'",
|
||||||
try:
|
label_visibility="collapsed"
|
||||||
meme_url = asyncio.run(generate_meme(query, api_key))
|
)
|
||||||
|
|
||||||
if meme_url:
|
if st.button("Generate Meme 🚀"):
|
||||||
st.success("🎉 Meme Generated Successfully!")
|
if not api_key:
|
||||||
st.image(meme_url, caption="Your Generated Meme", use_container_width=True)
|
st.warning(f"Please provide the {model_choice} API key")
|
||||||
|
st.stop()
|
||||||
|
if not query:
|
||||||
|
st.warning("Please enter a meme idea")
|
||||||
|
st.stop()
|
||||||
|
|
||||||
# Display clickable link
|
with st.spinner(f"🧠 {model_choice} is generating your meme..."):
|
||||||
st.markdown(f"**Meme Link:** [Open in ImgFlip]({meme_url})")
|
try:
|
||||||
else:
|
meme_url = asyncio.run(generate_meme(query, model_choice, api_key))
|
||||||
st.error("Could not retrieve meme URL. Please try again.")
|
|
||||||
|
|
||||||
except Exception as e:
|
if meme_url:
|
||||||
st.error(f"Error generating meme: {str(e)}")
|
st.success("✅ Meme Generated Successfully!")
|
||||||
else:
|
st.image(meme_url, caption="Generated Meme Preview", use_container_width=True)
|
||||||
st.warning("⚠️ Please provide both API key and meme idea")
|
st.markdown(f"""
|
||||||
|
**Direct Link:** [Open in ImgFlip]({meme_url})
|
||||||
|
**Embed URL:** `{meme_url}`
|
||||||
|
""")
|
||||||
|
else:
|
||||||
|
st.error("❌ Failed to generate meme. Please try again with a different prompt.")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
st.error(f"Error: {str(e)}")
|
||||||
|
st.info("💡 If using OpenAI, ensure your account has GPT-4o access")
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
import asyncio
|
|
||||||
import os
|
|
||||||
|
|
||||||
from dotenv import load_dotenv
|
|
||||||
from langchain_openai import ChatOpenAI
|
|
||||||
from pydantic import SecretStr
|
|
||||||
|
|
||||||
from browser_use import Agent
|
|
||||||
|
|
||||||
# dotenv
|
|
||||||
load_dotenv()
|
|
||||||
|
|
||||||
api_key = os.getenv('DEEPSEEK_API_KEY', '')
|
|
||||||
if not api_key:
|
|
||||||
raise ValueError('DEEPSEEK_API_KEY is not set')
|
|
||||||
|
|
||||||
|
|
||||||
async def run_search():
|
|
||||||
agent = Agent(
|
|
||||||
task=('go to amazon.com, search for laptop, sort by best rating, and give me the price of the first result'),
|
|
||||||
llm=ChatOpenAI(
|
|
||||||
base_url='https://api.deepseek.com/v1',
|
|
||||||
model='deepseek-reasoner',
|
|
||||||
api_key=SecretStr(api_key),
|
|
||||||
),
|
|
||||||
use_vision=False,
|
|
||||||
max_failures=2,
|
|
||||||
max_actions_per_step=1,
|
|
||||||
)
|
|
||||||
|
|
||||||
await agent.run()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
asyncio.run(run_search())
|
|
||||||
Loading…
Reference in a new issue