Merge branch 'Shubhamsaboo:main' into main

This commit is contained in:
Sakalya Mitra 2025-03-24 19:08:33 +05:30 committed by GitHub
commit 51836ad0fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
212 changed files with 14792 additions and 453 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@

147
README.md
View file

@ -1,6 +1,6 @@
<p align="center">
<a href="http://www.theunwindai.com">
<img src="docs/banner/unwind.png" width="600px" alt="Unwind AI">
<img src="docs/banner/unwind_black.png" width="900px" alt="Unwind AI">
</a>
</p>
@ -16,89 +16,122 @@
<hr/>
# 🌟 Awesome LLM Apps
A curated collection of awesome LLM apps built with RAG and AI agents. This repository features LLM apps that use models from OpenAI, Anthropic, Google, and even open-source models like LLaMA that you can run locally on your computer.
<a href="https://trendshift.io/repositories/9876" target="_blank"><img src="https://trendshift.io/api/badge/repositories/9876" alt="Shubhamsaboo%2Fawesome-llm-apps | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
A curated collection of awesome LLM apps built with RAG and AI agents. This repository features LLM apps that use models from OpenAI, Anthropic, Google, and open-source models like DeepSeek, Qwen or Llama that you can run locally on your computer.
## 📑 Table of Contents
- [🤔 Why Awesome LLM Apps?](#-why-awesome-llm-apps)
- [📂 Featured Projects](#-featured-projects)
- **AI Agents**
- [💼 AI Customer Support Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_customer_support_agent)
- [📈 AI Investment Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_investment_agent)
- [🗞️ AI Journalist Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_journalist_agent)
- [📊 AI Finance Agent Team](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_finance_agent_team)
- [💰 AI Personal Finance Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_personal_finance_agent)
- [🛫 AI Travel Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_travel_agent)
- [🎬 AI Movie Production Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_movie_production_agent)
- [📰 Multi-Agent AI Researcher](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/multi_agent_researcher)
- [📑 AI Meeting Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_meeting_agent)
- [🌐 Local News Agent OpenAI Swarm](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/local_news_agent_openai_swarm)
- **RAG (Retrieval Augmented Generation)**
- [🔍 Autonomous RAG](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/rag_tutorials/autonomous_rag)
- [🔗 Agentic RAG](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/rag_tutorials/agentic_rag)
- [🔄 Llama3.1 Local RAG](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/rag_tutorials/llama3.1_local_rag)
- [🧩 RAG-as-a-Service](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/rag_tutorials/rag-as-a-service)
- **LLM Apps with Memory**
- [💾 AI Arxiv Agent with Memory](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/llm_apps_with_memory_tutorials/ai_arxiv_agent_memory)
- [📝 LLM App with Personalized Memory](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/llm_apps_with_memory_tutorials/llm_app_personalized_memory)
- [🛩️ AI Travel Agent with Memory](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/llm_apps_with_memory_tutorials/ai_travel_agent_memory)
- [🗄️ Local ChatGPT with Memory](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/llm_apps_with_memory_tutorials/local_chatgpt_with_memory)
- **Chat with X**
- [💬 Chat with GitHub Repo](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/chat_with_X_tutorials/chat_with_github)
- [📨 Chat with Gmail](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/chat_with_X_tutorials/chat_with_gmail)
- [📄 Chat with PDF](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/chat_with_X_tutorials/chat_with_pdf)
- [📚 Chat with Research Papers](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/chat_with_X_tutorials/chat_with_research_papers)
- [📝 Chat with Substack Newsletter](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/chat_with_X_tutorials/chat_with_substack)
- [📽️ Chat with YouTube Videos](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/chat_with_X_tutorials/chat_with_youtube_videos)
- **LLM Finetuning**
- [🌐 Llama3.2 Finetuning](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/llm_finetuning_tutorials/llama3.2_finetuning)
- **Advanced Tools and Frameworks**
- [🧪 Gemini Multimodal Chatbot](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/advanced_tools_frameworks/gemini_multimodal_chatbot)
- [🔄 Mixture of Agents](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/advanced_tools_frameworks/mixture_of_agents)
- [🌐 MultiLLM Chat Playground](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/advanced_tools_frameworks/multillm_chat_playground)
- [🔗 LLM Router App](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/advanced_tools_frameworks/llm_router_app)
- [💬 Local ChatGPT Clone](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/advanced_tools_frameworks/local_chatgpt_clone)
- [🌍 Web Scraping AI Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/advanced_tools_frameworks/web_scrapping_ai_agent)
- [🔍 Web Search AI Assistant](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/advanced_tools_frameworks/web_search_ai_assistant)
- [🧪 Cursor AI Experiments](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/advanced_tools_frameworks/cursor_ai_experiments)
- [🚀 Getting Started](#-getting-started)
- [🤝 Contributing to Opensource](#-contributing-to-opensource)
<p align="center">
<a href="https://trendshift.io/repositories/9876" target="_blank">
<img src="https://trendshift.io/api/badge/repositories/9876" alt="Shubhamsaboo%2Fawesome-llm-apps | Trendshift" style="width: 250px; height: 55px;" />
</a>
</p>
## 🤔 Why Awesome LLM Apps?
- 💡 Discover practical and creative ways LLMs can be applied across different domains, from code repositories to email inboxes and more.
- 🔥 Explore apps that combine LLMs from OpenAI, Anthropic, Gemini, and open-source alternatives with RAG and AI Agents.
- 🎓 Learn from well-documented projects and contribute to the growing open-source ecosystem of LLM-powered applications.
## 📂 Featured AI Projects
### AI Agents
- [💼 AI Customer Support Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_customer_support_agent)
- [📈 AI Investment Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_investment_agent)
- [👨‍⚖️ AI Legal Agent Team](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_legal_agent_team)
- [💼 AI Recruitment Agent Team](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_recruitment_agent_team)
- [👨‍💼 AI Services Agency](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_services_agency)
- [🧲 AI Competitor Intelligence Agent Team](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_competitor_intelligence_agent_team)
- [🏋️‍♂️ AI Health & Fitness Planner Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_health_fitness_agent)
- [📈 AI Startup Trend Analysis Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_startup_trend_analysis_agent)
- [🗞️ AI Journalist Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_journalist_agent)
- [💲 AI Finance Agent Team](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_finance_agent_team)
- [🧲 AI Competitor Intelligence Agent Team](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_competitor_intelligence_agent_team)
- [🎯 AI Lead Generation Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_lead_generation_agent)
- [💰 AI Personal Finance Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_personal_finance_agent)
- [🩻 AI Medical Scan Diagnosis Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_medical_imaging_agent)
- [👨‍🏫 AI Teaching Agent Team](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_teaching_agent_team)
- [🛫 AI Travel Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_travel_agent)
- [🎬 AI Movie Production Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_movie_production_agent)
- [📰 Multi-Agent AI Researcher](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/multi_agent_researcher)
- [💻 Multimodal AI Coding Agent Team with o3-mini and Gemini](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_coding_agent_o3-mini)
- [📑 AI Meeting Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_meeting_agent)
- [♜ AI Chess Agent Game](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_chess_agent)
- [🏠 AI Real Estate Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_real_estate_agent)
- [🌐 Local News Agent OpenAI Swarm](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/local_news_agent_openai_swarm)
- [📊 AI Finance Agent with xAI Grok](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/xai_finance_agent)
- [🎮 AI 3D PyGame Visualizer with DeepSeek R1](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_3dpygame_r1)
- [🧠 AI Reasoning Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/ai_reasoning_agent)
- [🧬 Multimodal AI Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/ai_agent_tutorials/multimodal_ai_agent)
### RAG (Retrieval Augmented Generation)
- [🔍 Autonomous RAG](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/rag_tutorials/autonomous_rag)
- [🔗 Agentic RAG](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/rag_tutorials/agentic_rag)
- [🤔 Agentic RAG with Gemini Flash Thinking](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/rag_tutorials/gemini_agentic_rag)
- [🐋 Deepseek Local RAG Reasoning Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/rag_tutorials/deepseek_local_rag_agent)
- [🔄 Llama3.1 Local RAG](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/rag_tutorials/llama3.1_local_rag)
- [🧩 RAG-as-a-Service](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/rag_tutorials/rag-as-a-service)
- [🦙 Local RAG Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/rag_tutorials/local_rag_agent)
- [👀 RAG App with Hybrid Search](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/rag_tutorials/hybrid_search_rag)
- [🖥️ Local RAG App with Hybrid Search](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/rag_tutorials/local_hybrid_search_rag)
- [📠 RAG Agent with Database Routing](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/rag_tutorials/rag_database_routing)
- [🔄 Corrective RAG Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/rag_tutorials/corrective_rag)
### MCP AI Agents
- [🐙 MCP GitHub Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/mcp_ai_agents/github_mcp_agent)
### LLM Apps with Memory
- [💾 AI Arxiv Agent with Memory](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/llm_apps_with_memory_tutorials/ai_arxiv_agent_memory)
- [📝 LLM App with Personalized Memory](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/llm_apps_with_memory_tutorials/llm_app_personalized_memory)
- [🛩️ AI Travel Agent with Memory](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/llm_apps_with_memory_tutorials/ai_travel_agent_memory)
- [🗄️ Local ChatGPT with Memory](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/llm_apps_with_memory_tutorials/local_chatgpt_with_memory)
### Chat with X
- [💬 Chat with GitHub Repo](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/chat_with_X_tutorials/chat_with_github)
- [📨 Chat with Gmail](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/chat_with_X_tutorials/chat_with_gmail)
- [📄 Chat with PDF](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/chat_with_X_tutorials/chat_with_pdf)
- [📚 Chat with Research Papers](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/chat_with_X_tutorials/chat_with_research_papers)
- [📝 Chat with Substack Newsletter](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/chat_with_X_tutorials/chat_with_substack)
- [📽️ Chat with YouTube Videos](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/chat_with_X_tutorials/chat_with_youtube_videos)
### LLM Finetuning
- [🌐 Llama3.2 Finetuning](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/llm_finetuning_tutorials/llama3.2_finetuning)
### Advanced Tools and Frameworks
- [🧪 Gemini Multimodal Chatbot](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/advanced_tools_frameworks/gemini_multimodal_chatbot)
- [🔄 Mixture of Agents](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/advanced_tools_frameworks/mixture_of_agents)
- [🌐 MultiLLM Chat Playground](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/advanced_tools_frameworks/multillm_chat_playground)
- [🔗 LLM Router App](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/advanced_tools_frameworks/llm_router_app)
- [💬 Local ChatGPT Clone](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/advanced_tools_frameworks/local_chatgpt_clone)
- [🌍 Web Scraping AI Agent](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/advanced_tools_frameworks/web_scrapping_ai_agent)
- [🔍 Web Search AI Assistant](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/advanced_tools_frameworks/web_search_ai_assistant)
- [🧪 Cursor AI Experiments](https://github.com/Shubhamsaboo/awesome-llm-apps/tree/main/advanced_tools_frameworks/cursor_ai_experiments)
## 🚀 Getting Started
1. Clone the repository
1. **Clone the repository**
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
```
2. Navigate to the desired project directory
2. **Navigate to the desired project directory**
```bash
cd awesome-llm-apps/chat_with_gmail
cd awesome-llm-apps/chat_with_X_tutorials/chat_with_gmail
```
3. Install the required dependencies
3. **Install the required dependencies**
```bash
pip install -r requirements.txt
```
4. Follow the project-specific instructions in each project's README.md file to set up and run the app.
4. **Follow the project-specific instructions** in each project's `README.md` file to set up and run the app.
## 🤝 Contributing to Opensource
Contributions are welcome! If you have any ideas, improvements, or new apps to add, please create a new [GitHub Issue](https://github.com/Shubhamsaboo/awesome-llm-apps/issues) or submit a pull request. Make sure to follow the existing project structure and include a detailed README.md for each new app.
## 🤝 Contributing to Open Source
### Thank you community for the support 🙏
Contributions are welcome! If you have any ideas, improvements, or new apps to add, please create a new [GitHub Issue](https://github.com/Shubhamsaboo/awesome-llm-apps/issues) or submit a pull request. Make sure to follow the existing project structure and include a detailed `README.md` for each new app.
### Thank You, Community, for the Support! 🙏
[![Star History Chart](https://api.star-history.com/svg?repos=Shubhamsaboo/awesome-llm-apps&type=Date)](https://star-history.com/#Shubhamsaboo/awesome-llm-apps&Date)

View file

@ -7,6 +7,17 @@ import os
gpt4_model = None
def create_article_crew(topic):
"""Creates a team of agents to research, write, and edit an article on a given topic.
This function sets up a crew consisting of three agents: a researcher, a writer, and an editor.
Each agent is assigned a specific task to ensure the production of a well-researched,
well-written, and polished article. The article is formatted using markdown standards.
Args:
topic (str): The subject matter on which the article will be based.
Returns:
Crew: A crew object that contains the agents and tasks necessary to complete the article."""
# Create agents
researcher = Agent(
role='Researcher',

View file

@ -0,0 +1,7 @@
scrapegraphai
playwright
langchain-community
streamlit-chat
streamlit
crewai
ollama

View file

@ -12,6 +12,7 @@ This repository contains a Streamlit application that demonstrates a multimodal
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/advanced_tools_frameworks/gemini_multimodal_chatbot
```
2. Install the required dependencies:

View file

@ -16,6 +16,7 @@ This Streamlit application demonstrates the use of RouteLLM, a system that intel
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/advanced_tools_frameworks/llm_router_app
```
2. Install the required dependencies:

View file

@ -1,2 +1,3 @@
streamlit
"routellm[serve,eval]"
"routellm[serve,eval]"
routellm

View file

@ -12,6 +12,7 @@ This project demonstrates how to build a ChatGPT clone using the Llama-3 model r
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/advanced_tools_frameworks/local_chatgpt_clone
```
2. Install the required dependencies:

View file

@ -13,7 +13,7 @@ This Streamlit app demonstrates function calling with the local Llama3 model usi
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd local-llama3-tool-use
cd awesome-llm-apps/advanced_tools_frameworks/local_llama3.1_tool_use
```
2. Install the required dependencies:

View file

@ -1,9 +1,9 @@
import streamlit as st
import os
from phi.assistant import Assistant
from phi.llm.ollama import Ollama
from phi.tools.yfinance import YFinanceTools
from phi.tools.serpapi_tools import SerpApiTools
from agno.agent import Agent
from agno.models.ollama import Ollama
from agno.tools.yfinance import YFinanceTools
from agno.tools.serpapi import SerpApiTools
st.set_page_config(page_title="Llama-3 Tool Use", page_icon="🦙")
@ -13,9 +13,21 @@ if 'SERPAPI_API_KEY' not in os.environ:
st.stop()
def get_assistant(tools):
return Assistant(
"""Creates and returns a configured assistant agent.
This function initializes an assistant agent with a specific model and toolset.
The assistant is capable of accessing tools selected by the user and includes
additional features such as showing tool call details, running in debug mode,
and appending the current datetime to its instructions.
Args:
tools (list): A list of tools that the assistant can access.
Returns:
Agent: A configured assistant agent with specified capabilities and settings."""
return Agent(
name="llama3_assistant",
llm=Ollama(model="llama3"),
model=Ollama(id="llama3.1:8b"),
tools=tools,
description="You are a helpful assistant that can access specific tools based on user selection.",
show_tool_calls=True,
@ -25,7 +37,7 @@ def get_assistant(tools):
)
st.title("🦙 Local Llama-3 Tool Use")
st.title("🦙 Local Llama-3.1 Tool Use")
st.markdown("""
This app demonstrates function calling with the local Llama3 model using Ollama.
Select tools in the sidebar and ask relevant questions!

View file

@ -1,3 +1,3 @@
streamlit
ollama
phidata
agno

View file

@ -12,6 +12,7 @@ This Streamlit app allows you to scrape a website using OpenAI API and the scrap
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/advanced_tools_frameworks/web_scrapping_ai_agent
```
2. Install the required dependencies:

View file

@ -12,6 +12,7 @@ This Streamlit app combines the power of search engines and LLMs to provide you
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/advanced_tools_frameworks/web_search_ai_assistant
```
2. Install the required dependencies:

View file

@ -1,8 +1,8 @@
# Import the required libraries
import streamlit as st
from phi.assistant import Assistant
from phi.tools.duckduckgo import DuckDuckGo
from phi.llm.anthropic import Claude
from agno.agent import Agent
from agno.tools.duckduckgo import DuckDuckGoTools
from agno.models.anthropic import Claude
# Set up the Streamlit app
st.title("Claude Sonnet + AI Web Search 🤖")
@ -13,12 +13,12 @@ anthropic_api_key = st.text_input("Anthropic's Claude API Key", type="password")
# If Anthropic API key is provided, create an instance of Assistant
if anthropic_api_key:
assistant = Assistant(
llm=Claude(
model="claude-3-5-sonnet-20240620",
assistant = Agent(
model=Claude(
id="claude-3-5-sonnet-20240620",
max_tokens=1024,
temperature=0.9,
api_key=anthropic_api_key) , tools=[DuckDuckGo()], show_tool_calls=True
temperature=0.3,
api_key=anthropic_api_key) , tools=[DuckDuckGoTools()], show_tool_calls=True
)
# Get the search query from the user
query= st.text_input("Enter the Search Query", type="default")
@ -26,4 +26,4 @@ if anthropic_api_key:
if query:
# Search the web using the AI Assistant
response = assistant.run(query, stream=False)
st.write(response)
st.write(response.content)

View file

@ -1,8 +1,8 @@
# Import the required libraries
import streamlit as st
from phi.assistant import Assistant
from phi.tools.duckduckgo import DuckDuckGo
from phi.llm.openai import OpenAIChat
from agno.agent import Agent
from agno.tools.duckduckgo import DuckDuckGoTools
from agno.models.openai import OpenAIChat
# Set up the Streamlit app
st.title("AI Web Search Assistant 🤖")
@ -14,12 +14,12 @@ openai_access_token = st.text_input("OpenAI API Key", type="password")
# If OpenAI API key is provided, create an instance of Assistant
if openai_access_token:
# Create an instance of the Assistant
assistant = Assistant(
llm=OpenAIChat(
model="gpt-4o",
assistant = Agent(
model=OpenAIChat(
id="gpt-4o",
max_tokens=1024,
temperature=0.9,
api_key=openai_access_token) , tools=[DuckDuckGo()], show_tool_calls=True
api_key=openai_access_token) , tools=[DuckDuckGoTools()], show_tool_calls=True
)
# Get the search query from the user
@ -28,4 +28,4 @@ if openai_access_token:
if query:
# Search the web using the AI Assistant
response = assistant.run(query, stream=False)
st.write(response)
st.write(response.content)

View file

@ -1,4 +1,4 @@
streamlit
openai
phidata
agno
duckduckgo-search

View file

@ -0,0 +1,50 @@
# 🎮 AI 3D PyGame Visualizer with DeepSeek R1
This Project demonstrates R1's code capabilities with a PyGame code generator and visualizer with browser use. The system uses DeepSeek for reasoning, OpenAI for code extraction, and browser automation agents to visualize the code on Trinket.io.
### Features
- Generates PyGame code from natural language descriptions
- Uses DeepSeek Reasoner for code logic and explanation
- Extracts clean code using OpenAI GPT-4o
- Automates code visualization on Trinket.io using browser agents
- Provides a streamlined Streamlit interface
- Multi-agent system for handling different tasks (navigation, coding, execution, viewing)
### How to get Started?
1. Clone the GitHub repository
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/ai_agent_tutorials/ai_3dpygame_r1
```
2. Install the required dependencies:
```bash
pip install -r requirements.txt
```
3. Get your API Keys
- Sign up for [DeepSeek](https://platform.deepseek.com/) and obtain your API key
- Sign up for [OpenAI](https://platform.openai.com/) and obtain your API key
4. Run the AI PyGame Visualizer
```bash
streamlit run ai_3dpygame_r1.py
```
5. Browser use automatically opens your web browser and navigate to the URL provided in the console output to interact with the PyGame generator.
### How it works?
1. **Query Processing:** User enters a natural language description of the desired PyGame visualization.
2. **Code Generation:**
- DeepSeek Reasoner analyzes the query and provides detailed reasoning with code
- OpenAI agent extracts clean, executable code from the reasoning
3. **Visualization:**
- Browser agents automate the process of running code on Trinket.io
- Multiple specialized agents handle different tasks:
- Navigation to Trinket.io
- Code input
- Execution
- Visualization viewing
4. **User Interface:** Streamlit provides an intuitive interface for entering queries, viewing code, and managing the visualization process.

View file

@ -0,0 +1,173 @@
import streamlit as st
from openai import OpenAI
from agno.agent import Agent as AgnoAgent
from agno.models.openai import OpenAIChat as AgnoOpenAIChat
from langchain_openai import ChatOpenAI
import asyncio
from browser_use import Browser
st.set_page_config(page_title="PyGame Code Generator", layout="wide")
# Initialize session state
if "api_keys" not in st.session_state:
st.session_state.api_keys = {
"deepseek": "",
"openai": ""
}
# Streamlit sidebar for API keys
with st.sidebar:
st.title("API Keys Configuration")
st.session_state.api_keys["deepseek"] = st.text_input(
"DeepSeek API Key",
type="password",
value=st.session_state.api_keys["deepseek"]
)
st.session_state.api_keys["openai"] = st.text_input(
"OpenAI API Key",
type="password",
value=st.session_state.api_keys["openai"]
)
st.markdown("---")
st.info("""
📝 How to use:
1. Enter your API keys above
2. Write your PyGame visualization query
3. Click 'Generate Code' to get the code
4. Click 'Generate Visualization' to:
- Open Trinket.io PyGame editor
- Copy and paste the generated code
- Watch it run automatically
""")
# Main UI
st.title("🎮 AI 3D Visualizer with DeepSeek R1")
example_query = "Create a particle system simulation where 100 particles emit from the mouse position and respond to keyboard-controlled wind forces"
query = st.text_area(
"Enter your PyGame query:",
height=70,
placeholder=f"e.g.: {example_query}"
)
# Split the buttons into columns
col1, col2 = st.columns(2)
generate_code_btn = col1.button("Generate Code")
generate_vis_btn = col2.button("Generate Visualization")
if generate_code_btn and query:
if not st.session_state.api_keys["deepseek"] or not st.session_state.api_keys["openai"]:
st.error("Please provide both API keys in the sidebar")
st.stop()
# Initialize Deepseek client
deepseek_client = OpenAI(
api_key=st.session_state.api_keys["deepseek"],
base_url="https://api.deepseek.com"
)
system_prompt = """You are a Pygame and Python Expert that specializes in making games and visualisation through pygame and python programming.
During your reasoning and thinking, include clear, concise, and well-formatted Python code in your reasoning.
Always include explanations for the code you provide."""
try:
# Get reasoning from Deepseek
with st.spinner("Generating solution..."):
deepseek_response = deepseek_client.chat.completions.create(
model="deepseek-reasoner",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": query}
],
max_tokens=1
)
reasoning_content = deepseek_response.choices[0].message.reasoning_content
print("\nDeepseek Reasoning:\n", reasoning_content)
with st.expander("R1's Reasoning"):
st.write(reasoning_content)
# Initialize Claude agent (using PhiAgent)
openai_agent = AgnoAgent(
model=AgnoOpenAIChat(
id="gpt-4o",
api_key=st.session_state.api_keys["openai"]
),
show_tool_calls=True,
markdown=True
)
# Extract code
extraction_prompt = f"""Extract ONLY the Python code from the following content which is reasoning of a particular query to make a pygame script.
Return nothing but the raw code without any explanations, or markdown backticks:
{reasoning_content}"""
with st.spinner("Extracting code..."):
code_response = openai_agent.run(extraction_prompt)
extracted_code = code_response.content
# Store the generated code in session state
st.session_state.generated_code = extracted_code
# Display the code
with st.expander("Generated PyGame Code", expanded=True):
st.code(extracted_code, language="python")
st.success("Code generated successfully! Click 'Generate Visualization' to run it.")
except Exception as e:
st.error(f"An error occurred: {str(e)}")
elif generate_vis_btn:
if "generated_code" not in st.session_state:
st.warning("Please generate code first before visualization")
else:
async def run_pygame_on_trinket(code: str) -> None:
browser = Browser()
from browser_use import Agent
async with await browser.new_context() as context:
model = ChatOpenAI(
model="gpt-4o",
api_key=st.session_state.api_keys["openai"]
)
agent1 = Agent(
task='Go to https://trinket.io/features/pygame, thats your only job.',
llm=model,
browser_context=context,
)
executor = Agent(
task='Executor. Execute the code written by the User by clicking on the run button on the right. ',
llm=model,
browser_context=context
)
coder = Agent(
task='Coder. Your job is to wait for the user for 10 seconds to write the code in the code editor.',
llm=model,
browser_context=context
)
viewer = Agent(
task='Viewer. Your job is to just view the pygame window for 10 seconds.',
llm=model,
browser_context=context,
)
with st.spinner("Running code on Trinket..."):
try:
await agent1.run()
await coder.run()
await executor.run()
await viewer.run()
st.success("Code is running on Trinket!")
except Exception as e:
st.error(f"Error running code on Trinket: {str(e)}")
st.info("You can still copy the code above and run it manually on Trinket")
# Run the async function with the stored code
asyncio.run(run_pygame_on_trinket(st.session_state.generated_code))
elif generate_code_btn and not query:
st.warning("Please enter a query before generating code")

View file

@ -0,0 +1,4 @@
agno
langchain-openai
browser-use
streamlit

View file

@ -0,0 +1,81 @@
# 🌍 AQI Analysis Agent
The AQI Analysis Agent is a powerful air quality monitoring and health recommendation tool powered by Firecrawl and Agno's AI Agent framework. This app helps users make informed decisions about outdoor activities by analyzing real-time air quality data and providing personalized health recommendations.
## Features
- **Multi-Agent System**
- **AQI Analyzer**: Fetches and processes real-time air quality data
- **Health Recommendation Agent**: Generates personalized health advice
- **Air Quality Metrics**:
- Overall Air Quality Index (AQI)
- Particulate Matter (PM2.5 and PM10)
- Carbon Monoxide (CO) levels
- Temperature
- Humidity
- Wind Speed
- **Comprehensive Analysis**:
- Real-time data visualization
- Health impact assessment
- Activity safety recommendations
- Best time suggestions for outdoor activities
- Weather condition correlations
- **Interactive Features**:
- Location-based analysis
- Medical condition considerations
- Activity-specific recommendations
- Downloadable reports
- Example queries for quick testing
## How to Run
Follow these steps to set up and run the application:
1. **Clone the Repository**:
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd ai_agent_tutorials/ai_aqi_analysis_agent
```
2. **Install the dependencies**:
```bash
pip install -r requirements.txt
```
3. **Set up your API keys**:
- Get an OpenAI API key from: https://platform.openai.com/api-keys
- Get a Firecrawl API key from: [Firecrawl website](https://www.firecrawl.dev/app/api-keys)
4. **Run the Gradio app**:
```bash
python ai_aqi_analysis_agent.py
```
5. **Access the Web Interface**:
- The terminal will display two URLs:
- Local URL: `http://127.0.0.1:7860` (for local access)
- Public URL: `https://xxx-xxx-xxx.gradio.live` (for temporary public access)
- Click on either URL to open the web interface in your browser
## Usage
1. Enter your API keys in the API Configuration section
2. Input location details:
- City name
- State (optional for Union Territories/US cities)
- Country
3. Provide personal information:
- Medical conditions (optional)
- Planned outdoor activity
4. Click "Analyze & Get Recommendations" to receive:
- Current air quality data
- Health impact analysis
- Activity safety recommendations
5. Try the example queries for quick testing
## Note
The air quality data is fetched using Firecrawl's web scraping capabilities. Due to caching and rate limiting, the data might not always match real-time values on the website. For the most accurate real-time data, consider checking the source website directly.

View file

@ -0,0 +1,272 @@
from typing import Dict, Optional
from dataclasses import dataclass
from pydantic import BaseModel, Field
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from firecrawl import FirecrawlApp
import gradio as gr
import json
class AQIResponse(BaseModel):
success: bool
data: Dict[str, float]
status: str
expiresAt: str
class ExtractSchema(BaseModel):
aqi: float = Field(description="Air Quality Index")
temperature: float = Field(description="Temperature in degrees Celsius")
humidity: float = Field(description="Humidity percentage")
wind_speed: float = Field(description="Wind speed in kilometers per hour")
pm25: float = Field(description="Particulate Matter 2.5 micrometers")
pm10: float = Field(description="Particulate Matter 10 micrometers")
co: float = Field(description="Carbon Monoxide level")
@dataclass
class UserInput:
city: str
state: str
country: str
medical_conditions: Optional[str]
planned_activity: str
class AQIAnalyzer:
def __init__(self, firecrawl_key: str) -> None:
self.firecrawl = FirecrawlApp(api_key=firecrawl_key)
def _format_url(self, country: str, state: str, city: str) -> str:
"""Format URL based on location, handling cases with and without state"""
country_clean = country.lower().replace(' ', '-')
city_clean = city.lower().replace(' ', '-')
if not state or state.lower() == 'none':
return f"https://www.aqi.in/dashboard/{country_clean}/{city_clean}"
state_clean = state.lower().replace(' ', '-')
return f"https://www.aqi.in/dashboard/{country_clean}/{state_clean}/{city_clean}"
def fetch_aqi_data(self, city: str, state: str, country: str) -> tuple[Dict[str, float], str]:
"""Fetch AQI data using Firecrawl"""
try:
url = self._format_url(country, state, city)
info_msg = f"Accessing URL: {url}"
response = self.firecrawl.extract(
urls=[f"{url}/*"],
params={
'prompt': 'Extract the current real-time AQI, temperature, humidity, wind speed, PM2.5, PM10, and CO levels from the page. Also extract the timestamp of the data.',
'schema': ExtractSchema.model_json_schema()
}
)
aqi_response = AQIResponse(**response)
if not aqi_response.success:
raise ValueError(f"Failed to fetch AQI data: {aqi_response.status}")
return aqi_response.data, info_msg
except Exception as e:
error_msg = f"Error fetching AQI data: {str(e)}"
return {
'aqi': 0,
'temperature': 0,
'humidity': 0,
'wind_speed': 0,
'pm25': 0,
'pm10': 0,
'co': 0
}, error_msg
class HealthRecommendationAgent:
def __init__(self, openai_key: str) -> None:
self.agent = Agent(
model=OpenAIChat(
id="gpt-4o",
name="Health Recommendation Agent",
api_key=openai_key
)
)
def get_recommendations(
self,
aqi_data: Dict[str, float],
user_input: UserInput
) -> str:
prompt = self._create_prompt(aqi_data, user_input)
response = self.agent.run(prompt)
return response.content
def _create_prompt(self, aqi_data: Dict[str, float], user_input: UserInput) -> str:
return f"""
Based on the following air quality conditions in {user_input.city}, {user_input.state}, {user_input.country}:
- Overall AQI: {aqi_data['aqi']}
- PM2.5 Level: {aqi_data['pm25']} µg/
- PM10 Level: {aqi_data['pm10']} µg/
- CO Level: {aqi_data['co']} ppb
Weather conditions:
- Temperature: {aqi_data['temperature']}°C
- Humidity: {aqi_data['humidity']}%
- Wind Speed: {aqi_data['wind_speed']} km/h
User's Context:
- Medical Conditions: {user_input.medical_conditions or 'None'}
- Planned Activity: {user_input.planned_activity}
**Comprehensive Health Recommendations:**
1. **Impact of Current Air Quality on Health:**
2. **Necessary Safety Precautions for Planned Activity:**
3. **Advisability of Planned Activity:**
4. **Best Time to Conduct the Activity:**
"""
def analyze_conditions(
city: str,
state: str,
country: str,
medical_conditions: str,
planned_activity: str,
firecrawl_key: str,
openai_key: str
) -> tuple[str, str, str, str]:
"""Analyze conditions and return AQI data, recommendations, and status messages"""
try:
# Initialize analyzers
aqi_analyzer = AQIAnalyzer(firecrawl_key=firecrawl_key)
health_agent = HealthRecommendationAgent(openai_key=openai_key)
# Create user input
user_input = UserInput(
city=city,
state=state,
country=country,
medical_conditions=medical_conditions,
planned_activity=planned_activity
)
# Get AQI data
aqi_data, info_msg = aqi_analyzer.fetch_aqi_data(
city=user_input.city,
state=user_input.state,
country=user_input.country
)
# Format AQI data for display
aqi_json = json.dumps({
"Air Quality Index (AQI)": aqi_data['aqi'],
"PM2.5": f"{aqi_data['pm25']} µg/m³",
"PM10": f"{aqi_data['pm10']} µg/m³",
"Carbon Monoxide (CO)": f"{aqi_data['co']} ppb",
"Temperature": f"{aqi_data['temperature']}°C",
"Humidity": f"{aqi_data['humidity']}%",
"Wind Speed": f"{aqi_data['wind_speed']} km/h"
}, indent=2)
# Get recommendations
recommendations = health_agent.get_recommendations(aqi_data, user_input)
warning_msg = """
Note: The data shown may not match real-time values on the website.
This could be due to:
- Cached data in Firecrawl
- Rate limiting
- Website updates not being captured
Consider refreshing or checking the website directly for real-time values.
"""
return aqi_json, recommendations, info_msg, warning_msg
except Exception as e:
error_msg = f"Error occurred: {str(e)}"
return "", "Analysis failed", error_msg, ""
def create_demo() -> gr.Blocks:
"""Create and configure the Gradio interface"""
with gr.Blocks(title="AQI Analysis Agent") as demo:
gr.Markdown(
"""
# 🌍 AQI Analysis Agent
Get personalized health recommendations based on air quality conditions.
"""
)
# API Configuration
with gr.Accordion("API Configuration", open=False):
firecrawl_key = gr.Textbox(
label="Firecrawl API Key",
type="password",
placeholder="Enter your Firecrawl API key"
)
openai_key = gr.Textbox(
label="OpenAI API Key",
type="password",
placeholder="Enter your OpenAI API key"
)
# Location Details
with gr.Row():
with gr.Column():
city = gr.Textbox(label="City", placeholder="e.g., Mumbai")
state = gr.Textbox(
label="State",
placeholder="Leave blank for Union Territories or US cities",
value=""
)
country = gr.Textbox(label="Country", value="India")
# Personal Details
with gr.Row():
with gr.Column():
medical_conditions = gr.Textbox(
label="Medical Conditions (optional)",
placeholder="e.g., asthma, allergies",
lines=2
)
planned_activity = gr.Textbox(
label="Planned Activity",
placeholder="e.g., morning jog for 2 hours",
lines=2
)
# Status Messages
info_box = gr.Textbox(label=" Status", interactive=False)
warning_box = gr.Textbox(label="⚠️ Warning", interactive=False)
# Output Areas
aqi_data_json = gr.JSON(label="📊 Current Air Quality Data")
recommendations = gr.Markdown(label="🏥 Health Recommendations")
# Analyze Button
analyze_btn = gr.Button("🔍 Analyze & Get Recommendations", variant="primary")
analyze_btn.click(
fn=analyze_conditions,
inputs=[
city,
state,
country,
medical_conditions,
planned_activity,
firecrawl_key,
openai_key
],
outputs=[aqi_data_json, recommendations, info_box, warning_box]
)
# Examples
gr.Examples(
examples=[
["Mumbai", "Maharashtra", "India", "asthma", "morning walk for 30 minutes"],
["Delhi", "", "India", "", "outdoor yoga session"],
["New York", "", "United States", "allergies", "afternoon run"],
["Kakinada", "Andhra Pradesh", "India", "none", "Tennis for 2 hours"]
],
inputs=[city, state, country, medical_conditions, planned_activity]
)
return demo
if __name__ == "__main__":
demo = create_demo()
demo.launch(share=True)

View file

@ -0,0 +1,265 @@
from typing import Dict, Optional
from dataclasses import dataclass
from pydantic import BaseModel, Field
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from firecrawl import FirecrawlApp
import streamlit as st
class AQIResponse(BaseModel):
success: bool
data: Dict[str, float]
status: str
expiresAt: str
class ExtractSchema(BaseModel):
aqi: float = Field(description="Air Quality Index")
temperature: float = Field(description="Temperature in degrees Celsius")
humidity: float = Field(description="Humidity percentage")
wind_speed: float = Field(description="Wind speed in kilometers per hour")
pm25: float = Field(description="Particulate Matter 2.5 micrometers")
pm10: float = Field(description="Particulate Matter 10 micrometers")
co: float = Field(description="Carbon Monoxide level")
@dataclass
class UserInput:
city: str
state: str
country: str
medical_conditions: Optional[str]
planned_activity: str
class AQIAnalyzer:
def __init__(self, firecrawl_key: str) -> None:
self.firecrawl = FirecrawlApp(api_key=firecrawl_key)
def _format_url(self, country: str, state: str, city: str) -> str:
"""Format URL based on location, handling cases with and without state"""
country_clean = country.lower().replace(' ', '-')
city_clean = city.lower().replace(' ', '-')
if not state or state.lower() == 'none':
return f"https://www.aqi.in/dashboard/{country_clean}/{city_clean}"
state_clean = state.lower().replace(' ', '-')
return f"https://www.aqi.in/dashboard/{country_clean}/{state_clean}/{city_clean}"
def fetch_aqi_data(self, city: str, state: str, country: str) -> Dict[str, float]:
"""Fetch AQI data using Firecrawl"""
try:
url = self._format_url(country, state, city)
st.info(f"Accessing URL: {url}") # Display URL being accessed
response = self.firecrawl.extract(
urls=[f"{url}/*"],
params={
'prompt': 'Extract the current real-time AQI, temperature, humidity, wind speed, PM2.5, PM10, and CO levels from the page. Also extract the timestamp of the data.',
'schema': ExtractSchema.model_json_schema()
}
)
aqi_response = AQIResponse(**response)
if not aqi_response.success:
raise ValueError(f"Failed to fetch AQI data: {aqi_response.status}")
with st.expander("📦 Raw AQI Data", expanded=True):
st.json({
"url_accessed": url,
"timestamp": aqi_response.expiresAt,
"data": aqi_response.data
})
st.warning("""
Note: The data shown may not match real-time values on the website.
This could be due to:
- Cached data in Firecrawl
- Rate limiting
- Website updates not being captured
Consider refreshing or checking the website directly for real-time values.
""")
return aqi_response.data
except Exception as e:
st.error(f"Error fetching AQI data: {str(e)}")
return {
'aqi': 0,
'temperature': 0,
'humidity': 0,
'wind_speed': 0,
'pm25': 0,
'pm10': 0,
'co': 0
}
class HealthRecommendationAgent:
def __init__(self, openai_key: str) -> None:
self.agent = Agent(
model=OpenAIChat(
id="gpt-4o",
name="Health Recommendation Agent",
api_key=openai_key
)
)
def get_recommendations(
self,
aqi_data: Dict[str, float],
user_input: UserInput
) -> str:
prompt = self._create_prompt(aqi_data, user_input)
response = self.agent.run(prompt)
return response.content
def _create_prompt(self, aqi_data: Dict[str, float], user_input: UserInput) -> str:
return f"""
Based on the following air quality conditions in {user_input.city}, {user_input.state}, {user_input.country}:
- Overall AQI: {aqi_data['aqi']}
- PM2.5 Level: {aqi_data['pm25']} µg/
- PM10 Level: {aqi_data['pm10']} µg/
- CO Level: {aqi_data['co']} ppb
Weather conditions:
- Temperature: {aqi_data['temperature']}°C
- Humidity: {aqi_data['humidity']}%
- Wind Speed: {aqi_data['wind_speed']} km/h
User's Context:
- Medical Conditions: {user_input.medical_conditions or 'None'}
- Planned Activity: {user_input.planned_activity}
**Comprehensive Health Recommendations:**
1. **Impact of Current Air Quality on Health:**
2. **Necessary Safety Precautions for Planned Activity:**
3. **Advisability of Planned Activity:**
4. **Best Time to Conduct the Activity:**
"""
def analyze_conditions(
user_input: UserInput,
api_keys: Dict[str, str]
) -> str:
aqi_analyzer = AQIAnalyzer(firecrawl_key=api_keys['firecrawl'])
health_agent = HealthRecommendationAgent(openai_key=api_keys['openai'])
aqi_data = aqi_analyzer.fetch_aqi_data(
city=user_input.city,
state=user_input.state,
country=user_input.country
)
return health_agent.get_recommendations(aqi_data, user_input)
def initialize_session_state():
if 'api_keys' not in st.session_state:
st.session_state.api_keys = {
'firecrawl': '',
'openai': ''
}
def setup_page():
st.set_page_config(
page_title="AQI Analysis Agent",
page_icon="🌍",
layout="wide"
)
st.title("🌍 AQI Analysis Agent")
st.info("Get personalized health recommendations based on air quality conditions.")
def render_sidebar():
"""Render sidebar with API configuration"""
with st.sidebar:
st.header("🔑 API Configuration")
new_firecrawl_key = st.text_input(
"Firecrawl API Key",
type="password",
value=st.session_state.api_keys['firecrawl'],
help="Enter your Firecrawl API key"
)
new_openai_key = st.text_input(
"OpenAI API Key",
type="password",
value=st.session_state.api_keys['openai'],
help="Enter your OpenAI API key"
)
if (new_firecrawl_key and new_openai_key and
(new_firecrawl_key != st.session_state.api_keys['firecrawl'] or
new_openai_key != st.session_state.api_keys['openai'])):
st.session_state.api_keys.update({
'firecrawl': new_firecrawl_key,
'openai': new_openai_key
})
st.success("✅ API keys updated!")
def render_main_content():
st.header("📍 Location Details")
col1, col2 = st.columns(2)
with col1:
city = st.text_input("City", placeholder="e.g., Mumbai")
state = st.text_input("State", placeholder="If it's a Union Territory or a city in the US, leave it blank")
country = st.text_input("Country", value="India", placeholder="United States")
with col2:
st.header("👤 Personal Details")
medical_conditions = st.text_area(
"Medical Conditions (optional)",
placeholder="e.g., asthma, allergies"
)
planned_activity = st.text_area(
"Planned Activity",
placeholder="e.g., morning jog for 2 hours"
)
return UserInput(
city=city,
state=state,
country=country,
medical_conditions=medical_conditions,
planned_activity=planned_activity
)
def main():
"""Main application entry point"""
initialize_session_state()
setup_page()
render_sidebar()
user_input = render_main_content()
result = None
if st.button("🔍 Analyze & Get Recommendations"):
if not all([user_input.city, user_input.planned_activity]):
st.error("Please fill in all required fields (state and medical conditions are optional)")
elif not all(st.session_state.api_keys.values()):
st.error("Please provide both API keys in the sidebar")
else:
try:
with st.spinner("🔄 Analyzing conditions..."):
result = analyze_conditions(
user_input=user_input,
api_keys=st.session_state.api_keys
)
st.success("✅ Analysis completed!")
except Exception as e:
st.error(f"❌ Error: {str(e)}")
if result:
st.markdown("### 📦 Recommendations")
st.markdown(result)
st.download_button(
"💾 Download Recommendations",
data=result,
file_name=f"aqi_recommendations_{user_input.city}_{user_input.state}.txt",
mime="text/plain"
)
if __name__ == "__main__":
main()

View file

@ -0,0 +1,6 @@
agno
openai
firecrawl-py==1.9.0
gradio==5.9.1
pydantic
dataclasses

View file

@ -0,0 +1,46 @@
# ♜ Agent White vs Agent Black: Chess Game
An advanced Chess game system where two AI agents play chess against each other using Autogen in a streamlit app. It is built with robust move validation and game state management.
## Features
### Multi-Agent Architecture
- Player White: OpenAI-powered strategic decision maker
- Player Black: OpenAI-powered tactical opponent
- Board Proxy: Validation agent for move legality and game state
### Safety & Validation
- Robust move verification system
- Illegal move prevention
- Real-time board state monitoring
- Secure game progression control
### Strategic Gameplay
- AI-powered position evaluation
- Deep tactical analysis
- Dynamic strategy adaptation
- Complete chess ruleset implementation
### How to get Started?
1. Clone the GitHub repository
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd ai_agent_tutorials/ai_chess_game
```
2. Install the required dependencies:
```bash
pip install -r requirements.txt
```
3. Get your OpenAI API Key
- Sign up for an [OpenAI account](https://platform.openai.com/) (or the LLM provider of your choice) and obtain your API key.
4. Run the Streamlit App
```bash
streamlit run ai_chess_agent.py
```

View file

@ -0,0 +1,249 @@
import chess
import chess.svg
import streamlit as st
from autogen import ConversableAgent, register_function
if "openai_api_key" not in st.session_state:
st.session_state.openai_api_key = None
if "board" not in st.session_state:
st.session_state.board = chess.Board()
if "made_move" not in st.session_state:
st.session_state.made_move = False
if "board_svg" not in st.session_state:
st.session_state.board_svg = None
if "move_history" not in st.session_state:
st.session_state.move_history = []
if "max_turns" not in st.session_state:
st.session_state.max_turns = 5
st.sidebar.title("Chess Agent Configuration")
openai_api_key = st.sidebar.text_input("Enter your OpenAI API key:", type="password")
if openai_api_key:
st.session_state.openai_api_key = openai_api_key
st.sidebar.success("API key saved!")
st.sidebar.info("""
For a complete chess game with potential checkmate, it would take max_turns > 200 approximately.
However, this will consume significant API credits and a lot of time.
For demo purposes, using 5-10 turns is recommended.
""")
max_turns_input = st.sidebar.number_input(
"Enter the number of turns (max_turns):",
min_value=1,
max_value=1000,
value=st.session_state.max_turns,
step=1
)
if max_turns_input:
st.session_state.max_turns = max_turns_input
st.sidebar.success(f"Max turns of total chess moves set to {st.session_state.max_turns}!")
st.title("Chess with AutoGen Agents")
def available_moves() -> str:
available_moves = [str(move) for move in st.session_state.board.legal_moves]
return "Available moves are: " + ",".join(available_moves)
def execute_move(move: str) -> str:
try:
chess_move = chess.Move.from_uci(move)
if chess_move not in st.session_state.board.legal_moves:
return f"Invalid move: {move}. Please call available_moves() to see valid moves."
# Update board state
st.session_state.board.push(chess_move)
st.session_state.made_move = True
# Generate and store board visualization
board_svg = chess.svg.board(st.session_state.board,
arrows=[(chess_move.from_square, chess_move.to_square)],
fill={chess_move.from_square: "gray"},
size=400)
st.session_state.board_svg = board_svg
st.session_state.move_history.append(board_svg)
# Get piece information
moved_piece = st.session_state.board.piece_at(chess_move.to_square)
piece_unicode = moved_piece.unicode_symbol()
piece_type_name = chess.piece_name(moved_piece.piece_type)
piece_name = piece_type_name.capitalize() if piece_unicode.isupper() else piece_type_name
# Generate move description
from_square = chess.SQUARE_NAMES[chess_move.from_square]
to_square = chess.SQUARE_NAMES[chess_move.to_square]
move_desc = f"Moved {piece_name} ({piece_unicode}) from {from_square} to {to_square}."
if st.session_state.board.is_checkmate():
winner = 'White' if st.session_state.board.turn == chess.BLACK else 'Black'
move_desc += f"\nCheckmate! {winner} wins!"
elif st.session_state.board.is_stalemate():
move_desc += "\nGame ended in stalemate!"
elif st.session_state.board.is_insufficient_material():
move_desc += "\nGame ended - insufficient material to checkmate!"
elif st.session_state.board.is_check():
move_desc += "\nCheck!"
return move_desc
except ValueError:
return f"Invalid move format: {move}. Please use UCI format (e.g., 'e2e4')."
def check_made_move(msg):
if st.session_state.made_move:
st.session_state.made_move = False
return True
else:
return False
if st.session_state.openai_api_key:
try:
agent_white_config_list = [
{
"model": "gpt-4o-mini",
"api_key": st.session_state.openai_api_key,
},
]
agent_black_config_list = [
{
"model": "gpt-4o-mini",
"api_key": st.session_state.openai_api_key,
},
]
agent_white = ConversableAgent(
name="Agent_White",
system_message="You are a professional chess player and you play as white. "
"First call available_moves() first, to get list of legal available moves. "
"Then call execute_move(move) to make a move.",
llm_config={"config_list": agent_white_config_list, "cache_seed": None},
)
agent_black = ConversableAgent(
name="Agent_Black",
system_message="You are a professional chess player and you play as black. "
"First call available_moves() first, to get list of legal available moves. "
"Then call execute_move(move) to make a move.",
llm_config={"config_list": agent_black_config_list, "cache_seed": None},
)
game_master = ConversableAgent(
name="Game_Master",
llm_config=False,
is_termination_msg=check_made_move,
default_auto_reply="Please make a move.",
human_input_mode="NEVER",
)
register_function(
execute_move,
caller=agent_white,
executor=game_master,
name="execute_move",
description="Call this tool to make a move.",
)
register_function(
available_moves,
caller=agent_white,
executor=game_master,
name="available_moves",
description="Get legal moves.",
)
register_function(
execute_move,
caller=agent_black,
executor=game_master,
name="execute_move",
description="Call this tool to make a move.",
)
register_function(
available_moves,
caller=agent_black,
executor=game_master,
name="available_moves",
description="Get legal moves.",
)
agent_white.register_nested_chats(
trigger=agent_black,
chat_queue=[
{
"sender": game_master,
"recipient": agent_white,
"summary_method": "last_msg",
}
],
)
agent_black.register_nested_chats(
trigger=agent_white,
chat_queue=[
{
"sender": game_master,
"recipient": agent_black,
"summary_method": "last_msg",
}
],
)
st.info("""
This chess game is played between two AG2 AI agents:
- **Agent White**: A GPT-4o-mini powered chess player controlling white pieces
- **Agent Black**: A GPT-4o-mini powered chess player controlling black pieces
The game is managed by a **Game Master** that:
- Validates all moves
- Updates the chess board
- Manages turn-taking between players
- Provides legal move information
""")
initial_board_svg = chess.svg.board(st.session_state.board, size=300)
st.subheader("Initial Board")
st.image(initial_board_svg)
if st.button("Start Game"):
st.session_state.board.reset()
st.session_state.made_move = False
st.session_state.move_history = []
st.session_state.board_svg = chess.svg.board(st.session_state.board, size=300)
st.info("The AI agents will now play against each other. Each agent will analyze the board, "
"request legal moves from the Game Master (proxy agent), and make strategic decisions.")
st.success("You can view the interaction between the agents in the terminal output, after the turns between agents end, you get view all the chess board moves displayed below!")
st.write("Game started! White's turn.")
chat_result = agent_black.initiate_chat(
recipient=agent_white,
message="Let's play chess! You go first, its your move.",
max_turns=st.session_state.max_turns,
summary_method="reflection_with_llm"
)
st.markdown(chat_result.summary)
# Display the move history (boards for each move)
st.subheader("Move History")
for i, move_svg in enumerate(st.session_state.move_history):
# Determine which agent made the move
if i % 2 == 0:
move_by = "Agent White" # Even-indexed moves are by White
else:
move_by = "Agent Black" # Odd-indexed moves are by Black
st.write(f"Move {i + 1} by {move_by}")
st.image(move_svg)
if st.button("Reset Game"):
st.session_state.board.reset()
st.session_state.made_move = False
st.session_state.move_history = []
st.session_state.board_svg = None
st.write("Game reset! Click 'Start Game' to begin a new game.")
except Exception as e:
st.error(f"An error occurred: {e}. Please check your API key and try again.")
else:
st.warning("Please enter your OpenAI API key in the sidebar to start the game.")

View file

@ -0,0 +1,5 @@
streamlit
chess==1.11.1
autogen==0.6.1
cairosvg
pillow

View file

@ -0,0 +1,61 @@
# 💻 Multimodal AI Coding Agent Team with o3-mini and Gemini
An AI Powered Streamlit application that serves as your personal coding assistant, powered by multiple Agents built on the new o3-mini model. You can also upload an image of a coding problem or describe it in text, and the AI agent will analyze, generate an optimal solution, and execute it in a sandbox environment.
## Features
#### Multi-Modal Problem Input
- Upload images of coding problems (supports PNG, JPG, JPEG)
- Type problems in natural language
- Automatic problem extraction from images
- Interactive problem processing
#### Intelligent Code Generation
- Optimal solution generation with best time/space complexity
- Clean, documented Python code output
- Type hints and proper documentation
- Edge case handling
#### Secure Code Execution
- Sandboxed code execution environment
- Real-time execution results
- Error handling and explanations
- 30-second execution timeout protection
#### Multi-Agent Architecture
- Vision Agent (Gemini-2.0-flash) for image processing
- Coding Agent (OpenAI- o3-mini) for solution generation
- Execution Agent (OpenAI) for code running and result analysis
- E2B Sandbox for secure code execution
## How to Run
Follow the steps below to set up and run the application:
- Get an OpenAI API key from: https://platform.openai.com/
- Get a Google (Gemini) API key from: https://makersuite.google.com/app/apikey
- Get an E2B API key from: https://e2b.dev/docs/getting-started/api-key
1. **Clone the Repository**
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd ai_agent_tutorials/ai_coding_agent_o3-mini
```
2. **Install the dependencies**
```bash
pip install -r requirements.txt
```
3. **Run the Streamlit app**
```bash
streamlit run ai_coding_agent_o3.py
```
4. **Configure API Keys**
- Enter your API keys in the sidebar
- All three keys (OpenAI, Gemini, E2B) are required for full functionality
## Usage
1. Upload an image of a coding problem OR type your problem description
2. Click "Generate & Execute Solution"
3. View the generated solution with full documentation
4. See execution results and any generated files
5. Review any error messages or execution timeouts

View file

@ -0,0 +1,280 @@
from typing import Optional, Dict, Any
import streamlit as st
from agno.agent import Agent, RunResponse
from agno.models.openai import OpenAIChat
from agno.models.google import Gemini
from e2b_code_interpreter import Sandbox
import os
from PIL import Image
from io import BytesIO
import base64
def initialize_session_state() -> None:
if 'openai_key' not in st.session_state:
st.session_state.openai_key = ''
if 'gemini_key' not in st.session_state:
st.session_state.gemini_key = ''
if 'e2b_key' not in st.session_state:
st.session_state.e2b_key = ''
if 'sandbox' not in st.session_state:
st.session_state.sandbox = None
def setup_sidebar() -> None:
with st.sidebar:
st.title("API Configuration")
st.session_state.openai_key = st.text_input("OpenAI API Key",
value=st.session_state.openai_key,
type="password")
st.session_state.gemini_key = st.text_input("Gemini API Key",
value=st.session_state.gemini_key,
type="password")
st.session_state.e2b_key = st.text_input("E2B API Key",
value=st.session_state.e2b_key,
type="password")
def create_agents() -> tuple[Agent, Agent, Agent]:
vision_agent = Agent(
model=Gemini(id="gemini-2.0-flash", api_key=st.session_state.gemini_key),
markdown=True,
)
coding_agent = Agent(
model=OpenAIChat(
id="o3-mini",
api_key=st.session_state.openai_key,
system_prompt="""You are an expert Python programmer. You will receive coding problems similar to LeetCode questions,
which may include problem statements, sample inputs, and examples. Your task is to:
1. Analyze the problem carefully and Optimally with best possible time and space complexities.
2. Write clean, efficient Python code to solve it
3. Include proper documentation and type hints
4. The code will be executed in an e2b sandbox environment
Please ensure your code is complete and handles edge cases appropriately."""
),
markdown=True
)
execution_agent = Agent(
model=OpenAIChat(
id="o3-mini",
api_key=st.session_state.openai_key,
system_prompt="""You are an expert at executing Python code in sandbox environments.
Your task is to:
1. Take the provided Python code
2. Execute it in the e2b sandbox
3. Format and explain the results clearly
4. Handle any execution errors gracefully
Always ensure proper error handling and clear output formatting."""
),
markdown=True
)
return vision_agent, coding_agent, execution_agent
def initialize_sandbox() -> None:
try:
if st.session_state.sandbox:
try:
st.session_state.sandbox.close()
except:
pass
os.environ['E2B_API_KEY'] = st.session_state.e2b_key
# Initialize sandbox with 60 second timeout
st.session_state.sandbox = Sandbox(timeout=60)
except Exception as e:
st.error(f"Failed to initialize sandbox: {str(e)}")
st.session_state.sandbox = None
def run_code_in_sandbox(code: str) -> Dict[str, Any]:
if not st.session_state.sandbox:
initialize_sandbox()
execution = st.session_state.sandbox.run_code(code)
return {
"logs": execution.logs,
"files": st.session_state.sandbox.files.list("/")
}
def process_image_with_gemini(vision_agent: Agent, image: Image) -> str:
prompt = """Analyze this image and extract any coding problem or code snippet shown.
Describe it in clear natural language, including any:
1. Problem statement
2. Input/output examples
3. Constraints or requirements
Format it as a proper coding problem description."""
# Save image to a temporary file
temp_path = "temp_image.png"
try:
# Convert to RGB if needed
if image.mode != 'RGB':
image = image.convert('RGB')
image.save(temp_path, format="PNG")
# Read the file and create image data
with open(temp_path, 'rb') as img_file:
img_bytes = img_file.read()
# Pass image to Gemini
response = vision_agent.run(
prompt,
images=[{"filepath": temp_path}] # Use filepath instead of content
)
return response.content
except Exception as e:
st.error(f"Error processing image: {str(e)}")
return "Failed to process the image. Please try again or use text input instead."
finally:
# Clean up temporary file
if os.path.exists(temp_path):
os.remove(temp_path)
def execute_code_with_agent(execution_agent: Agent, code: str, sandbox: Sandbox) -> str:
try:
# Set timeout to 30 seconds for code execution
sandbox.set_timeout(30)
execution = sandbox.run_code(code)
# Handle execution errors
if execution.error:
if "TimeoutException" in str(execution.error):
return "⚠️ Execution Timeout: The code took too long to execute (>30 seconds). Please optimize your solution or try a smaller input."
error_prompt = f"""The code execution resulted in an error:
Error: {execution.error}
Please analyze the error and provide a clear explanation of what went wrong."""
response = execution_agent.run(error_prompt)
return f"⚠️ Execution Error:\n{response.content}"
# Get files list safely
try:
files = sandbox.files.list("/")
except:
files = []
prompt = f"""Here is the code execution result:
Logs: {execution.logs}
Files: {str(files)}
Please provide a clear explanation of the results and any outputs."""
response = execution_agent.run(prompt)
return response.content
except Exception as e:
# Reinitialize sandbox on error
try:
initialize_sandbox()
except:
pass
return f"⚠️ Sandbox Error: {str(e)}"
def main() -> None:
st.title("O3-Mini Coding Agent")
# Add timeout info in sidebar
initialize_session_state()
setup_sidebar()
with st.sidebar:
st.info("⏱️ Code execution timeout: 30 seconds")
# Check all required API keys
if not (st.session_state.openai_key and
st.session_state.gemini_key and
st.session_state.e2b_key):
st.warning("Please enter all required API keys in the sidebar.")
return
vision_agent, coding_agent, execution_agent = create_agents()
# Clean, single-column layout
uploaded_image = st.file_uploader(
"Upload an image of your coding problem (optional)",
type=['png', 'jpg', 'jpeg']
)
if uploaded_image:
st.image(uploaded_image, caption="Uploaded Image", use_container_width=True)
user_query = st.text_area(
"Or type your coding problem here:",
placeholder="Example: Write a function to find the sum of two numbers. Include sample input/output cases.",
height=100
)
# Process button
if st.button("Generate & Execute Solution", type="primary"):
if uploaded_image and not user_query:
# Process image with Gemini
with st.spinner("Processing image..."):
try:
# Save uploaded file to temporary location
image = Image.open(uploaded_image)
extracted_query = process_image_with_gemini(vision_agent, image)
if extracted_query.startswith("Failed to process"):
st.error(extracted_query)
return
st.info("📝 Extracted Problem:")
st.write(extracted_query)
# Pass extracted query to coding agent
with st.spinner("Generating solution..."):
response = coding_agent.run(extracted_query)
except Exception as e:
st.error(f"Error processing image: {str(e)}")
return
elif user_query and not uploaded_image:
# Direct text input processing
with st.spinner("Generating solution..."):
response = coding_agent.run(user_query)
elif user_query and uploaded_image:
st.error("Please use either image upload OR text input, not both.")
return
else:
st.warning("Please provide either an image or text description of your coding problem.")
return
# Display and execute solution
if 'response' in locals():
st.divider()
st.subheader("💻 Solution")
# Extract code from markdown response
code_blocks = response.content.split("```python")
if len(code_blocks) > 1:
code = code_blocks[1].split("```")[0].strip()
# Display the code
st.code(code, language="python")
# Execute code with execution agent
with st.spinner("Executing code..."):
# Always initialize a fresh sandbox for each execution
initialize_sandbox()
if st.session_state.sandbox:
execution_results = execute_code_with_agent(
execution_agent,
code,
st.session_state.sandbox
)
# Display execution results
st.divider()
st.subheader("🚀 Execution Results")
st.markdown(execution_results)
# Try to display files if available
try:
files = st.session_state.sandbox.files.list("/")
if files:
st.markdown("📁 **Generated Files:**")
st.json(files)
except:
pass
if __name__ == "__main__":
main()

View file

@ -0,0 +1,4 @@
streamlit
e2b-code-interpreter
agno
Pillow

View file

@ -0,0 +1,77 @@
# 🧲 AI Competitor Intelligence Agent Team
The AI Competitor Intelligence Agent Team is a powerful competitor analysis tool powered by Firecrawl and Agno's AI Agent framework. This app helps businesses analyze their competitors by extracting structured data from competitor websites and generating actionable insights using AI.
## Features
- **Multi-Agent System**
- **Firecrawl Agent**: Specializes in crawling and summarizing competitor websites
- **Analysis Agent**: Generates detailed competitive analysis reports
- **Comparison Agent**: Creates structured comparisons between competitors
- **Competitor Discovery**:
- Finds similar companies using URL matching with Exa AI
- Discovers competitors based on business descriptions
- Automatically extracts relevant competitor URLs
- **Comprehensive Analysis**:
- Provides structured analysis reports with:
- Market gaps and opportunities
- Competitor weaknesses
- Recommended features
- Pricing strategies
- Growth opportunities
- Actionable recommendations
- **Interactive Analysis**: Users can input either their company URL or description for analysis
## Requirements
The application requires the following Python libraries:
- `agno`
- `exa-py`
- `streamlit`
- `pandas`
- `firecrawl-py`
You'll also need API keys for:
- OpenAI
- Firecrawl
- Exa
## How to Run
Follow these steps to set up and run the application:
1. **Clone the Repository**:
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd ai_agent_tutorials/ai_competitors_analysis_team
```
2. **Install the dependencies**:
```bash
pip install -r requirements.txt
```
3. **Set up your API keys**:
- Get an OpenAI API key from: https://platform.openai.com/api-keys
- Get a Firecrawl API key from: [Firecrawl website](https://www.firecrawl.dev/app/api-keys)
- Get an Exa API key from: [Exa website](https://dashboard.exa.ai/api-keys)
4. **Run the Streamlit app**:
```bash
streamlit run ai_competitor_analyser.py
```
## Usage
1. Enter your API keys in the sidebar
2. Input either:
- Your company's website URL
- A description of your company
3. Click "Analyze Competitors" to generate:
- Competitor comparison table
- Detailed analysis report
- Strategic recommendations

View file

@ -0,0 +1,346 @@
import streamlit as st
from exa_py import Exa
from agno.agent import Agent
from agno.tools.firecrawl import FirecrawlTools
from agno.models.openai import OpenAIChat
from agno.tools.duckduckgo import DuckDuckGoTools
import pandas as pd
import requests
from firecrawl import FirecrawlApp
from pydantic import BaseModel, Field
from typing import List, Optional
import json
# Streamlit UI
st.set_page_config(page_title="AI Competitor Intelligence Agent Team", layout="wide")
# Sidebar for API keys
st.sidebar.title("API Keys")
openai_api_key = st.sidebar.text_input("OpenAI API Key", type="password")
firecrawl_api_key = st.sidebar.text_input("Firecrawl API Key", type="password")
# Add search engine selection before API keys
search_engine = st.sidebar.selectbox(
"Select Search Endpoint",
options=["Perplexity AI - Sonar Pro", "Exa AI"],
help="Choose which AI service to use for finding competitor URLs"
)
# Show relevant API key input based on selection
if search_engine == "Perplexity AI - Sonar Pro":
perplexity_api_key = st.sidebar.text_input("Perplexity API Key", type="password")
# Store API keys in session state
if openai_api_key and firecrawl_api_key and perplexity_api_key:
st.session_state.openai_api_key = openai_api_key
st.session_state.firecrawl_api_key = firecrawl_api_key
st.session_state.perplexity_api_key = perplexity_api_key
else:
st.sidebar.warning("Please enter all required API keys to proceed.")
else: # Exa AI
exa_api_key = st.sidebar.text_input("Exa API Key", type="password")
# Store API keys in session state
if openai_api_key and firecrawl_api_key and exa_api_key:
st.session_state.openai_api_key = openai_api_key
st.session_state.firecrawl_api_key = firecrawl_api_key
st.session_state.exa_api_key = exa_api_key
else:
st.sidebar.warning("Please enter all required API keys to proceed.")
# Main UI
st.title("🧲 AI Competitor Intelligence Agent Team")
st.info(
"""
This app helps businesses analyze their competitors by extracting structured data from competitor websites and generating insights using AI.
- Provide a **URL** or a **description** of your company.
- The app will fetch competitor URLs, extract relevant information, and generate a detailed analysis report.
"""
)
st.success("For better results, provide both URL and a 5-6 word description of your company!")
# Input fields for URL and description
url = st.text_input("Enter your company URL :")
description = st.text_area("Enter a description of your company (if URL is not available):")
# Initialize API keys and tools
if "openai_api_key" in st.session_state and "firecrawl_api_key" in st.session_state:
if (search_engine == "Perplexity AI - Sonar Pro" and "perplexity_api_key" in st.session_state) or \
(search_engine == "Exa AI" and "exa_api_key" in st.session_state):
# Initialize Exa only if selected
if search_engine == "Exa AI":
exa = Exa(api_key=st.session_state.exa_api_key)
firecrawl_tools = FirecrawlTools(
api_key=st.session_state.firecrawl_api_key,
scrape=False,
crawl=True,
limit=5
)
firecrawl_agent = Agent(
model=OpenAIChat(id="gpt-4o", api_key=st.session_state.openai_api_key),
tools=[firecrawl_tools, DuckDuckGoTools()],
show_tool_calls=True,
markdown=True
)
analysis_agent = Agent(
model=OpenAIChat(id="gpt-4o", api_key=st.session_state.openai_api_key),
show_tool_calls=True,
markdown=True
)
# New agent for comparing competitor data
comparison_agent = Agent(
model=OpenAIChat(id="gpt-4o", api_key=st.session_state.openai_api_key),
show_tool_calls=True,
markdown=True
)
def get_competitor_urls(url: str = None, description: str = None) -> list[str]:
if not url and not description:
raise ValueError("Please provide either a URL or a description.")
if search_engine == "Perplexity AI - Sonar Pro":
perplexity_url = "https://api.perplexity.ai/chat/completions"
content = "Find me 3 competitor company URLs similar to the company with "
if url and description:
content += f"URL: {url} and description: {description}"
elif url:
content += f"URL: {url}"
else:
content += f"description: {description}"
content += ". ONLY RESPOND WITH THE URLS, NO OTHER TEXT."
payload = {
"model": "sonar-pro",
"messages": [
{
"role": "system",
"content": "Be precise and only return 3 company URLs ONLY."
},
{
"role": "user",
"content": content
}
],
"max_tokens": 1000,
"temperature": 0.2,
}
headers = {
"Authorization": f"Bearer {st.session_state.perplexity_api_key}",
"Content-Type": "application/json"
}
try:
response = requests.post(perplexity_url, json=payload, headers=headers)
response.raise_for_status()
urls = response.json()['choices'][0]['message']['content'].strip().split('\n')
return [url.strip() for url in urls if url.strip()]
except Exception as e:
st.error(f"Error fetching competitor URLs from Perplexity: {str(e)}")
return []
else: # Exa AI
try:
if url:
result = exa.find_similar(
url=url,
num_results=3,
exclude_source_domain=True,
category="company"
)
else:
result = exa.search(
description,
type="neural",
category="company",
use_autoprompt=True,
num_results=3
)
return [item.url for item in result.results]
except Exception as e:
st.error(f"Error fetching competitor URLs from Exa: {str(e)}")
return []
class CompetitorDataSchema(BaseModel):
company_name: str = Field(description="Name of the company")
pricing: str = Field(description="Pricing details, tiers, and plans")
key_features: List[str] = Field(description="Main features and capabilities of the product/service")
tech_stack: List[str] = Field(description="Technologies, frameworks, and tools used")
marketing_focus: str = Field(description="Main marketing angles and target audience")
customer_feedback: str = Field(description="Customer testimonials, reviews, and feedback")
def extract_competitor_info(competitor_url: str) -> Optional[dict]:
try:
# Initialize FirecrawlApp with API key
app = FirecrawlApp(api_key=st.session_state.firecrawl_api_key)
# Add wildcard to crawl subpages
url_pattern = f"{competitor_url}/*"
extraction_prompt = """
Extract detailed information about the company's offerings, including:
- Company name and basic information
- Pricing details, plans, and tiers
- Key features and main capabilities
- Technology stack and technical details
- Marketing focus and target audience
- Customer feedback and testimonials
Analyze the entire website content to provide comprehensive information for each field.
"""
response = app.extract(
[url_pattern],
{
'prompt': extraction_prompt,
'schema': CompetitorDataSchema.model_json_schema(),
}
)
if response.get('success') and response.get('data'):
extracted_info = response['data']
# Create JSON structure
competitor_json = {
"competitor_url": competitor_url,
"company_name": extracted_info.get('company_name', 'N/A'),
"pricing": extracted_info.get('pricing', 'N/A'),
"key_features": extracted_info.get('key_features', [])[:5], # Top 5 features
"tech_stack": extracted_info.get('tech_stack', [])[:5], # Top 5 tech stack items
"marketing_focus": extracted_info.get('marketing_focus', 'N/A'),
"customer_feedback": extracted_info.get('customer_feedback', 'N/A')
}
return competitor_json
else:
return None
except Exception as e:
return None
def generate_comparison_report(competitor_data: list) -> None:
# Format the competitor data for the prompt
formatted_data = json.dumps(competitor_data, indent=2)
print(formatted_data)
# Updated system prompt for more structured output
system_prompt = f"""
As an expert business analyst, analyze the following competitor data in JSON format and create a structured comparison.
Extract and summarize the key information into concise points.
{formatted_data}
Return the data in a structured format with EXACTLY these columns:
Company, Pricing, Key Features, Tech Stack, Marketing Focus, Customer Feedback
Rules:
1. For Company: Include company name and URL
2. For Key Features: List top 3 most important features only
3. For Tech Stack: List top 3 most relevant technologies only
4. Keep all entries clear and concise
5. Format feedback as brief quotes
6. Return ONLY the structured data, no additional text
"""
# Get comparison data from agent
comparison_response = comparison_agent.run(system_prompt)
try:
# Split the response into lines and clean them
table_lines = [
line.strip()
for line in comparison_response.content.split('\n')
if line.strip() and '|' in line
]
# Extract headers (first row)
headers = [
col.strip()
for col in table_lines[0].split('|')
if col.strip()
]
# Extract data rows (skip header and separator rows)
data_rows = []
for line in table_lines[2:]: # Skip header and separator rows
row_data = [
cell.strip()
for cell in line.split('|')
if cell.strip()
]
if len(row_data) == len(headers):
data_rows.append(row_data)
# Create DataFrame
df = pd.DataFrame(
data_rows,
columns=headers
)
# Display the table
st.subheader("Competitor Comparison")
st.table(df)
except Exception as e:
st.error(f"Error creating comparison table: {str(e)}")
st.write("Raw comparison data for debugging:", comparison_response.content)
def generate_analysis_report(competitor_data: list):
# Format the competitor data for the prompt
formatted_data = json.dumps(competitor_data, indent=2)
print("Analysis Data:", formatted_data) # For debugging
report = analysis_agent.run(
f"""Analyze the following competitor data in JSON format and identify market opportunities to improve my own company:
{formatted_data}
Tasks:
1. Identify market gaps and opportunities based on competitor offerings
2. Analyze competitor weaknesses that we can capitalize on
3. Recommend unique features or capabilities we should develop
4. Suggest pricing and positioning strategies to gain competitive advantage
5. Outline specific growth opportunities in underserved market segments
6. Provide actionable recommendations for product development and go-to-market strategy
Focus on finding opportunities where we can differentiate and do better than competitors.
Highlight any unmet customer needs or pain points we can address.
"""
)
return report.content
# Run analysis when the user clicks the button
if st.button("Analyze Competitors"):
if url or description:
with st.spinner("Fetching competitor URLs..."):
competitor_urls = get_competitor_urls(url=url, description=description)
st.write(f"Competitor URLs: {competitor_urls}")
competitor_data = []
for comp_url in competitor_urls:
with st.spinner(f"Analyzing Competitor: {comp_url}..."):
competitor_info = extract_competitor_info(comp_url)
if competitor_info is not None:
competitor_data.append(competitor_info)
if competitor_data:
# Generate and display comparison report
with st.spinner("Generating comparison table..."):
generate_comparison_report(competitor_data)
# Generate and display final analysis report
with st.spinner("Generating analysis report..."):
analysis_report = generate_analysis_report(competitor_data)
st.subheader("Competitor Analysis Report")
st.markdown(analysis_report)
st.success("Analysis complete!")
else:
st.error("Could not extract data from any competitor URLs")
else:
st.error("Please provide either a URL or a description.")

View file

@ -0,0 +1,5 @@
exa-py==1.7.1
firecrawl-py==1.9.0
duckduckgo-search==7.2.1
agno
streamlit==1.41.1

View file

@ -13,6 +13,7 @@ This Streamlit app implements an AI-powered customer support agent for synthetic
1. Clone the GitHub repository
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/ai_agent_tutorials/ai_customer_support_agent
```
2. Install the required dependencies:
@ -28,7 +29,7 @@ The app expects Qdrant to be running on localhost:6333. Adjust the configuration
docker pull qdrant/qdrant
docker run -p 6333:6333 -p 6334:6334 \
-v $(pwd)/qdrant_storage:/qdrant/storage:z \
-v "$(pwd)/qdrant_storage:/qdrant/storage:z" \
qdrant/qdrant
```

View file

@ -14,84 +14,115 @@ openai_api_key = st.text_input("Enter OpenAI API Key", type="password")
if openai_api_key:
os.environ['OPENAI_API_KEY'] = openai_api_key
class CustomerSupportAIAgent:
def __init__(self):
# Initialize Mem0 with Qdrant as the vector store
config = {
"vector_store": {
"provider": "qdrant",
"config": {
"model": "gpt-4o-mini",
"host": "localhost",
"port": 6333,
}
},
}
self.memory = Memory.from_config(config)
try:
self.memory = Memory.from_config(config)
except Exception as e:
st.error(f"Failed to initialize memory: {e}")
st.stop() # Stop execution if memory initialization fails
self.client = OpenAI()
self.app_id = "customer-support"
def handle_query(self, query, user_id=None):
relevant_memories = self.memory.search(query=query, user_id=user_id)
context = "Relevant past information:\n"
for mem in relevant_memories:
context += f"- {mem['text']}\n"
try:
# Search for relevant memories
relevant_memories = self.memory.search(query=query, user_id=user_id)
# Build context from relevant memories
context = "Relevant past information:\n"
if relevant_memories and "results" in relevant_memories:
for memory in relevant_memories["results"]:
if "memory" in memory:
context += f"- {memory['memory']}\n"
full_prompt = f"{context}\nCustomer: {query}\nSupport Agent:"
# Generate a response using OpenAI
full_prompt = f"{context}\nCustomer: {query}\nSupport Agent:"
response = self.client.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": "You are a customer support AI agent for TechGadgets.com, an online electronics store."},
{"role": "user", "content": full_prompt}
]
)
answer = response.choices[0].message.content
response = self.client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "You are a customer support AI agent for TechGadgets.com, an online electronics store."},
{"role": "user", "content": full_prompt}
]
)
answer = response.choices[0].message.content
# Add the query and answer to memory
self.memory.add(query, user_id=user_id, metadata={"app_id": self.app_id, "role": "user"})
self.memory.add(answer, user_id=user_id, metadata={"app_id": self.app_id, "role": "assistant"})
self.memory.add(query, user_id=user_id, metadata={"app_id": self.app_id, "role": "user"})
self.memory.add(answer, user_id=user_id, metadata={"app_id": self.app_id, "role": "assistant"})
return answer
return answer
except Exception as e:
st.error(f"An error occurred while handling the query: {e}")
return "Sorry, I encountered an error. Please try again later."
def get_memories(self, user_id=None):
return self.memory.get_all(user_id=user_id)
try:
# Retrieve all memories for a user
return self.memory.get_all(user_id=user_id)
except Exception as e:
st.error(f"Failed to retrieve memories: {e}")
return None
def generate_synthetic_data(self, user_id):
today = datetime.now()
order_date = (today - timedelta(days=10)).strftime("%B %d, %Y")
expected_delivery = (today + timedelta(days=2)).strftime("%B %d, %Y")
def generate_synthetic_data(self, user_id: str) -> dict | None:
try:
today = datetime.now()
order_date = (today - timedelta(days=10)).strftime("%B %d, %Y")
expected_delivery = (today + timedelta(days=2)).strftime("%B %d, %Y")
prompt = f"""Generate a detailed customer profile and order history for a TechGadgets.com customer with ID {user_id}. Include:
1. Customer name and basic info
2. A recent order of a high-end electronic device (placed on {order_date}, to be delivered by {expected_delivery})
3. Order details (product, price, order number)
4. Customer's shipping address
5. 2-3 previous orders from the past year
6. 2-3 customer service interactions related to these orders
7. Any preferences or patterns in their shopping behavior
prompt = f"""Generate a detailed customer profile and order history for a TechGadgets.com customer with ID {user_id}. Include:
1. Customer name and basic info
2. A recent order of a high-end electronic device (placed on {order_date}, to be delivered by {expected_delivery})
3. Order details (product, price, order number)
4. Customer's shipping address
5. 2-3 previous orders from the past year
6. 2-3 customer service interactions related to these orders
7. Any preferences or patterns in their shopping behavior
Format the output as a JSON object."""
Format the output as a JSON object."""
response = self.client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "You are a data generation AI that creates realistic customer profiles and order histories. Always respond with valid JSON."},
{"role": "user", "content": prompt}
],
response_format={"type": "json_object"}
)
response = self.client.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": "You are a data generation AI that creates realistic customer profiles and order histories. Always respond with valid JSON."},
{"role": "user", "content": prompt}
]
)
customer_data = json.loads(response.choices[0].message.content)
customer_data = json.loads(response.choices[0].message.content)
# Add generated data to memory
for key, value in customer_data.items():
if isinstance(value, list):
for item in value:
self.memory.add(json.dumps(item), user_id=user_id, metadata={"app_id": self.app_id, "role": "system"})
else:
self.memory.add(f"{key}: {json.dumps(value)}", user_id=user_id, metadata={"app_id": self.app_id, "role": "system"})
# Add generated data to memory
for key, value in customer_data.items():
if isinstance(value, list):
for item in value:
self.memory.add(
json.dumps(item),
user_id=user_id,
metadata={"app_id": self.app_id, "role": "system"}
)
else:
self.memory.add(
f"{key}: {json.dumps(value)}",
user_id=user_id,
metadata={"app_id": self.app_id, "role": "system"}
)
return customer_data
return customer_data
except Exception as e:
st.error(f"Failed to generate synthetic data: {e}")
return None
# Initialize the CustomerSupportAIAgent
support_agent = CustomerSupportAIAgent()
@ -111,7 +142,10 @@ if openai_api_key:
if customer_id:
with st.spinner("Generating customer data..."):
st.session_state.customer_data = support_agent.generate_synthetic_data(customer_id)
st.sidebar.success("Synthetic data generated successfully!")
if st.session_state.customer_data:
st.sidebar.success("Synthetic data generated successfully!")
else:
st.sidebar.error("Failed to generate synthetic data.")
else:
st.sidebar.error("Please enter a customer ID first.")
@ -126,8 +160,10 @@ if openai_api_key:
memories = support_agent.get_memories(user_id=customer_id)
if memories:
st.sidebar.write(f"Memory for customer **{customer_id}**:")
for mem in memories:
st.sidebar.write(f"- {mem['text']}")
if memories and "results" in memories:
for memory in memories["results"]:
if "memory" in memory:
st.write(f"- {memory['memory']}")
else:
st.sidebar.info("No memory found for this customer ID.")
else:
@ -152,7 +188,8 @@ if openai_api_key:
st.markdown(query)
# Generate and display response
answer = support_agent.handle_query(query, user_id=customer_id)
with st.spinner("Generating response..."):
answer = support_agent.handle_query(query, user_id=customer_id)
# Add assistant response to chat history
st.session_state.messages.append({"role": "assistant", "content": answer})

View file

@ -1,3 +1,3 @@
streamlit
openai
mem0ai
mem0ai==0.1.29

View file

@ -0,0 +1,55 @@
# 📊 AI Data Analysis Agent
An AI data analysis Agent built using the Agno Agent framework and Openai's gpt-4o model. This agent helps users analyze their data - csv, excel files through natural language queries, powered by OpenAI's language models and DuckDB for efficient data processing - making data analysis accessible to users regardless of their SQL expertise.
## Features
- 📤 **File Upload Support**:
- Upload CSV and Excel files
- Automatic data type detection and schema inference
- Support for multiple file formats
- 💬 **Natural Language Queries**:
- Convert natural language questions into SQL queries
- Get instant answers about your data
- No SQL knowledge required
- 🔍 **Advanced Analysis**:
- Perform complex data aggregations
- Filter and sort data
- Generate statistical summaries
- Create data visualizations
- 🎯 **Interactive UI**:
- User-friendly Streamlit interface
- Real-time query processing
- Clear result presentation
## How to Run
1. **Setup Environment**
```bash
# Clone the repository
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd ai_agent_tutorials/ai_data_analysis_agent
# Install dependencies
pip install -r requirements.txt
```
2. **Configure API Keys**
- Get OpenAI API key from [OpenAI Platform](https://platform.openai.com)
3. **Run the Application**
```bash
streamlit run ai_data_analyst.py
```
## Usage
1. Launch the application using the command above
2. Provide your OpenAI API key in the sidebar of Streamlit
3. Upload your CSV or Excel file through the Streamlit interface
4. Ask questions about your data in natural language
5. View the results and generated visualizations

View file

@ -0,0 +1,137 @@
import json
import tempfile
import csv
import streamlit as st
import pandas as pd
from agno.models.openai import OpenAIChat
from phi.agent.duckdb import DuckDbAgent
from agno.tools.pandas import PandasTools
import re
# Function to preprocess and save the uploaded file
def preprocess_and_save(file):
try:
# Read the uploaded file into a DataFrame
if file.name.endswith('.csv'):
df = pd.read_csv(file, encoding='utf-8', na_values=['NA', 'N/A', 'missing'])
elif file.name.endswith('.xlsx'):
df = pd.read_excel(file, na_values=['NA', 'N/A', 'missing'])
else:
st.error("Unsupported file format. Please upload a CSV or Excel file.")
return None, None, None
# Ensure string columns are properly quoted
for col in df.select_dtypes(include=['object']):
df[col] = df[col].astype(str).replace({r'"': '""'}, regex=True)
# Parse dates and numeric columns
for col in df.columns:
if 'date' in col.lower():
df[col] = pd.to_datetime(df[col], errors='coerce')
elif df[col].dtype == 'object':
try:
df[col] = pd.to_numeric(df[col])
except (ValueError, TypeError):
# Keep as is if conversion fails
pass
# Create a temporary file to save the preprocessed data
with tempfile.NamedTemporaryFile(delete=False, suffix=".csv") as temp_file:
temp_path = temp_file.name
# Save the DataFrame to the temporary CSV file with quotes around string fields
df.to_csv(temp_path, index=False, quoting=csv.QUOTE_ALL)
return temp_path, df.columns.tolist(), df # Return the DataFrame as well
except Exception as e:
st.error(f"Error processing file: {e}")
return None, None, None
# Streamlit app
st.title("📊 Data Analyst Agent")
# Sidebar for API keys
with st.sidebar:
st.header("API Keys")
openai_key = st.text_input("Enter your OpenAI API key:", type="password")
if openai_key:
st.session_state.openai_key = openai_key
st.success("API key saved!")
else:
st.warning("Please enter your OpenAI API key to proceed.")
# File upload widget
uploaded_file = st.file_uploader("Upload a CSV or Excel file", type=["csv", "xlsx"])
if uploaded_file is not None and "openai_key" in st.session_state:
# Preprocess and save the uploaded file
temp_path, columns, df = preprocess_and_save(uploaded_file)
if temp_path and columns and df is not None:
# Display the uploaded data as a table
st.write("Uploaded Data:")
st.dataframe(df) # Use st.dataframe for an interactive table
# Display the columns of the uploaded data
st.write("Uploaded columns:", columns)
# Configure the semantic model with the temporary file path
semantic_model = {
"tables": [
{
"name": "uploaded_data",
"description": "Contains the uploaded dataset.",
"path": temp_path,
}
]
}
# Initialize the DuckDbAgent for SQL query generation
duckdb_agent = DuckDbAgent(
model=OpenAIChat(model="gpt-4", api_key=st.session_state.openai_key),
semantic_model=json.dumps(semantic_model),
tools=[PandasTools()],
markdown=True,
add_history_to_messages=False, # Disable chat history
followups=False, # Disable follow-up queries
read_tool_call_history=False, # Disable reading tool call history
system_prompt="You are an expert data analyst. Generate SQL queries to solve the user's query. Return only the SQL query, enclosed in ```sql ``` and give the final answer.",
)
# Initialize code storage in session state
if "generated_code" not in st.session_state:
st.session_state.generated_code = None
# Main query input widget
user_query = st.text_area("Ask a query about the data:")
# Add info message about terminal output
st.info("💡 Check your terminal for a clearer output of the agent's response")
if st.button("Submit Query"):
if user_query.strip() == "":
st.warning("Please enter a query.")
else:
try:
# Show loading spinner while processing
with st.spinner('Processing your query...'):
# Get the response from DuckDbAgent
response1 = duckdb_agent.run(user_query)
# Extract the content from the RunResponse object
if hasattr(response1, 'content'):
response_content = response1.content
else:
response_content = str(response1)
response = duckdb_agent.print_response(
user_query,
stream=True,
)
# Display the response in Streamlit
st.markdown(response_content)
except Exception as e:
st.error(f"Error generating response from the DuckDbAgent: {e}")
st.error("Please try rephrasing your query or check if the data format is correct.")

View file

@ -0,0 +1,7 @@
phidata
streamlit==1.41.1
openai==1.58.1
duckdb==1.1.3
pandas
numpy==1.26.4
agno

View file

@ -0,0 +1,41 @@
# 📊 AI Data Visualization Agent
A Streamlit application that acts as your personal data visualization expert, powered by LLMs. Simply upload your dataset and ask questions in natural language - the AI agent will analyze your data, generate appropriate visualizations, and provide insights through a combination of charts, statistics, and explanations.
## Features
#### Natural Language Data Analysis
- Ask questions about your data in plain English
- Get instant visualizations and statistical analysis
- Receive explanations of findings and insights
- Interactive follow-up questioning
#### Intelligent Visualization Selection
- Automatic choice of appropriate chart types
- Dynamic visualization generation
- Statistical visualization support
- Custom plot formatting and styling
#### Multi-Model AI Support
- Meta-Llama 3.1 405B for complex analysis
- DeepSeek V3 for detailed insights
- Qwen 2.5 7B for quick analysis
- Meta-Llama 3.3 70B for advanced queries
## How to Run
Follow the steps below to set up and run the application:
- Before anything else, Please get a free Together AI API Key here: https://api.together.ai/signin
- Get a free E2B API Key here: https://e2b.dev/ ; https://e2b.dev/docs/legacy/getting-started/api-key
1. **Clone the Repository**
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd ai_agent_tutorials/ai_data_visualisation_agent
```
2. **Install the dependencies**
```bash
pip install -r requirements.txt
```
3. **Run the Streamlit app**
```bash
streamlit run ai_data_visualisation_agent.py
```

View file

@ -0,0 +1,178 @@
import os
import json
import re
import sys
import io
import contextlib
import warnings
from typing import Optional, List, Any, Tuple
from PIL import Image
import streamlit as st
import pandas as pd
import base64
from io import BytesIO
from together import Together
from e2b_code_interpreter import Sandbox
warnings.filterwarnings("ignore", category=UserWarning, module="pydantic")
pattern = re.compile(r"```python\n(.*?)\n```", re.DOTALL)
def code_interpret(e2b_code_interpreter: Sandbox, code: str) -> Optional[List[Any]]:
with st.spinner('Executing code in E2B sandbox...'):
stdout_capture = io.StringIO()
stderr_capture = io.StringIO()
with contextlib.redirect_stdout(stdout_capture), contextlib.redirect_stderr(stderr_capture):
with warnings.catch_warnings():
warnings.simplefilter("ignore")
exec = e2b_code_interpreter.run_code(code)
if stderr_capture.getvalue():
print("[Code Interpreter Warnings/Errors]", file=sys.stderr)
print(stderr_capture.getvalue(), file=sys.stderr)
if stdout_capture.getvalue():
print("[Code Interpreter Output]", file=sys.stdout)
print(stdout_capture.getvalue(), file=sys.stdout)
if exec.error:
print(f"[Code Interpreter ERROR] {exec.error}", file=sys.stderr)
return None
return exec.results
def match_code_blocks(llm_response: str) -> str:
match = pattern.search(llm_response)
if match:
code = match.group(1)
return code
return ""
def chat_with_llm(e2b_code_interpreter: Sandbox, user_message: str, dataset_path: str) -> Tuple[Optional[List[Any]], str]:
# Update system prompt to include dataset path information
system_prompt = f"""You're a Python data scientist and data visualization expert. You are given a dataset at path '{dataset_path}' and also the user's query.
You need to analyze the dataset and answer the user's query with a response and you run Python code to solve them.
IMPORTANT: Always use the dataset path variable '{dataset_path}' in your code when reading the CSV file."""
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_message},
]
with st.spinner('Getting response from Together AI LLM model...'):
client = Together(api_key=st.session_state.together_api_key)
response = client.chat.completions.create(
model=st.session_state.model_name,
messages=messages,
)
response_message = response.choices[0].message
python_code = match_code_blocks(response_message.content)
if python_code:
code_interpreter_results = code_interpret(e2b_code_interpreter, python_code)
return code_interpreter_results, response_message.content
else:
st.warning(f"Failed to match any Python code in model's response")
return None, response_message.content
def upload_dataset(code_interpreter: Sandbox, uploaded_file) -> str:
dataset_path = f"./{uploaded_file.name}"
try:
code_interpreter.files.write(dataset_path, uploaded_file)
return dataset_path
except Exception as error:
st.error(f"Error during file upload: {error}")
raise error
def main():
"""Main Streamlit application."""
st.title("📊 AI Data Visualization Agent")
st.write("Upload your dataset and ask questions about it!")
# Initialize session state variables
if 'together_api_key' not in st.session_state:
st.session_state.together_api_key = ''
if 'e2b_api_key' not in st.session_state:
st.session_state.e2b_api_key = ''
if 'model_name' not in st.session_state:
st.session_state.model_name = ''
with st.sidebar:
st.header("API Keys and Model Configuration")
st.session_state.together_api_key = st.sidebar.text_input("Together AI API Key", type="password")
st.sidebar.info("💡 Everyone gets a free $1 credit by Together AI - AI Acceleration Cloud platform")
st.sidebar.markdown("[Get Together AI API Key](https://api.together.ai/signin)")
st.session_state.e2b_api_key = st.sidebar.text_input("Enter E2B API Key", type="password")
st.sidebar.markdown("[Get E2B API Key](https://e2b.dev/docs/legacy/getting-started/api-key)")
# Add model selection dropdown
model_options = {
"Meta-Llama 3.1 405B": "meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo",
"DeepSeek V3": "deepseek-ai/DeepSeek-V3",
"Qwen 2.5 7B": "Qwen/Qwen2.5-7B-Instruct-Turbo",
"Meta-Llama 3.3 70B": "meta-llama/Llama-3.3-70B-Instruct-Turbo"
}
st.session_state.model_name = st.selectbox(
"Select Model",
options=list(model_options.keys()),
index=0 # Default to first option
)
st.session_state.model_name = model_options[st.session_state.model_name]
uploaded_file = st.file_uploader("Choose a CSV file", type="csv")
if uploaded_file is not None:
# Display dataset with toggle
df = pd.read_csv(uploaded_file)
st.write("Dataset:")
show_full = st.checkbox("Show full dataset")
if show_full:
st.dataframe(df)
else:
st.write("Preview (first 5 rows):")
st.dataframe(df.head())
# Query input
query = st.text_area("What would you like to know about your data?",
"Can you compare the average cost for two people between different categories?")
if st.button("Analyze"):
if not st.session_state.together_api_key or not st.session_state.e2b_api_key:
st.error("Please enter both API keys in the sidebar.")
else:
with Sandbox(api_key=st.session_state.e2b_api_key) as code_interpreter:
# Upload the dataset
dataset_path = upload_dataset(code_interpreter, uploaded_file)
# Pass dataset_path to chat_with_llm
code_results, llm_response = chat_with_llm(code_interpreter, query, dataset_path)
# Display LLM's text response
st.write("AI Response:")
st.write(llm_response)
# Display results/visualizations
if code_results:
for result in code_results:
if hasattr(result, 'png') and result.png: # Check if PNG data is available
# Decode the base64-encoded PNG data
png_data = base64.b64decode(result.png)
# Convert PNG data to an image and display it
image = Image.open(BytesIO(png_data))
st.image(image, caption="Generated Visualization", use_container_width=False)
elif hasattr(result, 'figure'): # For matplotlib figures
fig = result.figure # Extract the matplotlib figure
st.pyplot(fig) # Display using st.pyplot
elif hasattr(result, 'show'): # For plotly figures
st.plotly_chart(result)
elif isinstance(result, (pd.DataFrame, pd.Series)):
st.dataframe(result)
else:
st.write(result)
if __name__ == "__main__":
main()

View file

@ -0,0 +1,7 @@
together==1.3.10
e2b-code-interpreter==1.0.3
e2b==1.0.5
Pillow==10.4.0
streamlit
pandas
matplotlib

View file

@ -0,0 +1,74 @@
# Deep Research Agent with OpenAI Agents SDK and Firecrawl
A powerful research assistant that leverages OpenAI's Agents SDK and Firecrawl's deep research capabilities to perform comprehensive web research on any topic and any question.
## Features
- **Deep Web Research**: Automatically searches the web, extracts content, and synthesizes findings
- **Enhanced Analysis**: Uses OpenAI's Agents SDK to elaborate on research findings with additional context and insights
- **Interactive UI**: Clean Streamlit interface for easy interaction
- **Downloadable Reports**: Export research findings as markdown files
## How It Works
1. **Input Phase**: User provides a research topic and API credentials
2. **Research Phase**: The tool uses Firecrawl to search the web and extract relevant information
3. **Analysis Phase**: An initial research report is generated based on the findings
4. **Enhancement Phase**: A second agent elaborates on the initial report, adding depth and context
5. **Output Phase**: The enhanced report is presented to the user and available for download
## Requirements
- Python 3.8+
- OpenAI API key
- Firecrawl API key
- Required Python packages (see `requirements.txt`)
## Installation
1. Clone this repository:
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd ai_agent_tutorials/ai_deep_research_agent
```
2. Install the required packages:
```bash
pip install -r requirements.txt
```
## Usage
1. Run the Streamlit app:
```bash
streamlit run deep_research_openai.py
```
2. Enter your API keys in the sidebar:
- OpenAI API key
- Firecrawl API key
3. Enter your research topic in the main input field
4. Click "Start Research" and wait for the process to complete
5. View and download your enhanced research report
## Example Research Topics
- "Latest developments in quantum computing"
- "Impact of climate change on marine ecosystems"
- "Advancements in renewable energy storage"
- "Ethical considerations in artificial intelligence"
- "Emerging trends in remote work technologies"
## Technical Details
The application uses two specialized agents:
1. **Research Agent**: Utilizes Firecrawl's deep research endpoint to gather comprehensive information from multiple web sources.
2. **Elaboration Agent**: Enhances the initial research by adding detailed explanations, examples, case studies, and practical implications.
The Firecrawl deep research tool performs multiple iterations of web searches, content extraction, and analysis to provide thorough coverage of the topic.

View file

@ -0,0 +1,185 @@
import asyncio
import streamlit as st
from typing import Dict, Any, List
from agents import Agent, Runner, trace
from agents import set_default_openai_key
from firecrawl import FirecrawlApp
from agents.tool import function_tool
# Set page configuration
st.set_page_config(
page_title="OpenAI Deep Research Agent",
page_icon="📘",
layout="wide"
)
# Initialize session state for API keys if not exists
if "openai_api_key" not in st.session_state:
st.session_state.openai_api_key = ""
if "firecrawl_api_key" not in st.session_state:
st.session_state.firecrawl_api_key = ""
# Sidebar for API keys
with st.sidebar:
st.title("API Configuration")
openai_api_key = st.text_input(
"OpenAI API Key",
value=st.session_state.openai_api_key,
type="password"
)
firecrawl_api_key = st.text_input(
"Firecrawl API Key",
value=st.session_state.firecrawl_api_key,
type="password"
)
if openai_api_key:
st.session_state.openai_api_key = openai_api_key
set_default_openai_key(openai_api_key)
if firecrawl_api_key:
st.session_state.firecrawl_api_key = firecrawl_api_key
# Main content
st.title("📘 OpenAI Deep Research Agent")
st.markdown("This OpenAI Agent from the OpenAI Agents SDK performs deep research on any topic using Firecrawl")
# Research topic input
research_topic = st.text_input("Enter your research topic:", placeholder="e.g., Latest developments in AI")
# Keep the original deep_research tool
@function_tool
async def deep_research(query: str, max_depth: int, time_limit: int, max_urls: int) -> Dict[str, Any]:
"""
Perform comprehensive web research using Firecrawl's deep research endpoint.
"""
try:
# Initialize FirecrawlApp with the API key from session state
firecrawl_app = FirecrawlApp(api_key=st.session_state.firecrawl_api_key)
# Define research parameters
params = {
"maxDepth": max_depth,
"timeLimit": time_limit,
"maxUrls": max_urls
}
# Set up a callback for real-time updates
def on_activity(activity):
st.write(f"[{activity['type']}] {activity['message']}")
# Run deep research
with st.spinner("Performing deep research..."):
results = firecrawl_app.deep_research(
query=query,
params=params,
on_activity=on_activity
)
return {
"success": True,
"final_analysis": results['data']['finalAnalysis'],
"sources_count": len(results['data']['sources']),
"sources": results['data']['sources']
}
except Exception as e:
st.error(f"Deep research error: {str(e)}")
return {"error": str(e), "success": False}
# Keep the original agents
research_agent = Agent(
name="research_agent",
instructions="""You are a research assistant that can perform deep web research on any topic.
When given a research topic or question:
1. Use the deep_research tool to gather comprehensive information
- Always use these parameters:
* max_depth: 3 (for moderate depth)
* time_limit: 180 (3 minutes)
* max_urls: 10 (sufficient sources)
2. The tool will search the web, analyze multiple sources, and provide a synthesis
3. Review the research results and organize them into a well-structured report
4. Include proper citations for all sources
5. Highlight key findings and insights
""",
tools=[deep_research]
)
elaboration_agent = Agent(
name="elaboration_agent",
instructions="""You are an expert content enhancer specializing in research elaboration.
When given a research report:
1. Analyze the structure and content of the report
2. Enhance the report by:
- Adding more detailed explanations of complex concepts
- Including relevant examples, case studies, and real-world applications
- Expanding on key points with additional context and nuance
- Adding visual elements descriptions (charts, diagrams, infographics)
- Incorporating latest trends and future predictions
- Suggesting practical implications for different stakeholders
3. Maintain academic rigor and factual accuracy
4. Preserve the original structure while making it more comprehensive
5. Ensure all additions are relevant and valuable to the topic
"""
)
async def run_research_process(topic: str):
"""Run the complete research process."""
# Step 1: Initial Research
with st.spinner("Conducting initial research..."):
research_result = await Runner.run(research_agent, topic)
initial_report = research_result.final_output
# Display initial report in an expander
with st.expander("View Initial Research Report"):
st.markdown(initial_report)
# Step 2: Enhance the report
with st.spinner("Enhancing the report with additional information..."):
elaboration_input = f"""
RESEARCH TOPIC: {topic}
INITIAL RESEARCH REPORT:
{initial_report}
Please enhance this research report with additional information, examples, case studies,
and deeper insights while maintaining its academic rigor and factual accuracy.
"""
elaboration_result = await Runner.run(elaboration_agent, elaboration_input)
enhanced_report = elaboration_result.final_output
return enhanced_report
# Main research process
if st.button("Start Research", disabled=not (openai_api_key and firecrawl_api_key and research_topic)):
if not openai_api_key or not firecrawl_api_key:
st.warning("Please enter both API keys in the sidebar.")
elif not research_topic:
st.warning("Please enter a research topic.")
else:
try:
# Create placeholder for the final report
report_placeholder = st.empty()
# Run the research process
enhanced_report = asyncio.run(run_research_process(research_topic))
# Display the enhanced report
report_placeholder.markdown("## Enhanced Research Report")
report_placeholder.markdown(enhanced_report)
# Add download button
st.download_button(
"Download Report",
enhanced_report,
file_name=f"{research_topic.replace(' ', '_')}_report.md",
mime="text/markdown"
)
except Exception as e:
st.error(f"An error occurred: {str(e)}")
# Footer
st.markdown("---")
st.markdown("Powered by OpenAI Agents SDK and Firecrawl")

View file

@ -0,0 +1,4 @@
openai-agents
firecrawl
streamlit
firecrawl-py

View file

@ -15,6 +15,7 @@ This script demonstrates how to build a team of AI agents that work together as
1. Clone the GitHub repository
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/ai_agent_tutorials/ai_finance_agent_team
```
2. Install the required dependencies:

View file

@ -1,16 +1,16 @@
from phi.agent import Agent
from phi.model.openai import OpenAIChat
from phi.storage.agent.sqlite import SqlAgentStorage
from phi.tools.duckduckgo import DuckDuckGo
from phi.tools.yfinance import YFinanceTools
from phi.playground import Playground, serve_playground_app
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.storage.agent.sqlite import SqliteAgentStorage
from agno.tools.duckduckgo import DuckDuckGoTools
from agno.tools.yfinance import YFinanceTools
from agno.playground import Playground, serve_playground_app
web_agent = Agent(
name="Web Agent",
role="Search the web for information",
model=OpenAIChat(id="gpt-4o"),
tools=[DuckDuckGo()],
storage=SqlAgentStorage(table_name="web_agent", db_file="agents.db"),
tools=[DuckDuckGoTools()],
storage=SqliteAgentStorage(table_name="web_agent", db_file="agents.db"),
add_history_to_messages=True,
markdown=True,
)
@ -21,7 +21,7 @@ finance_agent = Agent(
model=OpenAIChat(id="gpt-4o"),
tools=[YFinanceTools(stock_price=True, analyst_recommendations=True, company_info=True, company_news=True)],
instructions=["Always use tables to display data"],
storage=SqlAgentStorage(table_name="finance_agent", db_file="agents.db"),
storage=SqliteAgentStorage(table_name="finance_agent", db_file="agents.db"),
add_history_to_messages=True,
markdown=True,
)

View file

@ -1,5 +1,5 @@
openai
phidata
agno
duckduckgo-search
yfinance
fastapi[standard]

View file

@ -0,0 +1,67 @@
# AI Game Design Agent Team 🎮
The AI Game Design Agent Team is a collaborative game design system powered by [AG2](https://github.com/ag2ai/ag2?tab=readme-ov-file)(formerly AutoGen)'s AI Agent framework. This app generates comprehensive game concepts through the coordination of multiple specialized AI agents, each focusing on different aspects of game design based on user inputs such as game type, target audience, art style, and technical requirements. This is built on AG2's new swarm feature run through initiate_chat() method.
## Features
- **Specialized Game Design Agent Team**
- 🎭 **Story Agent**: Specializes in narrative design and world-building, including character development, plot arcs, dialogue writing, and lore creation
- 🎮 **Gameplay Agent**: Focuses on game mechanics and systems design, including player progression, combat systems, resource management, and balancing
- 🎨 **Visuals Agent**: Handles art direction and audio design, covering UI/UX, character/environment art style, sound effects, and music composition
- ⚙️ **Tech Agent**: Provides technical architecture and implementation guidance, including engine selection, optimization strategies, networking requirements, and development roadmap
- 🎯 **Task Agent**: Coordinates between all specialized agents and ensures cohesive integration of different game aspects
- **Comprehensive Game Design Outputs**:
- Detailed narrative and world-building elements
- Core gameplay mechanics and systems
- Visual and audio direction
- Technical specifications and requirements
- Development timeline and budget considerations
- Coherent game design from the team.
- **Customizable Input Parameters**:
- Game type and target audience
- Art style and visual preferences
- Platform requirements
- Development constraints (time, budget)
- Core mechanics and gameplay features
- **Interactive Results**:
- Quick show of game design ideas from each agent
- Detailed results are presented in expandable sections for easy navigation and reference
## How to Run
Follow these steps to set up and run the application:
1. **Clone the Repository**:
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd ai_agent_tutorials/ai_game_design_team
```
2. **Install Dependencies**:
```bash
pip install -r requirements.txt
```
3. **Set Up OpenAI API Key**:
- Obtain an OpenAI API key from [OpenAI's platform](https://platform.openai.com)
- You'll input this key in the app's sidebar when running
4. **Run the Streamlit App**:
```bash
streamlit run ai_game_design_agent_team/game_design_agent_team.py
```
## Usage
1. Enter your OpenAI API key in the sidebar
2. Fill in the game details:
- Background vibe and setting
- Game type and target audience
- Visual style preferences
- Technical requirements
- Development constraints
3. Click "Generate Game Concept" to receive comprehensive design documentation from all agents
4. Review the outputs in the expandable sections for each aspect of game design

View file

@ -0,0 +1,290 @@
import asyncio
import streamlit as st
from autogen import (
SwarmAgent,
SwarmResult,
initiate_swarm_chat,
OpenAIWrapper,
AFTER_WORK,
UPDATE_SYSTEM_MESSAGE
)
# Initialize session state
if 'output' not in st.session_state:
st.session_state.output = {'story': '', 'gameplay': '', 'visuals': '', 'tech': ''}
# Sidebar for API key input
st.sidebar.title("API Key")
api_key = st.sidebar.text_input("Enter your OpenAI API Key", type="password")
# Add guidance in sidebar
st.sidebar.success("""
**Getting Started**
Please provide inputs and features for your dream game! Consider:
- The overall vibe and setting
- Core gameplay elements
- Target audience and platforms
- Visual style preferences
- Technical requirements
The AI agents will collaborate to develop a comprehensive game concept based on your specifications.
""")
# Main app UI
st.title("🎮 AI Game Design Agent Team")
# Add agent information below title
st.info("""
**Meet Your AI Game Design Team:**
🎭 **Story Agent** - Crafts compelling narratives and rich worlds
🎮 **Gameplay Agent** - Creates engaging mechanics and systems
🎨 **Visuals Agent** - Shapes the artistic vision and style
**Tech Agent** - Provides technical direction and solutions
These agents collaborate to create a comprehensive game concept based on your inputs.
""")
# User inputs
st.subheader("Game Details")
col1, col2 = st.columns(2)
with col1:
background_vibe = st.text_input("Background Vibe", "Epic fantasy with dragons")
game_type = st.selectbox("Game Type", ["RPG", "Action", "Adventure", "Puzzle", "Strategy", "Simulation", "Platform", "Horror"])
target_audience = st.selectbox("Target Audience", ["Kids (7-12)", "Teens (13-17)", "Young Adults (18-25)", "Adults (26+)", "All Ages"])
player_perspective = st.selectbox("Player Perspective", ["First Person", "Third Person", "Top Down", "Side View", "Isometric"])
multiplayer = st.selectbox("Multiplayer Support", ["Single Player Only", "Local Co-op", "Online Multiplayer", "Both Local and Online"])
with col2:
game_goal = st.text_input("Game Goal", "Save the kingdom from eternal winter")
art_style = st.selectbox("Art Style", ["Realistic", "Cartoon", "Pixel Art", "Stylized", "Low Poly", "Anime", "Hand-drawn"])
platform = st.multiselect("Target Platforms", ["PC", "Mobile", "PlayStation", "Xbox", "Nintendo Switch", "Web Browser"])
development_time = st.slider("Development Time (months)", 1, 36, 12)
cost = st.number_input("Budget (USD)", min_value=0, value=10000, step=5000)
# Additional details
st.subheader("Detailed Preferences")
col3, col4 = st.columns(2)
with col3:
core_mechanics = st.multiselect(
"Core Gameplay Mechanics",
["Combat", "Exploration", "Puzzle Solving", "Resource Management", "Base Building", "Stealth", "Racing", "Crafting"]
)
mood = st.multiselect(
"Game Mood/Atmosphere",
["Epic", "Mysterious", "Peaceful", "Tense", "Humorous", "Dark", "Whimsical", "Scary"]
)
with col4:
inspiration = st.text_area("Games for Inspiration (comma-separated)", "")
unique_features = st.text_area("Unique Features or Requirements", "")
depth = st.selectbox("Level of Detail in Response", ["Low", "Medium", "High"])
# Button to start the agent collaboration
if st.button("Generate Game Concept"):
# Check if API key is provided
if not api_key:
st.error("Please enter your OpenAI API key.")
else:
with st.spinner('🤖 AI Agents are collaborating on your game concept...'):
# Prepare the task based on user inputs
task = f"""
Create a game concept with the following details:
- Background Vibe: {background_vibe}
- Game Type: {game_type}
- Game Goal: {game_goal}
- Target Audience: {target_audience}
- Player Perspective: {player_perspective}
- Multiplayer Support: {multiplayer}
- Art Style: {art_style}
- Target Platforms: {', '.join(platform)}
- Development Time: {development_time} months
- Budget: ${cost:,}
- Core Mechanics: {', '.join(core_mechanics)}
- Mood/Atmosphere: {', '.join(mood)}
- Inspiration: {inspiration}
- Unique Features: {unique_features}
- Detail Level: {depth}
"""
llm_config = {"config_list": [{"model": "gpt-4o-mini","api_key": api_key}]}
# initialize context variables
context_variables = {
"story": None,
"gameplay": None,
"visuals": None,
"tech": None,
}
# define functions to be called by the agents
def update_story_overview(story_summary:str, context_variables:dict) -> SwarmResult:
"""Keep the summary as short as possible."""
context_variables["story"] = story_summary
st.sidebar.success('Story overview: ' + story_summary)
return SwarmResult(agent="gameplay_agent", context_variables=context_variables)
def update_gameplay_overview(gameplay_summary:str, context_variables:dict) -> SwarmResult:
"""Keep the summary as short as possible."""
context_variables["gameplay"] = gameplay_summary
st.sidebar.success('Gameplay overview: ' + gameplay_summary)
return SwarmResult(agent="visuals_agent", context_variables=context_variables)
def update_visuals_overview(visuals_summary:str, context_variables:dict) -> SwarmResult:
"""Keep the summary as short as possible."""
context_variables["visuals"] = visuals_summary
st.sidebar.success('Visuals overview: ' + visuals_summary)
return SwarmResult(agent="tech_agent", context_variables=context_variables)
def update_tech_overview(tech_summary:str, context_variables:dict) -> SwarmResult:
"""Keep the summary as short as possible."""
context_variables["tech"] = tech_summary
st.sidebar.success('Tech overview: ' + tech_summary)
return SwarmResult(agent="story_agent", context_variables=context_variables)
system_messages = {
"story_agent": """
You are an experienced game story designer specializing in narrative design and world-building. Your task is to:
1. Create a compelling narrative that aligns with the specified game type and target audience.
2. Design memorable characters with clear motivations and character arcs.
3. Develop the game's world, including its history, culture, and key locations.
4. Plan story progression and major plot points.
5. Integrate the narrative with the specified mood/atmosphere.
6. Consider how the story supports the core gameplay mechanics.
""",
"gameplay_agent": """
You are a senior game mechanics designer with expertise in player engagement and systems design. Your task is to:
1. Design core gameplay loops that match the specified game type and mechanics.
2. Create progression systems (character development, skills, abilities).
3. Define player interactions and control schemes for the chosen perspective.
4. Balance gameplay elements for the target audience.
5. Design multiplayer interactions if applicable.
6. Specify game modes and difficulty settings.
7. Consider the budget and development time constraints.
""",
"visuals_agent": """
You are a creative art director with expertise in game visual and audio design. Your task is to:
1. Define the visual style guide matching the specified art style.
2. Design character and environment aesthetics.
3. Plan visual effects and animations.
4. Create the audio direction including music style, sound effects, and ambient sound.
5. Consider technical constraints of chosen platforms.
6. Align visual elements with the game's mood/atmosphere.
7. Work within the specified budget constraints.
""",
"tech_agent": """
You are a technical director with extensive game development experience. Your task is to:
1. Recommend appropriate game engine and development tools.
2. Define technical requirements for all target platforms.
3. Plan the development pipeline and asset workflow.
4. Identify potential technical challenges and solutions.
5. Estimate resource requirements within the budget.
6. Consider scalability and performance optimization.
7. Plan for multiplayer infrastructure if applicable.
"""
}
def update_system_message_func(agent: SwarmAgent, messages) -> str:
""""""
system_prompt = system_messages[agent.name]
current_gen = agent.name.split("_")[0]
if agent._context_variables.get(current_gen) is None:
system_prompt += f"Call the update function provided to first provide a 2-3 sentence summary of your ideas on {current_gen.upper()} based on the context provided."
agent.llm_config['tool_choice'] = {"type": "function", "function": {"name": f"update_{current_gen}_overview"}}
agent.client = OpenAIWrapper(**agent.llm_config)
else:
# remove the tools to avoid the agent from using it and reduce cost
agent.llm_config["tools"] = None
agent.llm_config['tool_choice'] = None
agent.client = OpenAIWrapper(**agent.llm_config)
# the agent has given a summary, now it should generate a detailed response
system_prompt += f"\n\nYour task\nYou task is write the {current_gen} part of the report. Do not include any other parts. Do not use XML tags.\nStart your response with: '## {current_gen.capitalize()} Design'."
# Remove all messages except the first one with less cost
k = list(agent._oai_messages.keys())[-1]
agent._oai_messages[k] = agent._oai_messages[k][:1]
system_prompt += f"\n\n\nBelow are some context for you to refer to:"
# Add context variables to the prompt
for k, v in agent._context_variables.items():
if v is not None:
system_prompt += f"\n{k.capitalize()} Summary:\n{v}"
return system_prompt
state_update = UPDATE_SYSTEM_MESSAGE(update_system_message_func)
# Define agents
story_agent = SwarmAgent(
"story_agent",
llm_config=llm_config,
functions=update_story_overview,
update_agent_state_before_reply=[state_update]
)
gameplay_agent = SwarmAgent(
"gameplay_agent",
llm_config= llm_config,
functions=update_gameplay_overview,
update_agent_state_before_reply=[state_update]
)
visuals_agent = SwarmAgent(
"visuals_agent",
llm_config=llm_config,
functions=update_visuals_overview,
update_agent_state_before_reply=[state_update]
)
tech_agent = SwarmAgent(
name="tech_agent",
llm_config=llm_config,
functions=update_tech_overview,
update_agent_state_before_reply=[state_update]
)
story_agent.register_hand_off(AFTER_WORK(gameplay_agent))
gameplay_agent.register_hand_off(AFTER_WORK(visuals_agent))
visuals_agent.register_hand_off(AFTER_WORK(tech_agent))
tech_agent.register_hand_off(AFTER_WORK(story_agent))
result, _, _ = initiate_swarm_chat(
initial_agent=story_agent,
agents=[story_agent, gameplay_agent, visuals_agent, tech_agent],
user_agent=None,
messages=task,
max_rounds=13,
)
# Update session state with the individual responses
st.session_state.output = {
'story': result.chat_history[-4]['content'],
'gameplay': result.chat_history[-3]['content'],
'visuals': result.chat_history[-2]['content'],
'tech': result.chat_history[-1]['content']
}
# Display success message after completion
st.success('✨ Game concept generated successfully!')
# Display the individual outputs in expanders
with st.expander("Story Design"):
st.markdown(st.session_state.output['story'])
with st.expander("Gameplay Mechanics"):
st.markdown(st.session_state.output['gameplay'])
with st.expander("Visual and Audio Design"):
st.markdown(st.session_state.output['visuals'])
with st.expander("Technical Recommendations"):
st.markdown(st.session_state.output['tech'])

View file

@ -0,0 +1,2 @@
streamlit==1.41.1
autogen

View file

@ -0,0 +1,53 @@
# AI Health & Fitness Planner Agent 🏋️‍♂️
The **AI Health & Fitness Planner** is a personalized health and fitness Agent powered by Agno AI Agent framework. This app generates tailored dietary and fitness plans based on user inputs such as age, weight, height, activity level, dietary preferences, and fitness goals.
## Features
- **Health Agent and Fitness Agent**
- The app has two phidata agents that are specialists in giving Diet advice and Fitness/workout advice respectively.
- **Personalized Dietary Plans**:
- Generates detailed meal plans (breakfast, lunch, dinner, and snacks).
- Includes important considerations like hydration, electrolytes, and fiber intake.
- Supports various dietary preferences like Keto, Vegetarian, Low Carb, etc.
- **Personalized Fitness Plans**:
- Provides customized exercise routines based on fitness goals.
- Covers warm-ups, main workouts, and cool-downs.
- Includes actionable fitness tips and progress tracking advice.
- **Interactive Q&A**: Allows users to ask follow-up questions about their plans.
## Requirements
The application requires the following Python libraries:
- `agno`
- `google-generativeai`
- `streamlit`
Ensure these dependencies are installed via the `requirements.txt` file according to their mentioned versions
## How to Run
Follow the steps below to set up and run the application:
Before anything else, Please get a free Gemini API Key provided by Google AI here: https://aistudio.google.com/apikey
1. **Clone the Repository**:
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/ai_agent_tutorials/ai_health_fitness_agent
```
2. **Install the dependencies**
```bash
pip install -r requirements.txt
```
3. **Run the Streamlit app**
```bash
streamlit run health_agent.py
```

View file

@ -0,0 +1,244 @@
import streamlit as st
from agno.agent import Agent
from agno.models.google import Gemini
st.set_page_config(
page_title="AI Health & Fitness Planner",
page_icon="🏋️‍♂️",
layout="wide",
initial_sidebar_state="expanded"
)
st.markdown("""
<style>
.main {
padding: 2rem;
}
.stButton>button {
width: 100%;
border-radius: 5px;
height: 3em;
}
.success-box {
padding: 1rem;
border-radius: 0.5rem;
background-color: #f0fff4;
border: 1px solid #9ae6b4;
}
.warning-box {
padding: 1rem;
border-radius: 0.5rem;
background-color: #fffaf0;
border: 1px solid #fbd38d;
}
div[data-testid="stExpander"] div[role="button"] p {
font-size: 1.1rem;
font-weight: 600;
}
</style>
""", unsafe_allow_html=True)
def display_dietary_plan(plan_content):
with st.expander("📋 Your Personalized Dietary Plan", expanded=True):
col1, col2 = st.columns([2, 1])
with col1:
st.markdown("### 🎯 Why this plan works")
st.info(plan_content.get("why_this_plan_works", "Information not available"))
st.markdown("### 🍽️ Meal Plan")
st.write(plan_content.get("meal_plan", "Plan not available"))
with col2:
st.markdown("### ⚠️ Important Considerations")
considerations = plan_content.get("important_considerations", "").split('\n')
for consideration in considerations:
if consideration.strip():
st.warning(consideration)
def display_fitness_plan(plan_content):
with st.expander("💪 Your Personalized Fitness Plan", expanded=True):
col1, col2 = st.columns([2, 1])
with col1:
st.markdown("### 🎯 Goals")
st.success(plan_content.get("goals", "Goals not specified"))
st.markdown("### 🏋️‍♂️ Exercise Routine")
st.write(plan_content.get("routine", "Routine not available"))
with col2:
st.markdown("### 💡 Pro Tips")
tips = plan_content.get("tips", "").split('\n')
for tip in tips:
if tip.strip():
st.info(tip)
def main():
if 'dietary_plan' not in st.session_state:
st.session_state.dietary_plan = {}
st.session_state.fitness_plan = {}
st.session_state.qa_pairs = []
st.session_state.plans_generated = False
st.title("🏋️‍♂️ AI Health & Fitness Planner")
st.markdown("""
<div style='background-color: #00008B; padding: 1rem; border-radius: 0.5rem; margin-bottom: 2rem;'>
Get personalized dietary and fitness plans tailored to your goals and preferences.
Our AI-powered system considers your unique profile to create the perfect plan for you.
</div>
""", unsafe_allow_html=True)
with st.sidebar:
st.header("🔑 API Configuration")
gemini_api_key = st.text_input(
"Gemini API Key",
type="password",
help="Enter your Gemini API key to access the service"
)
if not gemini_api_key:
st.warning("⚠️ Please enter your Gemini API Key to proceed")
st.markdown("[Get your API key here](https://aistudio.google.com/apikey)")
return
st.success("API Key accepted!")
if gemini_api_key:
try:
gemini_model = Gemini(id="gemini-1.5-flash", api_key=gemini_api_key)
except Exception as e:
st.error(f"❌ Error initializing Gemini model: {e}")
return
st.header("👤 Your Profile")
col1, col2 = st.columns(2)
with col1:
age = st.number_input("Age", min_value=10, max_value=100, step=1, help="Enter your age")
height = st.number_input("Height (cm)", min_value=100.0, max_value=250.0, step=0.1)
activity_level = st.selectbox(
"Activity Level",
options=["Sedentary", "Lightly Active", "Moderately Active", "Very Active", "Extremely Active"],
help="Choose your typical activity level"
)
dietary_preferences = st.selectbox(
"Dietary Preferences",
options=["Vegetarian", "Keto", "Gluten Free", "Low Carb", "Dairy Free"],
help="Select your dietary preference"
)
with col2:
weight = st.number_input("Weight (kg)", min_value=20.0, max_value=300.0, step=0.1)
sex = st.selectbox("Sex", options=["Male", "Female", "Other"])
fitness_goals = st.selectbox(
"Fitness Goals",
options=["Lose Weight", "Gain Muscle", "Endurance", "Stay Fit", "Strength Training"],
help="What do you want to achieve?"
)
if st.button("🎯 Generate My Personalized Plan", use_container_width=True):
with st.spinner("Creating your perfect health and fitness routine..."):
try:
dietary_agent = Agent(
name="Dietary Expert",
role="Provides personalized dietary recommendations",
model=gemini_model,
instructions=[
"Consider the user's input, including dietary restrictions and preferences.",
"Suggest a detailed meal plan for the day, including breakfast, lunch, dinner, and snacks.",
"Provide a brief explanation of why the plan is suited to the user's goals.",
"Focus on clarity, coherence, and quality of the recommendations.",
]
)
fitness_agent = Agent(
name="Fitness Expert",
role="Provides personalized fitness recommendations",
model=gemini_model,
instructions=[
"Provide exercises tailored to the user's goals.",
"Include warm-up, main workout, and cool-down exercises.",
"Explain the benefits of each recommended exercise.",
"Ensure the plan is actionable and detailed.",
]
)
user_profile = f"""
Age: {age}
Weight: {weight}kg
Height: {height}cm
Sex: {sex}
Activity Level: {activity_level}
Dietary Preferences: {dietary_preferences}
Fitness Goals: {fitness_goals}
"""
dietary_plan_response = dietary_agent.run(user_profile)
dietary_plan = {
"why_this_plan_works": "High Protein, Healthy Fats, Moderate Carbohydrates, and Caloric Balance",
"meal_plan": dietary_plan_response.content,
"important_considerations": """
- Hydration: Drink plenty of water throughout the day
- Electrolytes: Monitor sodium, potassium, and magnesium levels
- Fiber: Ensure adequate intake through vegetables and fruits
- Listen to your body: Adjust portion sizes as needed
"""
}
fitness_plan_response = fitness_agent.run(user_profile)
fitness_plan = {
"goals": "Build strength, improve endurance, and maintain overall fitness",
"routine": fitness_plan_response.content,
"tips": """
- Track your progress regularly
- Allow proper rest between workouts
- Focus on proper form
- Stay consistent with your routine
"""
}
st.session_state.dietary_plan = dietary_plan
st.session_state.fitness_plan = fitness_plan
st.session_state.plans_generated = True
st.session_state.qa_pairs = []
display_dietary_plan(dietary_plan)
display_fitness_plan(fitness_plan)
except Exception as e:
st.error(f"❌ An error occurred: {e}")
if st.session_state.plans_generated:
st.header("❓ Questions about your plan?")
question_input = st.text_input("What would you like to know?")
if st.button("Get Answer"):
if question_input:
with st.spinner("Finding the best answer for you..."):
dietary_plan = st.session_state.dietary_plan
fitness_plan = st.session_state.fitness_plan
context = f"Dietary Plan: {dietary_plan.get('meal_plan', '')}\n\nFitness Plan: {fitness_plan.get('routine', '')}"
full_context = f"{context}\nUser Question: {question_input}"
try:
agent = Agent(model=gemini_model, show_tool_calls=True, markdown=True)
run_response = agent.run(full_context)
if hasattr(run_response, 'content'):
answer = run_response.content
else:
answer = "Sorry, I couldn't generate a response at this time."
st.session_state.qa_pairs.append((question_input, answer))
except Exception as e:
st.error(f"❌ An error occurred while getting the answer: {e}")
if st.session_state.qa_pairs:
st.header("💬 Q&A History")
for question, answer in st.session_state.qa_pairs:
st.markdown(f"**Q:** {question}")
st.markdown(f"**A:** {answer}")
if __name__ == "__main__":
main()

View file

@ -0,0 +1,3 @@
google-generativeai==0.8.3
streamlit==1.40.2
agno

View file

@ -1,5 +1,5 @@
## 📈 AI Investment Agent
This Streamlit app is an AI-powered investment agent that compares the performance of two stocks and generates detailed reports. By using GPT-4o with Yahoo Finance data, this app provides valuable insights to help you make informed investment decisions.
This Streamlit app is an AI-powered investment agent built with Agno's AI Agent framework that compares the performance of two stocks and generates detailed reports. By using GPT-4o with Yahoo Finance data, this app provides valuable insights to help you make informed investment decisions.
### Features
- Compare the performance of two stocks
@ -13,6 +13,7 @@ This Streamlit app is an AI-powered investment agent that compares the performan
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/ai_agent_tutorials/ai_investment_agent
```
2. Install the required dependencies:
@ -31,7 +32,7 @@ streamlit run investment_agent.py
### How it Works?
- Upon running the app, you will be prompted to enter your OpenAI API key. This key is used to authenticate and access the OpenAI language model.
- Once you provide a valid API key, an instance of the Assistant class is created. This assistant utilizes the GPT-4 language model from OpenAI and the YFinanceTools for accessing stock data.
- Once you provide a valid API key, an instance of the Assistant class is created. This assistant utilizes the GPT-4o language model from OpenAI and the YFinanceTools for accessing stock data.
- Enter the stock symbols of the two companies you want to compare in the provided text input fields.
- The assistant will perform the following steps:
- Retrieve real-time stock prices and historical data using YFinanceTools

View file

@ -1,30 +1,34 @@
# Import the required libraries
import streamlit as st
from phi.assistant import Assistant
from phi.llm.openai import OpenAIChat
from phi.tools.yfinance import YFinanceTools
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.yfinance import YFinanceTools
# Set up the Streamlit app
st.title("AI Investment Agent 📈🤖")
st.caption("This app allows you to compare the performance of two stocks and generate detailed reports.")
# Get OpenAI API key from user
openai_api_key = st.text_input("OpenAI API Key", type="password")
if openai_api_key:
# Create an instance of the Assistant
assistant = Assistant(
llm=OpenAIChat(model="gpt-4o", api_key=openai_api_key),
tools=[YFinanceTools(stock_price=True, analyst_recommendations=True, company_info=True, company_news=True)],
assistant = Agent(
model=OpenAIChat(id="gpt-4o", api_key=openai_api_key),
tools=[
YFinanceTools(stock_price=True, analyst_recommendations=True, stock_fundamentals=True)
],
show_tool_calls=True,
description="You are an investment analyst that researches stock prices, analyst recommendations, and stock fundamentals.",
instructions=[
"Format your response using markdown and use tables to display data where possible."
],
)
# Input fields for the stocks to compare
stock1 = st.text_input("Enter the first stock symbol")
stock2 = st.text_input("Enter the second stock symbol")
col1, col2 = st.columns(2)
with col1:
stock1 = st.text_input("Enter first stock symbol (e.g. AAPL)")
with col2:
stock2 = st.text_input("Enter second stock symbol (e.g. MSFT)")
if stock1 and stock2:
# Get the response from the assistant
query = f"Compare {stock1} to {stock2}. Use every tool you have."
response = assistant.run(query, stream=False)
st.write(response)
with st.spinner(f"Analyzing {stock1} and {stock2}..."):
query = f"Compare both the stocks - {stock1} and {stock2} and make a detailed report for an investment trying to invest and compare these stocks"
response = assistant.run(query, stream=False)
st.markdown(response.content)

View file

@ -1,4 +1,4 @@
streamlit
phidata
agno
openai
yfinance

View file

@ -12,6 +12,7 @@ This Streamlit app is an AI-powered journalist agent that generates high-quality
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/ai_agent_tutorials/ai_journalist_agent
```
2. Install the required dependencies:

View file

@ -1,10 +1,10 @@
# Import the required libraries
from textwrap import dedent
from phi.assistant import Assistant
from phi.tools.serpapi_tools import SerpApiTools
from phi.tools.newspaper_toolkit import NewspaperToolkit
from agno.agent import Agent
from agno.tools.serpapi import SerpApiTools
from agno.tools.newspaper4k import Newspaper4kTools
import streamlit as st
from phi.llm.openai import OpenAIChat
from agno.models.openai import OpenAIChat
# Set up the Streamlit app
st.title("AI Journalist Agent 🗞️")
@ -17,10 +17,10 @@ openai_api_key = st.text_input("Enter OpenAI API Key to access GPT-4o", type="pa
serp_api_key = st.text_input("Enter Serp API Key for Search functionality", type="password")
if openai_api_key and serp_api_key:
searcher = Assistant(
searcher = Agent(
name="Searcher",
role="Searches for top URLs based on a topic",
llm=OpenAIChat(model="gpt-4o", api_key=openai_api_key),
model=OpenAIChat(id="gpt-4o", api_key=openai_api_key),
description=dedent(
"""\
You are a world-class journalist for the New York Times. Given a topic, generate a list of 3 search terms
@ -37,10 +37,10 @@ if openai_api_key and serp_api_key:
tools=[SerpApiTools(api_key=serp_api_key)],
add_datetime_to_instructions=True,
)
writer = Assistant(
writer = Agent(
name="Writer",
role="Retrieves text from URLs and writes a high-quality article",
llm=OpenAIChat(model="gpt-4o", api_key=openai_api_key),
model=OpenAIChat(id="gpt-4o", api_key=openai_api_key),
description=dedent(
"""\
You are a senior writer for the New York Times. Given a topic and a list of URLs,
@ -57,15 +57,14 @@ if openai_api_key and serp_api_key:
"Focus on clarity, coherence, and overall quality.",
"Never make up facts or plagiarize. Always provide proper attribution.",
],
tools=[NewspaperToolkit()],
tools=[Newspaper4kTools()],
add_datetime_to_instructions=True,
add_chat_history_to_prompt=True,
num_history_messages=3,
markdown=True,
)
editor = Assistant(
editor = Agent(
name="Editor",
llm=OpenAIChat(model="gpt-4o", api_key=openai_api_key),
model=OpenAIChat(id="gpt-4o", api_key=openai_api_key),
team=[searcher, writer],
description="You are a senior NYT editor. Given a topic, your goal is to write a NYT worthy article.",
instructions=[
@ -88,4 +87,4 @@ if openai_api_key and serp_api_key:
with st.spinner("Processing..."):
# Get the response from the assistant
response = editor.run(query, stream=False)
st.write(response)
st.write(response.content)

View file

@ -1,6 +1,6 @@
streamlit
phidata
agno
openai
google-search-results
newspaper3k
newspaper4k
lxml_html_clean

View file

@ -0,0 +1,35 @@
## 🎯 AI Lead Generation Agent - Powered by Firecrawl's Extract Endpoint
The AI Lead Generation Agent automates the process of finding and qualifying potential leads from Quora. It uses Firecrawl's search and the new Extract endpoint to identify relevant user profiles, extract valuable information, and organize it into a structured format in Google Sheets. This agent helps sales and marketing teams efficiently build targeted lead lists while saving hours of manual research.
### Features
- **Targeted Search**: Uses Firecrawl's search endpoint to find relevant Quora URLs based on your search criteria
- **Intelligent Extraction**: Leverages Firecrawl's new Extract endpoint to pull user information from Quora profiles
- **Automated Processing**: Formats extracted user information into a clean, structured format
- **Google Sheets Integration**: Automatically creates and populates Google Sheets with lead information
- **Customizable Criteria**: Allows you to define specific search parameters to find your ideal leads for your niche
### How to Get Started
1. **Clone the repository**:
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd ai_agent_tutorials/ai_lead_generation_agent
```
3. **Install the required packages**:
```bash
pip install -r requirements.txt
```
4. **Important thing to do in composio**:
- in the terminal, run this command: `composio add googlesheets`
- In your compposio dashboard, create a new google sheet intergation and make sure it is active in the active integrations/connections tab
5. **Set up your API keys**:
- Get your Firecrawl API key from [Firecrawl's website](https://www.firecrawl.dev/app/api-keys)
- Get your Composio API key from [Composio's website](https://composio.ai)
- Get your OpenAI API key from [OpenAI's website](https://platform.openai.com/api-keys)
6. **Run the application**:
```bash
streamlit run ai_lead_generation_agent.py
```

View file

@ -0,0 +1,209 @@
import streamlit as st
import requests
from agno.agent import Agent
from agno.tools.firecrawl import FirecrawlTools
from agno.models.openai import OpenAIChat
from firecrawl import FirecrawlApp
from pydantic import BaseModel, Field
from typing import List
from composio_phidata import Action, ComposioToolSet
import json
class QuoraUserInteractionSchema(BaseModel):
username: str = Field(description="The username of the user who posted the question or answer")
bio: str = Field(description="The bio or description of the user")
post_type: str = Field(description="The type of post, either 'question' or 'answer'")
timestamp: str = Field(description="When the question or answer was posted")
upvotes: int = Field(default=0, description="Number of upvotes received")
links: List[str] = Field(default_factory=list, description="Any links included in the post")
class QuoraPageSchema(BaseModel):
interactions: List[QuoraUserInteractionSchema] = Field(description="List of all user interactions (questions and answers) on the page")
def search_for_urls(company_description: str, firecrawl_api_key: str, num_links: int) -> List[str]:
url = "https://api.firecrawl.dev/v1/search"
headers = {
"Authorization": f"Bearer {firecrawl_api_key}",
"Content-Type": "application/json"
}
query1 = f"quora websites where people are looking for {company_description} services"
payload = {
"query": query1,
"limit": num_links,
"lang": "en",
"location": "United States",
"timeout": 60000,
}
response = requests.post(url, json=payload, headers=headers)
if response.status_code == 200:
data = response.json()
if data.get("success"):
results = data.get("data", [])
return [result["url"] for result in results]
return []
def extract_user_info_from_urls(urls: List[str], firecrawl_api_key: str) -> List[dict]:
user_info_list = []
firecrawl_app = FirecrawlApp(api_key=firecrawl_api_key)
try:
for url in urls:
response = firecrawl_app.extract(
[url],
{
'prompt': 'Extract all user information including username, bio, post type (question/answer), timestamp, upvotes, and any links from Quora posts. Focus on identifying potential leads who are asking questions or providing answers related to the topic.',
'schema': QuoraPageSchema.model_json_schema(),
}
)
if response.get('success') and response.get('status') == 'completed':
interactions = response.get('data', {}).get('interactions', [])
if interactions:
user_info_list.append({
"website_url": url,
"user_info": interactions
})
except Exception:
pass
return user_info_list
def format_user_info_to_flattened_json(user_info_list: List[dict]) -> List[dict]:
flattened_data = []
for info in user_info_list:
website_url = info["website_url"]
user_info = info["user_info"]
for interaction in user_info:
flattened_interaction = {
"Website URL": website_url,
"Username": interaction.get("username", ""),
"Bio": interaction.get("bio", ""),
"Post Type": interaction.get("post_type", ""),
"Timestamp": interaction.get("timestamp", ""),
"Upvotes": interaction.get("upvotes", 0),
"Links": ", ".join(interaction.get("links", [])),
}
flattened_data.append(flattened_interaction)
return flattened_data
def create_google_sheets_agent(composio_api_key: str, openai_api_key: str) -> Agent:
composio_toolset = ComposioToolSet(api_key=composio_api_key)
google_sheets_tool = composio_toolset.get_tools(actions=[Action.GOOGLESHEETS_SHEET_FROM_JSON])[0]
google_sheets_agent = Agent(
model=OpenAIChat(id="gpt-4o-mini", api_key=openai_api_key),
tools=[google_sheets_tool],
show_tool_calls=True,
system_prompt="You are an expert at creating and updating Google Sheets. You will be given user information in JSON format, and you need to write it into a new Google Sheet.",
markdown=True
)
return google_sheets_agent
def write_to_google_sheets(flattened_data: List[dict], composio_api_key: str, openai_api_key: str) -> str:
google_sheets_agent = create_google_sheets_agent(composio_api_key, openai_api_key)
try:
message = (
"Create a new Google Sheet with this data. "
"The sheet should have these columns: Website URL, Username, Bio, Post Type, Timestamp, Upvotes, and Links in the same order as mentioned. "
"Here's the data in JSON format:\n\n"
f"{json.dumps(flattened_data, indent=2)}"
)
create_sheet_response = google_sheets_agent.run(message)
if "https://docs.google.com/spreadsheets/d/" in create_sheet_response.content:
google_sheets_link = create_sheet_response.content.split("https://docs.google.com/spreadsheets/d/")[1].split(" ")[0]
return f"https://docs.google.com/spreadsheets/d/{google_sheets_link}"
except Exception:
pass
return None
def create_prompt_transformation_agent(openai_api_key: str) -> Agent:
return Agent(
model=OpenAIChat(id="gpt-4o-mini", api_key=openai_api_key),
system_prompt="""You are an expert at transforming detailed user queries into concise company descriptions.
Your task is to extract the core business/product focus in 3-4 words.
Examples:
Input: "Generate leads looking for AI-powered customer support chatbots for e-commerce stores."
Output: "AI customer support chatbots for e commerce"
Input: "Find people interested in voice cloning technology for creating audiobooks and podcasts"
Output: "voice cloning technology"
Input: "Looking for users who need automated video editing software with AI capabilities"
Output: "AI video editing software"
Input: "Need to find businesses interested in implementing machine learning solutions for fraud detection"
Output: "ML fraud detection"
Always focus on the core product/service and keep it concise but clear.""",
markdown=True
)
def main():
st.title("🎯 AI Lead Generation Agent")
st.info("This firecrawl powered agent helps you generate leads from Quora by searching for relevant posts and extracting user information.")
with st.sidebar:
st.header("API Keys")
firecrawl_api_key = st.text_input("Firecrawl API Key", type="password")
st.caption(" Get your Firecrawl API key from [Firecrawl's website](https://www.firecrawl.dev/app/api-keys)")
openai_api_key = st.text_input("OpenAI API Key", type="password")
st.caption(" Get your OpenAI API key from [OpenAI's website](https://platform.openai.com/api-keys)")
composio_api_key = st.text_input("Composio API Key", type="password")
st.caption(" Get your Composio API key from [Composio's website](https://composio.ai)")
num_links = st.number_input("Number of links to search", min_value=1, max_value=10, value=3)
if st.button("Reset"):
st.session_state.clear()
st.experimental_rerun()
user_query = st.text_area(
"Describe what kind of leads you're looking for:",
placeholder="e.g., Looking for users who need automated video editing software with AI capabilities",
help="Be specific about the product/service and target audience. The AI will convert this into a focused search query."
)
if st.button("Generate Leads"):
if not all([firecrawl_api_key, openai_api_key, composio_api_key, user_query]):
st.error("Please fill in all the API keys and describe what leads you're looking for.")
else:
with st.spinner("Processing your query..."):
transform_agent = create_prompt_transformation_agent(openai_api_key)
company_description = transform_agent.run(f"Transform this query into a concise 3-4 word company description: {user_query}")
st.write("🎯 Searching for:", company_description.content)
with st.spinner("Searching for relevant URLs..."):
urls = search_for_urls(company_description.content, firecrawl_api_key, num_links)
if urls:
st.subheader("Quora Links Used:")
for url in urls:
st.write(url)
with st.spinner("Extracting user info from URLs..."):
user_info_list = extract_user_info_from_urls(urls, firecrawl_api_key)
with st.spinner("Formatting user info..."):
flattened_data = format_user_info_to_flattened_json(user_info_list)
with st.spinner("Writing to Google Sheets..."):
google_sheets_link = write_to_google_sheets(flattened_data, composio_api_key, openai_api_key)
if google_sheets_link:
st.success("Lead generation and data writing to Google Sheets completed successfully!")
st.subheader("Google Sheets Link:")
st.markdown(f"[View Google Sheet]({google_sheets_link})")
else:
st.error("Failed to retrieve the Google Sheets link.")
else:
st.warning("No relevant URLs found.")
if __name__ == "__main__":
main()

View file

@ -0,0 +1,6 @@
firecrawl-py==1.9.0
agno
composio-phidata
composio==0.1.1
pydantic==2.10.5
streamlit

View file

@ -0,0 +1,56 @@
# 👨‍⚖️ AI Legal Agent Team
A Streamlit application that simulates a full-service legal team using multiple AI agents to analyze legal documents and provide comprehensive legal insights. Each agent represents a different legal specialist role, from research and contract analysis to strategic planning, working together to provide thorough legal analysis and recommendations.
## Features
- **Specialized Legal AI Agent Team**
- **Legal Researcher**: Equipped with DuckDuckGo search tool to find and cite relevant legal cases and precedents. Provides detailed research summaries with sources and references specific sections from uploaded documents.
- **Contract Analyst**: Specializes in thorough contract review, identifying key terms, obligations, and potential issues. References specific clauses from documents for detailed analysis.
- **Legal Strategist**: Focuses on developing comprehensive legal strategies, providing actionable recommendations while considering both risks and opportunities.
- **Team Lead**: Coordinates analysis between team members, ensures comprehensive responses, properly sourced recommendations, and references to specific document parts. Acts as an Agent Team coordinator for all three agents.
- **Document Analysis Types**
- Contract Review - Done by Contract Analyst
- Legal Research - Done by Legal Researcher
- Risk Assessment - Done by Legal Strategist, Contract Analyst
- Compliance Check - Done by Legal Strategist, Legal Researcher, Contract Analyst
- Custom Queries - Done by Agent Team - Legal Researcher, Legal Strategist, Contract Analyst
## How to Run
1. **Setup Environment**
```bash
# Clone the repository
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/ai_agent_tutorials/ai_legal_agent_team
# Install dependencies
pip install -r requirements.txt
```
2. **Configure API Keys**
- Get OpenAI API key from [OpenAI Platform](https://platform.openai.com)
- Get Qdrant API key and URL from [Qdrant Cloud](https://cloud.qdrant.io)
3. **Run the Application**
```bash
streamlit run legal_agent_team.py
```
4. **Use the Interface**
- Enter API credentials
- Upload a legal document (PDF)
- Select analysis type
- Add custom queries if needed
- View analysis results
## Notes
- Supports PDF documents only
- Uses GPT-4o for analysis
- Uses text-embedding-3-small for embeddings
- Requires stable internet connection
- API usage costs apply

View file

@ -0,0 +1,400 @@
import streamlit as st
from agno.agent import Agent
from agno.knowledge.pdf import PDFKnowledgeBase, PDFReader
from agno.vectordb.qdrant import Qdrant
from agno.tools.duckduckgo import DuckDuckGoTools
from agno.models.openai import OpenAIChat
from agno.embedder.openai import OpenAIEmbedder
import tempfile
import os
from agno.document.chunking.document import DocumentChunking
def init_session_state():
"""Initialize session state variables"""
if 'openai_api_key' not in st.session_state:
st.session_state.openai_api_key = None
if 'qdrant_api_key' not in st.session_state:
st.session_state.qdrant_api_key = None
if 'qdrant_url' not in st.session_state:
st.session_state.qdrant_url = None
if 'vector_db' not in st.session_state:
st.session_state.vector_db = None
if 'legal_team' not in st.session_state:
st.session_state.legal_team = None
if 'knowledge_base' not in st.session_state:
st.session_state.knowledge_base = None
# Add a new state variable to track processed files
if 'processed_files' not in st.session_state:
st.session_state.processed_files = set()
COLLECTION_NAME = "legal_documents" # Define your collection name
def init_qdrant():
"""Initialize Qdrant client with configured settings."""
if not all([st.session_state.qdrant_api_key, st.session_state.qdrant_url]):
return None
try:
# Create Agno's Qdrant instance which implements VectorDb
vector_db = Qdrant(
collection=COLLECTION_NAME,
url=st.session_state.qdrant_url,
api_key=st.session_state.qdrant_api_key,
embedder=OpenAIEmbedder(
id="text-embedding-3-small",
api_key=st.session_state.openai_api_key
)
)
return vector_db
except Exception as e:
st.error(f"🔴 Qdrant connection failed: {str(e)}")
return None
def process_document(uploaded_file, vector_db: Qdrant):
"""
Process document, create embeddings and store in Qdrant vector database
Args:
uploaded_file: Streamlit uploaded file object
vector_db (Qdrant): Initialized Qdrant instance from Agno
Returns:
PDFKnowledgeBase: Initialized knowledge base with processed documents
"""
if not st.session_state.openai_api_key:
raise ValueError("OpenAI API key not provided")
os.environ['OPENAI_API_KEY'] = st.session_state.openai_api_key
try:
# Save the uploaded file to a temporary location
with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') as temp_file:
temp_file.write(uploaded_file.getvalue())
temp_file_path = temp_file.name
st.info("Loading and processing document...")
# Create a PDFKnowledgeBase with the vector_db
knowledge_base = PDFKnowledgeBase(
path=temp_file_path, # Single string path, not a list
vector_db=vector_db,
reader=PDFReader(),
chunking_strategy=DocumentChunking(
chunk_size=1000,
overlap=200
)
)
# Load the documents into the knowledge base
with st.spinner('📤 Loading documents into knowledge base...'):
try:
knowledge_base.load(recreate=True, upsert=True)
st.success("✅ Documents stored successfully!")
except Exception as e:
st.error(f"Error loading documents: {str(e)}")
raise
# Clean up the temporary file
try:
os.unlink(temp_file_path)
except Exception:
pass
return knowledge_base
except Exception as e:
st.error(f"Document processing error: {str(e)}")
raise Exception(f"Error processing document: {str(e)}")
def main():
st.set_page_config(page_title="Legal Document Analyzer", layout="wide")
init_session_state()
st.title("AI Legal Agent Team 👨‍⚖️")
with st.sidebar:
st.header("🔑 API Configuration")
openai_key = st.text_input(
"OpenAI API Key",
type="password",
value=st.session_state.openai_api_key if st.session_state.openai_api_key else "",
help="Enter your OpenAI API key"
)
if openai_key:
st.session_state.openai_api_key = openai_key
qdrant_key = st.text_input(
"Qdrant API Key",
type="password",
value=st.session_state.qdrant_api_key if st.session_state.qdrant_api_key else "",
help="Enter your Qdrant API key"
)
if qdrant_key:
st.session_state.qdrant_api_key = qdrant_key
qdrant_url = st.text_input(
"Qdrant URL",
value=st.session_state.qdrant_url if st.session_state.qdrant_url else "",
help="Enter your Qdrant instance URL"
)
if qdrant_url:
st.session_state.qdrant_url = qdrant_url
if all([st.session_state.qdrant_api_key, st.session_state.qdrant_url]):
try:
if not st.session_state.vector_db:
# Make sure we're initializing a QdrantClient here
st.session_state.vector_db = init_qdrant()
if st.session_state.vector_db:
st.success("Successfully connected to Qdrant!")
except Exception as e:
st.error(f"Failed to connect to Qdrant: {str(e)}")
st.divider()
if all([st.session_state.openai_api_key, st.session_state.vector_db]):
st.header("📄 Document Upload")
uploaded_file = st.file_uploader("Upload Legal Document", type=['pdf'])
if uploaded_file:
# Check if this file has already been processed
if uploaded_file.name not in st.session_state.processed_files:
with st.spinner("Processing document..."):
try:
# Process the document and get the knowledge base
knowledge_base = process_document(uploaded_file, st.session_state.vector_db)
if knowledge_base:
st.session_state.knowledge_base = knowledge_base
# Add the file to processed files
st.session_state.processed_files.add(uploaded_file.name)
# Initialize agents
legal_researcher = Agent(
name="Legal Researcher",
role="Legal research specialist",
model=OpenAIChat(id="gpt-4o"),
tools=[DuckDuckGoTools()],
knowledge=st.session_state.knowledge_base,
search_knowledge=True,
instructions=[
"Find and cite relevant legal cases and precedents",
"Provide detailed research summaries with sources",
"Reference specific sections from the uploaded document",
"Always search the knowledge base for relevant information"
],
show_tool_calls=True,
markdown=True
)
contract_analyst = Agent(
name="Contract Analyst",
role="Contract analysis specialist",
model=OpenAIChat(id="gpt-4o"),
knowledge=st.session_state.knowledge_base,
search_knowledge=True,
instructions=[
"Review contracts thoroughly",
"Identify key terms and potential issues",
"Reference specific clauses from the document"
],
markdown=True
)
legal_strategist = Agent(
name="Legal Strategist",
role="Legal strategy specialist",
model=OpenAIChat(id="gpt-4o"),
knowledge=st.session_state.knowledge_base,
search_knowledge=True,
instructions=[
"Develop comprehensive legal strategies",
"Provide actionable recommendations",
"Consider both risks and opportunities"
],
markdown=True
)
# Legal Agent Team
st.session_state.legal_team = Agent(
name="Legal Team Lead",
role="Legal team coordinator",
model=OpenAIChat(id="gpt-4o"),
team=[legal_researcher, contract_analyst, legal_strategist],
knowledge=st.session_state.knowledge_base,
search_knowledge=True,
instructions=[
"Coordinate analysis between team members",
"Provide comprehensive responses",
"Ensure all recommendations are properly sourced",
"Reference specific parts of the uploaded document",
"Always search the knowledge base before delegating tasks"
],
show_tool_calls=True,
markdown=True
)
st.success("✅ Document processed and team initialized!")
except Exception as e:
st.error(f"Error processing document: {str(e)}")
else:
# File already processed, just show a message
st.success("✅ Document already processed and team ready!")
st.divider()
st.header("🔍 Analysis Options")
analysis_type = st.selectbox(
"Select Analysis Type",
[
"Contract Review",
"Legal Research",
"Risk Assessment",
"Compliance Check",
"Custom Query"
]
)
else:
st.warning("Please configure all API credentials to proceed")
# Main content area
if not all([st.session_state.openai_api_key, st.session_state.vector_db]):
st.info("👈 Please configure your API credentials in the sidebar to begin")
elif not uploaded_file:
st.info("👈 Please upload a legal document to begin analysis")
elif st.session_state.legal_team:
# Create a dictionary for analysis type icons
analysis_icons = {
"Contract Review": "📑",
"Legal Research": "🔍",
"Risk Assessment": "⚠️",
"Compliance Check": "",
"Custom Query": "💭"
}
# Dynamic header with icon
st.header(f"{analysis_icons[analysis_type]} {analysis_type} Analysis")
analysis_configs = {
"Contract Review": {
"query": "Review this contract and identify key terms, obligations, and potential issues.",
"agents": ["Contract Analyst"],
"description": "Detailed contract analysis focusing on terms and obligations"
},
"Legal Research": {
"query": "Research relevant cases and precedents related to this document.",
"agents": ["Legal Researcher"],
"description": "Research on relevant legal cases and precedents"
},
"Risk Assessment": {
"query": "Analyze potential legal risks and liabilities in this document.",
"agents": ["Contract Analyst", "Legal Strategist"],
"description": "Combined risk analysis and strategic assessment"
},
"Compliance Check": {
"query": "Check this document for regulatory compliance issues.",
"agents": ["Legal Researcher", "Contract Analyst", "Legal Strategist"],
"description": "Comprehensive compliance analysis"
},
"Custom Query": {
"query": None,
"agents": ["Legal Researcher", "Contract Analyst", "Legal Strategist"],
"description": "Custom analysis using all available agents"
}
}
st.info(f"📋 {analysis_configs[analysis_type]['description']}")
st.write(f"🤖 Active Legal AI Agents: {', '.join(analysis_configs[analysis_type]['agents'])}") #dictionary!!
# Replace the existing user_query section with this:
if analysis_type == "Custom Query":
user_query = st.text_area(
"Enter your specific query:",
help="Add any specific questions or points you want to analyze"
)
else:
user_query = None # Set to None for non-custom queries
if st.button("Analyze"):
if analysis_type == "Custom Query" and not user_query:
st.warning("Please enter a query")
else:
with st.spinner("Analyzing document..."):
try:
# Ensure OpenAI API key is set
os.environ['OPENAI_API_KEY'] = st.session_state.openai_api_key
# Combine predefined and user queries
if analysis_type != "Custom Query":
combined_query = f"""
Using the uploaded document as reference:
Primary Analysis Task: {analysis_configs[analysis_type]['query']}
Focus Areas: {', '.join(analysis_configs[analysis_type]['agents'])}
Please search the knowledge base and provide specific references from the document.
"""
else:
combined_query = f"""
Using the uploaded document as reference:
{user_query}
Please search the knowledge base and provide specific references from the document.
Focus Areas: {', '.join(analysis_configs[analysis_type]['agents'])}
"""
response = st.session_state.legal_team.run(combined_query)
# Display results in tabs
tabs = st.tabs(["Analysis", "Key Points", "Recommendations"])
with tabs[0]:
st.markdown("### Detailed Analysis")
if response.content:
st.markdown(response.content)
else:
for message in response.messages:
if message.role == 'assistant' and message.content:
st.markdown(message.content)
with tabs[1]:
st.markdown("### Key Points")
key_points_response = st.session_state.legal_team.run(
f"""Based on this previous analysis:
{response.content}
Please summarize the key points in bullet points.
Focus on insights from: {', '.join(analysis_configs[analysis_type]['agents'])}"""
)
if key_points_response.content:
st.markdown(key_points_response.content)
else:
for message in key_points_response.messages:
if message.role == 'assistant' and message.content:
st.markdown(message.content)
with tabs[2]:
st.markdown("### Recommendations")
recommendations_response = st.session_state.legal_team.run(
f"""Based on this previous analysis:
{response.content}
What are your key recommendations based on the analysis, the best course of action?
Provide specific recommendations from: {', '.join(analysis_configs[analysis_type]['agents'])}"""
)
if recommendations_response.content:
st.markdown(recommendations_response.content)
else:
for message in recommendations_response.messages:
if message.role == 'assistant' and message.content:
st.markdown(message.content)
except Exception as e:
st.error(f"Error during analysis: {str(e)}")
else:
st.info("Please upload a legal document to begin analysis")
if __name__ == "__main__":
main()

View file

@ -0,0 +1,278 @@
import streamlit as st
from agno.agent import Agent
from agno.knowledge.pdf import PDFKnowledgeBase, PDFReader
from agno.vectordb.qdrant import Qdrant
from agno.models.ollama import Ollama
from agno.embedder.ollama import OllamaEmbedder
import tempfile
import os
def init_session_state():
if 'vector_db' not in st.session_state:
st.session_state.vector_db = None
if 'legal_team' not in st.session_state:
st.session_state.legal_team = None
if 'knowledge_base' not in st.session_state:
st.session_state.knowledge_base = None
def init_qdrant():
"""Initialize local Qdrant vector database"""
return Qdrant(
collection="legal_knowledge",
url="http://localhost:6333",
embedder=OllamaEmbedder(model="openhermes")
)
def process_document(uploaded_file, vector_db: Qdrant):
"""Process document using local resources"""
with tempfile.TemporaryDirectory() as temp_dir:
temp_file_path = os.path.join(temp_dir, uploaded_file.name)
with open(temp_file_path, "wb") as f:
f.write(uploaded_file.getbuffer())
try:
st.write("Processing document...")
# Create knowledge base with local embedder
knowledge_base = PDFKnowledgeBase(
path=temp_dir,
vector_db=vector_db,
reader=PDFReader(chunk=True),
recreate_vector_db=True
)
st.write("Loading knowledge base...")
knowledge_base.load()
# Verify knowledge base
st.write("Verifying knowledge base...")
test_results = knowledge_base.search("test")
if not test_results:
raise Exception("Knowledge base verification failed")
st.write("Knowledge base ready!")
return knowledge_base
except Exception as e:
raise Exception(f"Error processing document: {str(e)}")
def main():
st.set_page_config(page_title="Local Legal Document Analyzer", layout="wide")
init_session_state()
st.title("Local AI Legal Agent Team")
# Initialize local Qdrant
if not st.session_state.vector_db:
try:
st.session_state.vector_db = init_qdrant()
st.success("Connected to local Qdrant!")
except Exception as e:
st.error(f"Failed to connect to Qdrant: {str(e)}")
return
# Document upload section
st.header("📄 Document Upload")
uploaded_file = st.file_uploader("Upload Legal Document", type=['pdf'])
if uploaded_file:
with st.spinner("Processing document..."):
try:
knowledge_base = process_document(uploaded_file, st.session_state.vector_db)
st.session_state.knowledge_base = knowledge_base
# Initialize agents with Llama model
legal_researcher = Agent(
name="Legal Researcher",
role="Legal research specialist",
model=Ollama(id="llama3.1:8b"),
knowledge=st.session_state.knowledge_base,
search_knowledge=True,
instructions=[
"Find and cite relevant legal cases and precedents",
"Provide detailed research summaries with sources",
"Reference specific sections from the uploaded document"
],
markdown=True
)
contract_analyst = Agent(
name="Contract Analyst",
role="Contract analysis specialist",
model=Ollama(id="llama3.1:8b"),
knowledge=knowledge_base,
search_knowledge=True,
instructions=[
"Review contracts thoroughly",
"Identify key terms and potential issues",
"Reference specific clauses from the document"
],
markdown=True
)
legal_strategist = Agent(
name="Legal Strategist",
role="Legal strategy specialist",
model=Ollama(id="llama3.1:8b"),
knowledge=knowledge_base,
search_knowledge=True,
instructions=[
"Develop comprehensive legal strategies",
"Provide actionable recommendations",
"Consider both risks and opportunities"
],
markdown=True
)
# Legal Agent Team
st.session_state.legal_team = Agent(
name="Legal Team Lead",
role="Legal team coordinator",
model=Ollama(id="llama3.1:8b"),
team=[legal_researcher, contract_analyst, legal_strategist],
knowledge=st.session_state.knowledge_base,
search_knowledge=True,
instructions=[
"Coordinate analysis between team members",
"Provide comprehensive responses",
"Ensure all recommendations are properly sourced",
"Reference specific parts of the uploaded document"
],
markdown=True
)
st.success("✅ Document processed and team initialized!")
except Exception as e:
st.error(f"Error processing document: {str(e)}")
st.divider()
st.header("🔍 Analysis Options")
analysis_type = st.selectbox(
"Select Analysis Type",
[
"Contract Review",
"Legal Research",
"Risk Assessment",
"Compliance Check",
"Custom Query"
]
)
# Main content area
if not st.session_state.vector_db:
st.info("👈 Waiting for Qdrant connection...")
elif not uploaded_file:
st.info("👈 Please upload a legal document to begin analysis")
elif st.session_state.legal_team:
st.header("Document Analysis")
analysis_configs = {
"Contract Review": {
"query": "Review this contract and identify key terms, obligations, and potential issues.",
"agents": ["Contract Analyst"],
"description": "Detailed contract analysis focusing on terms and obligations"
},
"Legal Research": {
"query": "Research relevant cases and precedents related to this document.",
"agents": ["Legal Researcher"],
"description": "Research on relevant legal cases and precedents"
},
"Risk Assessment": {
"query": "Analyze potential legal risks and liabilities in this document.",
"agents": ["Contract Analyst", "Legal Strategist"],
"description": "Combined risk analysis and strategic assessment"
},
"Compliance Check": {
"query": "Check this document for regulatory compliance issues.",
"agents": ["Legal Researcher", "Contract Analyst", "Legal Strategist"],
"description": "Comprehensive compliance analysis"
},
"Custom Query": {
"query": None,
"agents": ["Legal Researcher", "Contract Analyst", "Legal Strategist"],
"description": "Custom analysis using all available agents"
}
}
st.info(f"📋 {analysis_configs[analysis_type]['description']}")
st.write(f"🤖 Active Agents: {', '.join(analysis_configs[analysis_type]['agents'])}")
user_query = st.text_area(
"Enter your specific query:",
help="Add any specific questions or points you want to analyze"
)
if st.button("Analyze"):
if user_query or analysis_type != "Custom Query":
with st.spinner("Analyzing document..."):
try:
# Combine predefined and user queries
if analysis_type != "Custom Query":
combined_query = f"""
Using the uploaded document as reference:
Primary Analysis Task: {analysis_configs[analysis_type]['query']}
Additional User Query: {user_query if user_query else 'None'}
Focus Areas: {', '.join(analysis_configs[analysis_type]['agents'])}
Please search the knowledge base and provide specific references from the document.
"""
else:
combined_query = user_query
response = st.session_state.legal_team.run(combined_query)
# Display results in tabs
tabs = st.tabs(["Analysis", "Key Points", "Recommendations"])
with tabs[0]:
st.markdown("### Detailed Analysis")
if response.content:
st.markdown(response.content)
else:
for message in response.messages:
if message.role == 'assistant' and message.content:
st.markdown(message.content)
with tabs[1]:
st.markdown("### Key Points")
key_points_response = st.session_state.legal_team.run(
f"""Based on this previous analysis:
{response.content}
Please summarize the key points in bullet points.
Focus on insights from: {', '.join(analysis_configs[analysis_type]['agents'])}"""
)
if key_points_response.content:
st.markdown(key_points_response.content)
else:
for message in key_points_response.messages:
if message.role == 'assistant' and message.content:
st.markdown(message.content)
with tabs[2]:
st.markdown("### Recommendations")
recommendations_response = st.session_state.legal_team.run(
f"""Based on this previous analysis:
{response.content}
What are your key recommendations based on the analysis, the best course of action?
Provide specific recommendations from: {', '.join(analysis_configs[analysis_type]['agents'])}"""
)
if recommendations_response.content:
st.markdown(recommendations_response.content)
else:
for message in recommendations_response.messages:
if message.role == 'assistant' and message.content:
st.markdown(message.content)
except Exception as e:
st.error(f"Error during analysis: {str(e)}")
else:
st.warning("Please enter a query or select an analysis type")
else:
st.info("Please upload a legal document to begin analysis")
if __name__ == "__main__":
main()

View file

@ -0,0 +1,4 @@
agno
streamlit==1.40.2
qdrant-client==1.12.1
ollama==0.4.4

View file

@ -0,0 +1,6 @@
agno
streamlit==1.40.2
qdrant-client==1.12.1
openai
pypdf
duckduckgo-search

View file

@ -0,0 +1,66 @@
# 🩻 Medical Imaging Diagnosis Agent
A Medical Imaging Diagnosis Agent build on agno powered by Gemini 2.0 Flash that provides AI-assisted analysis of medical images of various scans. The agent acts as a medical imaging diagnosis expert to analyze various types of medical images and videos, providing detailed diagnostic insights and explanations.
## Features
- **Comprehensive Image Analysis**
- Image Type Identification (X-ray, MRI, CT scan, ultrasound)
- Anatomical Region Detection
- Key Findings and Observations
- Potential Abnormalities Detection
- Image Quality Assessment
- Research and Reference
## How to Run
1. **Setup Environment**
```bash
# Clone the repository
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd ai_agent_tutorials/ai_medical_imaging_agent
# Install dependencies
pip install -r requirements.txt
```
2. **Configure API Keys**
- Get Google API key from [Google AI Studio](https://aistudio.google.com)
3. **Run the Application**
```bash
streamlit run ai_medical_imaging.py
```
## Analysis Components
- **Image Type and Region**
- Identifies imaging modality
- Specifies anatomical region
- **Key Findings**
- Systematic listing of observations
- Detailed appearance descriptions
- Abnormality highlighting
- **Diagnostic Assessment**
- Potential diagnoses ranking
- Differential diagnoses
- Severity assessment
- **Patient-Friendly Explanations**
- Simplified terminology
- Detailed first-principles explanations
- Visual reference points
## Notes
- Uses Gemini 2.0 Flash for analysis
- Requires stable internet connection
- Free API usage costs - 1,500 free requests per day by google!
- For educational and development purposes only
- Not a replacement for professional medical diagnosis
## Disclaimer
This tool is for educational and informational purposes only. All analyses should be reviewed by qualified healthcare professionals. Do not make medical decisions based solely on this analysis.

View file

@ -0,0 +1,156 @@
import os
from PIL import Image as PILImage
from agno.agent import Agent
from agno.models.google import Gemini
import streamlit as st
from agno.tools.duckduckgo import DuckDuckGoTools
from agno.media import Image as AgnoImage
if "GOOGLE_API_KEY" not in st.session_state:
st.session_state.GOOGLE_API_KEY = None
with st.sidebar:
st.title(" Configuration")
if not st.session_state.GOOGLE_API_KEY:
api_key = st.text_input(
"Enter your Google API Key:",
type="password"
)
st.caption(
"Get your API key from [Google AI Studio]"
"(https://aistudio.google.com/apikey) 🔑"
)
if api_key:
st.session_state.GOOGLE_API_KEY = api_key
st.success("API Key saved!")
st.rerun()
else:
st.success("API Key is configured")
if st.button("🔄 Reset API Key"):
st.session_state.GOOGLE_API_KEY = None
st.rerun()
st.info(
"This tool provides AI-powered analysis of medical imaging data using "
"advanced computer vision and radiological expertise."
)
st.warning(
"⚠DISCLAIMER: This tool is for educational and informational purposes only. "
"All analyses should be reviewed by qualified healthcare professionals. "
"Do not make medical decisions based solely on this analysis."
)
medical_agent = Agent(
model=Gemini(
id="gemini-2.0-flash",
api_key=st.session_state.GOOGLE_API_KEY
),
tools=[DuckDuckGoTools()],
markdown=True
) if st.session_state.GOOGLE_API_KEY else None
if not medical_agent:
st.warning("Please configure your API key in the sidebar to continue")
# Medical Analysis Query
query = """
You are a highly skilled medical imaging expert with extensive knowledge in radiology and diagnostic imaging. Analyze the patient's medical image and structure your response as follows:
### 1. Image Type & Region
- Specify imaging modality (X-ray/MRI/CT/Ultrasound/etc.)
- Identify the patient's anatomical region and positioning
- Comment on image quality and technical adequacy
### 2. Key Findings
- List primary observations systematically
- Note any abnormalities in the patient's imaging with precise descriptions
- Include measurements and densities where relevant
- Describe location, size, shape, and characteristics
- Rate severity: Normal/Mild/Moderate/Severe
### 3. Diagnostic Assessment
- Provide primary diagnosis with confidence level
- List differential diagnoses in order of likelihood
- Support each diagnosis with observed evidence from the patient's imaging
- Note any critical or urgent findings
### 4. Patient-Friendly Explanation
- Explain the findings in simple, clear language that the patient can understand
- Avoid medical jargon or provide clear definitions
- Include visual analogies if helpful
- Address common patient concerns related to these findings
### 5. Research Context
IMPORTANT: Use the DuckDuckGo search tool to:
- Find recent medical literature about similar cases
- Search for standard treatment protocols
- Provide a list of relevant medical links of them too
- Research any relevant technological advances
- Include 2-3 key references to support your analysis
Format your response using clear markdown headers and bullet points. Be concise yet thorough.
"""
st.title("🏥 Medical Imaging Diagnosis Agent")
st.write("Upload a medical image for professional analysis")
# Create containers for better organization
upload_container = st.container()
image_container = st.container()
analysis_container = st.container()
with upload_container:
uploaded_file = st.file_uploader(
"Upload Medical Image",
type=["jpg", "jpeg", "png", "dicom"],
help="Supported formats: JPG, JPEG, PNG, DICOM"
)
if uploaded_file is not None:
with image_container:
col1, col2, col3 = st.columns([1, 2, 1])
with col2:
image = PILImage.open(uploaded_file)
width, height = image.size
aspect_ratio = width / height
new_width = 500
new_height = int(new_width / aspect_ratio)
resized_image = image.resize((new_width, new_height))
st.image(
resized_image,
caption="Uploaded Medical Image",
use_container_width=True
)
analyze_button = st.button(
"🔍 Analyze Image",
type="primary",
use_container_width=True
)
with analysis_container:
if analyze_button:
with st.spinner("🔄 Analyzing image... Please wait."):
try:
temp_path = "temp_resized_image.png"
resized_image.save(temp_path)
# Create AgnoImage object
agno_image = AgnoImage(filepath=temp_path) # Adjust if constructor differs
# Run analysis
response = medical_agent.run(query, images=[agno_image])
st.markdown("### 📋 Analysis Results")
st.markdown("---")
st.markdown(response.content)
st.markdown("---")
st.caption(
"Note: This analysis is generated by AI and should be reviewed by "
"a qualified healthcare professional."
)
except Exception as e:
st.error(f"Analysis error: {e}")
else:
st.info("👆 Please upload a medical image to begin analysis")

View file

@ -0,0 +1,5 @@
streamlit==1.40.2
agno
Pillow==10.0.0
duckduckgo-search==6.4.1
google-generativeai==0.8.3

View file

@ -14,6 +14,7 @@ This Streamlit application leverages multiple AI agents to create comprehensive
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/ai_agent_tutorials/ai_meeting_agent
```
2. Install the required dependencies:

View file

@ -1,7 +1,6 @@
import streamlit as st
from crewai import Agent, Task, Crew, Process
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
from crewai import Agent, Task, Crew, LLM
from crewai.process import Process
from crewai_tools import SerperDevTool
import os
@ -11,20 +10,16 @@ st.title("AI Meeting Preparation Agent 📝")
# Sidebar for API keys
st.sidebar.header("API Keys")
openai_api_key = st.sidebar.text_input("OpenAI API Key", type="password")
anthropic_api_key = st.sidebar.text_input("Anthropic API Key", type="password")
serper_api_key = st.sidebar.text_input("Serper API Key", type="password")
# Check if all API keys are set
if openai_api_key and anthropic_api_key and serper_api_key:
# Set API keys as environment variables
os.environ["OPENAI_API_KEY"] = openai_api_key
if anthropic_api_key and serper_api_key:
# # Set API keys as environment variables
os.environ["ANTHROPIC_API_KEY"] = anthropic_api_key
os.environ["SERPER_API_KEY"] = serper_api_key
# Initialize the AI models and tools
gpt4 = ChatOpenAI(model_name="gpt-4o-mini")
claude = ChatAnthropic(model_name="claude-3-5-sonnet-20240620")
claude = LLM(model="claude-3-5-sonnet-20240620", temperature= 0.7, api_key=anthropic_api_key)
search_tool = SerperDevTool()
# Input fields
@ -41,7 +36,7 @@ if openai_api_key and anthropic_api_key and serper_api_key:
backstory='You are an expert at quickly understanding complex business contexts and identifying critical information.',
verbose=True,
allow_delegation=False,
llm=gpt4,
llm=claude,
tools=[search_tool]
)
@ -51,7 +46,7 @@ if openai_api_key and anthropic_api_key and serper_api_key:
backstory='You are a seasoned industry analyst with a knack for spotting emerging trends and opportunities.',
verbose=True,
allow_delegation=False,
llm=gpt4,
llm=claude,
tools=[search_tool]
)

View file

@ -0,0 +1,51 @@
# 🥸 AI Meme Generator Agent - Browser Use
The AI Meme Generator Agent is a powerful browser automation tool that creates memes using AI agents. This app combines multi-LLM capabilities with automated browser interactions to generate memes based on text prompts through direct website manipulation.
## Features
- **Multi-LLM Support**
- Claude 3.5 Sonnet (Anthropic)
- GPT-4o (OpenAI)
- Deepseek v3 (Deepseek)
- Automatic model switching with API key validation
- **Browser Automation**:
- Direct interaction with imgflip.com meme templates
- Automated search for relevant meme formats
- Dynamic text insertion for top/bottom captions
- Image link extraction from generated memes
- **Smart Generation Workflow**:
- Action verb extraction from prompts
- Metaphorical template matching
- Multi-step quality validation
- Automatic retry mechanism for failed generations
- **User-Friendly Interface**:
- Model configuration sidebar
- API key management
- Direct meme preview with clickable links
- Responsive error handling
API keys required:
- **Anthropic** (for Claude)
- **Deepseek**
- **OpenAI** (for GPT-4o)
## How to Run
1. **Clone the Repository**:
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd ai_agent_tutorials/ai_meme_generator_browseruse
```
2. **Install the dependencies**:
```bash
pip install -r requirements.txt
```
3. **Run the Streamlit app**:
```bash
streamlit run ai_meme_generator.py
```

View file

@ -0,0 +1,130 @@
import asyncio
import streamlit as st
from browser_use import Agent, SystemPrompt
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
from langchain_core.messages import HumanMessage
import re
async def generate_meme(query: str, model_choice: str, api_key: str) -> None:
# Initialize the appropriate LLM based on user selection
if model_choice == "Claude":
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 = (
"You are a meme generator expert. You are given a query and you need to generate a meme for it.\n"
"1. Go to https://imgflip.com/memetemplates \n"
"2. Click on the Search bar in the middle and search for ONLY ONE MAIN ACTION VERB (like 'bully', 'laugh', 'cry') in this query: '{0}'\n"
"3. Choose any meme template that metaphorically fits the meme topic: '{0}'\n"
" by clicking on the 'Add Caption' button below it\n"
"4. Write a Top Text (setup/context) and Bottom Text (punchline/outcome) related to '{0}'.\n"
"5. Check the preview making sure it is funny and a meaningful meme. Adjust text directly if needed. \n"
"6. Look at the meme and text on it, if it doesnt make sense, PLEASE retry by filling the text boxes with different text. \n"
"7. Click on the Generate meme button to generate the meme\n"
"8. Copy the image link and give it as the output\n"
).format(query)
agent = Agent(
task=task_description,
llm=llm,
max_actions_per_step=5,
max_failures=25,
use_vision=(model_choice != "Deepseek")
)
history = await agent.run()
# Extract final result from agent history
final_result = history.final_result()
# Use regex to find the meme URL in the result
url_match = re.search(r'https://imgflip\.com/i/(\w+)', final_result)
if url_match:
meme_id = url_match.group(1)
return f"https://i.imgflip.com/{meme_id}.jpg"
return None
def main():
# Custom CSS styling
st.title("🥸 AI Meme Generator Agent - Browser Use")
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.")
# Sidebar configuration
with st.sidebar:
st.markdown('<p class="sidebar-header">⚙️ Model Configuration</p>', unsafe_allow_html=True)
# 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
st.markdown('<p class="header-text">🎨 Describe Your Meme Concept</p>', unsafe_allow_html=True)
query = st.text_input(
"Meme Idea Input",
placeholder="Example: 'Ilya's SSI quietly looking at the OpenAI vs Deepseek debate while diligently working on ASI'",
label_visibility="collapsed"
)
if st.button("Generate Meme 🚀"):
if not api_key:
st.warning(f"Please provide the {model_choice} API key")
st.stop()
if not query:
st.warning("Please enter a meme idea")
st.stop()
with st.spinner(f"🧠 {model_choice} is generating your meme..."):
try:
meme_url = asyncio.run(generate_meme(query, model_choice, api_key))
if meme_url:
st.success("✅ Meme Generated Successfully!")
st.image(meme_url, caption="Generated Meme Preview", use_container_width=True)
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__':
main()

View file

@ -0,0 +1,6 @@
streamlit
browser-use==0.1.26
playwright==1.49.1
langchain-openai
langchain-anthropic
asyncio

View file

@ -0,0 +1,73 @@
# AI Mental Wellbeing Agent Team 🧠
The AI Mental Wellbeing Agent Team is a supportive mental health assessment and guidance system powered by [AG2](https://github.com/ag2ai/ag2?tab=readme-ov-file)(formerly AutoGen)'s AI Agent framework. This app provides personalized mental health support through the coordination of specialized AI agents, each focusing on different aspects of mental health care based on user inputs such as emotional state, stress levels, sleep patterns, and current symptoms. This is built on AG2's new swarm feature run through initiate_swarm_chat() method.
## Features
- **Specialized Mental Wellbeing Support Team**
- 🧠 **Assessment Agent**: Analyzes emotional state and psychological needs with clinical precision and empathy
- 🎯 **Action Agent**: Creates immediate action plans and connects users with appropriate resources
- 🔄 **Follow-up Agent**: Designs long-term support strategies and prevention plans
- **Comprehensive Mental Wellbeing Support**:
- Detailed psychological assessment
- Immediate coping strategies
- Resource recommendations
- Long-term support planning
- Crisis prevention strategies
- Progress monitoring systems
- **Customizable Input Parameters**:
- Current emotional state
- Sleep patterns
- Stress levels
- Support system information
- Recent life changes
- Current symptoms
- **Interactive Results**:
- Real-time assessment summaries
- Detailed recommendations in expandable sections
- Clear action steps and resources
- Long-term support strategies
## How to Run
Follow these steps to set up and run the application:
1. **Clone the Repository**:
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd ai_agent_tutorials/ai_mental_wellbeing_agent
```
2. **Install Dependencies**:
```bash
pip install -r requirements.txt
```
3. **Create Environment File**:
Create a `.env` file in the project directory:
```bash
echo "AUTOGEN_USE_DOCKER=0" > .env
```
This disables Docker requirement for code execution in AutoGen.
4. **Set Up OpenAI API Key**:
- Obtain an OpenAI API key from [OpenAI's platform](https://platform.openai.com)
- You'll input this key in the app's sidebar when running
5. **Run the Streamlit App**:
```bash
streamlit run ai_mental_wellbeing_agent.py
```
## ⚠️ Important Notice
This application is a supportive tool and does not replace professional mental health care. If you're experiencing thoughts of self-harm or severe crisis:
- Call National Crisis Hotline: 988
- Call Emergency Services: 911
- Seek immediate professional help

View file

@ -0,0 +1,226 @@
import streamlit as st
from autogen import (SwarmAgent, SwarmResult, initiate_swarm_chat, OpenAIWrapper,AFTER_WORK,UPDATE_SYSTEM_MESSAGE)
import os
os.environ["AUTOGEN_USE_DOCKER"] = "0"
if 'output' not in st.session_state:
st.session_state.output = {
'assessment': '',
'action': '',
'followup': ''
}
st.sidebar.title("OpenAI API Key")
api_key = st.sidebar.text_input("Enter your OpenAI API Key", type="password")
st.sidebar.warning("""
## ⚠️ Important Notice
This application is a supportive tool and does not replace professional mental health care. If you're experiencing thoughts of self-harm or severe crisis:
- Call National Crisis Hotline: 988
- Call Emergency Services: 911
- Seek immediate professional help
""")
st.title("🧠 Mental Wellbeing Agent")
st.info("""
**Meet Your Mental Wellbeing Agent Team:**
🧠 **Assessment Agent** - Analyzes your situation and emotional needs
🎯 **Action Agent** - Creates immediate action plan and connects you with resources
🔄 **Follow-up Agent** - Designs your long-term support strategy
""")
st.subheader("Personal Information")
col1, col2 = st.columns(2)
with col1:
mental_state = st.text_area("How have you been feeling recently?",
placeholder="Describe your emotional state, thoughts, or concerns...")
sleep_pattern = st.select_slider(
"Sleep Pattern (hours per night)",
options=[f"{i}" for i in range(0, 13)],
value="7"
)
with col2:
stress_level = st.slider("Current Stress Level (1-10)", 1, 10, 5)
support_system = st.multiselect(
"Current Support System",
["Family", "Friends", "Therapist", "Support Groups", "None"]
)
recent_changes = st.text_area(
"Any significant life changes or events recently?",
placeholder="Job changes, relationships, losses, etc..."
)
current_symptoms = st.multiselect(
"Current Symptoms",
["Anxiety", "Depression", "Insomnia", "Fatigue", "Loss of Interest",
"Difficulty Concentrating", "Changes in Appetite", "Social Withdrawal",
"Mood Swings", "Physical Discomfort"]
)
if st.button("Get Support Plan"):
if not api_key:
st.error("Please enter your OpenAI API key.")
else:
with st.spinner('🤖 AI Agents are analyzing your situation...'):
try:
task = f"""
Create a comprehensive mental health support plan based on:
Emotional State: {mental_state}
Sleep: {sleep_pattern} hours per night
Stress Level: {stress_level}/10
Support System: {', '.join(support_system) if support_system else 'None reported'}
Recent Changes: {recent_changes}
Current Symptoms: {', '.join(current_symptoms) if current_symptoms else 'None reported'}
"""
system_messages = {
"assessment_agent": """
You are an experienced mental health professional speaking directly to the user. Your task is to:
1. Create a safe space by acknowledging their courage in seeking support
2. Analyze their emotional state with clinical precision and genuine empathy
3. Ask targeted follow-up questions to understand their full situation
4. Identify patterns in their thoughts, behaviors, and relationships
5. Assess risk levels with validated screening approaches
6. Help them understand their current mental health in accessible language
7. Validate their experiences without minimizing or catastrophizing
Always use "you" and "your" when addressing the user. Blend clinical expertise with genuine warmth and never rush to conclusions.
""",
"action_agent": """
You are a crisis intervention and resource specialist speaking directly to the user. Your task is to:
1. Provide immediate evidence-based coping strategies tailored to their specific situation
2. Prioritize interventions based on urgency and effectiveness
3. Connect them with appropriate mental health services while acknowledging barriers (cost, access, stigma)
4. Create a concrete daily wellness plan with specific times and activities
5. Suggest specific support communities with details on how to join
6. Balance crisis resources with empowerment techniques
7. Teach simple self-regulation techniques they can use immediately
Focus on practical, achievable steps that respect their current capacity and energy levels. Provide options ranging from minimal effort to more involved actions.
""",
"followup_agent": """
You are a mental health recovery planner speaking directly to the user. Your task is to:
1. Design a personalized long-term support strategy with milestone markers
2. Create a progress monitoring system that matches their preferences and habits
3. Develop specific relapse prevention strategies based on their unique triggers
4. Establish a support network mapping exercise to identify existing resources
5. Build a graduated self-care routine that evolves with their recovery
6. Plan for setbacks with self-compassion techniques
7. Set up a maintenance schedule with clear check-in mechanisms
Focus on building sustainable habits that integrate with their lifestyle and values. Emphasize progress over perfection and teach skills for self-directed care.
"""
}
llm_config = {
"config_list": [{"model": "gpt-4o", "api_key": api_key}]
}
context_variables = {
"assessment": None,
"action": None,
"followup": None,
}
def update_assessment_overview(assessment_summary: str, context_variables: dict) -> SwarmResult:
context_variables["assessment"] = assessment_summary
st.sidebar.success('Assessment: ' + assessment_summary)
return SwarmResult(agent="action_agent", context_variables=context_variables)
def update_action_overview(action_summary: str, context_variables: dict) -> SwarmResult:
context_variables["action"] = action_summary
st.sidebar.success('Action Plan: ' + action_summary)
return SwarmResult(agent="followup_agent", context_variables=context_variables)
def update_followup_overview(followup_summary: str, context_variables: dict) -> SwarmResult:
context_variables["followup"] = followup_summary
st.sidebar.success('Follow-up Strategy: ' + followup_summary)
return SwarmResult(agent="assessment_agent", context_variables=context_variables)
def update_system_message_func(agent: SwarmAgent, messages) -> str:
system_prompt = system_messages[agent.name]
current_gen = agent.name.split("_")[0]
if agent._context_variables.get(current_gen) is None:
system_prompt += f"Call the update function provided to first provide a 2-3 sentence summary of your ideas on {current_gen.upper()} based on the context provided."
agent.llm_config['tool_choice'] = {"type": "function", "function": {"name": f"update_{current_gen}_overview"}}
else:
agent.llm_config["tools"] = None
agent.llm_config['tool_choice'] = None
system_prompt += f"\n\nYour task\nYou task is write the {current_gen} part of the report. Do not include any other parts. Do not use XML tags.\nStart your reponse with: '## {current_gen.capitalize()} Design'."
k = list(agent._oai_messages.keys())[-1]
agent._oai_messages[k] = agent._oai_messages[k][:1]
system_prompt += f"\n\n\nBelow are some context for you to refer to:"
for k, v in agent._context_variables.items():
if v is not None:
system_prompt += f"\n{k.capitalize()} Summary:\n{v}"
agent.client = OpenAIWrapper(**agent.llm_config)
return system_prompt
state_update = UPDATE_SYSTEM_MESSAGE(update_system_message_func)
assessment_agent = SwarmAgent(
"assessment_agent",
llm_config=llm_config,
functions=update_assessment_overview,
update_agent_state_before_reply=[state_update]
)
action_agent = SwarmAgent(
"action_agent",
llm_config=llm_config,
functions=update_action_overview,
update_agent_state_before_reply=[state_update]
)
followup_agent = SwarmAgent(
"followup_agent",
llm_config=llm_config,
functions=update_followup_overview,
update_agent_state_before_reply=[state_update]
)
assessment_agent.register_hand_off(AFTER_WORK(action_agent))
action_agent.register_hand_off(AFTER_WORK(followup_agent))
followup_agent.register_hand_off(AFTER_WORK(assessment_agent))
result, _, _ = initiate_swarm_chat(
initial_agent=assessment_agent,
agents=[assessment_agent, action_agent, followup_agent],
user_agent=None,
messages=task,
max_rounds=13,
)
st.session_state.output = {
'assessment': result.chat_history[-3]['content'],
'action': result.chat_history[-2]['content'],
'followup': result.chat_history[-1]['content']
}
with st.expander("Situation Assessment"):
st.markdown(st.session_state.output['assessment'])
with st.expander("Action Plan & Resources"):
st.markdown(st.session_state.output['action'])
with st.expander("Long-term Support Strategy"):
st.markdown(st.session_state.output['followup'])
st.success('✨ Mental health support plan generated successfully!')
except Exception as e:
st.error(f"An error occurred: {str(e)}")

View file

@ -0,0 +1,4 @@
autogen-agentchat
autogen-ext
pyautogen
streamlit

View file

@ -12,6 +12,7 @@ This Streamlit app is an AI-powered movie production assistant that helps bring
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/ai_agent_tutorials/ai_movie_production_agent
```
2. Install the required dependencies:

View file

@ -1,8 +1,8 @@
# Import the required libraries
import streamlit as st
from phi.assistant import Assistant
from phi.tools.serpapi_tools import SerpApiTools
from phi.llm.anthropic import Claude
from agno.agent import Agent
from agno.tools.serpapi import SerpApiTools
from agno.models.anthropic import Claude
from textwrap import dedent
# Set up the Streamlit app
@ -15,9 +15,9 @@ anthropic_api_key = st.text_input("Enter Anthropic API Key to access Claude Sonn
serp_api_key = st.text_input("Enter Serp API Key for Search functionality", type="password")
if anthropic_api_key and serp_api_key:
script_writer = Assistant(
script_writer = Agent(
name="ScriptWriter",
llm=Claude(model="claude-3-5-sonnet-20240620", api_key=anthropic_api_key),
model=Claude(id="claude-3-5-sonnet-20240620", api_key=anthropic_api_key),
description=dedent(
"""\
You are an expert screenplay writer. Given a movie idea and genre,
@ -31,9 +31,9 @@ if anthropic_api_key and serp_api_key:
],
)
casting_director = Assistant(
casting_director = Agent(
name="CastingDirector",
llm=Claude(model="claude-3-5-sonnet-20240620", api_key=anthropic_api_key),
model=Claude(id="claude-3-5-sonnet-20240620", api_key=anthropic_api_key),
description=dedent(
"""\
You are a talented casting director. Given a script outline and character descriptions,
@ -49,9 +49,9 @@ if anthropic_api_key and serp_api_key:
tools=[SerpApiTools(api_key=serp_api_key)],
)
movie_producer = Assistant(
movie_producer = Agent(
name="MovieProducer",
llm=Claude(model="claude-3-5-sonnet-20240620", api_key=anthropic_api_key),
model=Claude(id="claude-3-5-sonnet-20240620", api_key=anthropic_api_key),
team=[script_writer, casting_director],
description="Experienced movie producer overseeing script and casting.",
instructions=[

View file

@ -1,5 +1,5 @@
streamlit
phidata
agno
anthropic
google-search-results
lxml_html_clean

View file

@ -12,6 +12,7 @@ This Streamlit app is an AI-powered personal finance planner that generates pers
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/ai_agent_tutorials/ai_personal_finance_agent
```
2. Install the required dependencies:

View file

@ -1,8 +1,8 @@
from textwrap import dedent
from phi.assistant import Assistant
from phi.tools.serpapi_tools import SerpApiTools
from agno.agent import Agent
from agno.tools.serpapi import SerpApiTools
import streamlit as st
from phi.llm.openai import OpenAIChat
from agno.models.openai import OpenAIChat
# Set up the Streamlit app
st.title("AI Personal Finance Planner 💰")
@ -15,10 +15,10 @@ openai_api_key = st.text_input("Enter OpenAI API Key to access GPT-4o", type="pa
serp_api_key = st.text_input("Enter Serp API Key for Search functionality", type="password")
if openai_api_key and serp_api_key:
researcher = Assistant(
researcher = Agent(
name="Researcher",
role="Searches for financial advice, investment opportunities, and savings strategies based on user preferences",
llm=OpenAIChat(model="gpt-4o", api_key=openai_api_key),
model=OpenAIChat(id="gpt-4o", api_key=openai_api_key),
description=dedent(
"""\
You are a world-class financial researcher. Given a user's financial goals and current financial situation,
@ -35,10 +35,10 @@ if openai_api_key and serp_api_key:
tools=[SerpApiTools(api_key=serp_api_key)],
add_datetime_to_instructions=True,
)
planner = Assistant(
planner = Agent(
name="Planner",
role="Generates a personalized financial plan based on user preferences and research results",
llm=OpenAIChat(model="gpt-4o", api_key=openai_api_key),
model=OpenAIChat(id="gpt-4o", api_key=openai_api_key),
description=dedent(
"""\
You are a senior financial planner. Given a user's financial goals, current financial situation, and a list of research results,
@ -54,8 +54,6 @@ if openai_api_key and serp_api_key:
"Never make up facts or plagiarize. Always provide proper attribution.",
],
add_datetime_to_instructions=True,
add_chat_history_to_prompt=True,
num_history_messages=3,
)
# Input fields for the user's financial goals and current financial situation
@ -66,4 +64,4 @@ if openai_api_key and serp_api_key:
with st.spinner("Processing..."):
# Get the response from the assistant
response = planner.run(f"Financial goals: {financial_goals}, Current situation: {current_situation}", stream=False)
st.write(response)
st.write(response.content)

View file

@ -1,4 +1,4 @@
streamlit
phidata
agno
openai
google-search-results

View file

@ -0,0 +1,61 @@
## 🏠 AI Real Estate Agent - Powered by Firecrawl's Extract Endpoint
The AI Real Estate Agent automates property search and market analysis using Firecrawl's Extract endpoint and Agno AI Agent's insights. It helps users find properties matching their criteria while providing detailed location trends and investment recommendations. This agent streamlines the property search process by combining data from multiple real estate websites and offering intelligent analysis.
### Features
- **Smart Property Search**: Uses Firecrawl's Extract endpoint to find properties across multiple real estate websites
- **Multi-Source Integration**: Aggregates data from 99acres, Housing.com, Square Yards, Nobroker, and MagicBricks
- **Location Analysis**: Provides detailed price trends and investment insights for different localities
- **AI-Powered Recommendations**: Uses GPT models to analyze properties and provide structured recommendations
- **User-Friendly Interface**: Clean Streamlit UI for easy property search and results viewing
- **Customizable Search**: Filter by city, property type, category, and budget
### How to Get Started
1. **Clone the repository**:
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd ai_agent_tutorials/ai_real_estate_agent
```
2. **Install the required packages**:
```bash
pip install -r requirements.txt
```
3. **Set up your API keys**:
- Get your Firecrawl API key from [Firecrawl's website](https://www.firecrawl.dev/app/api-keys)
- Get your OpenAI API key from [OpenAI's website](https://platform.openai.com/api-keys)
4. **Run the application**:
```bash
streamlit run ai_real_estate_agent.py
```
### Using the Agent
1. **Enter API Keys**:
- Input your Firecrawl and OpenAI API keys in the sidebar
- Keys are securely stored in the session state
2. **Set Search Criteria**:
- Enter the city name
- Select property category (Residential/Commercial)
- Choose property type (Flat/Individual House)
- Set maximum budget in Crores
3. **View Results**:
- Property recommendations with detailed analysis
- Location trends with investment insights
- Expandable sections for easy reading
### Features in Detail
- **Property Finding**:
- Searches across multiple real estate websites
- Returns 3-6 properties matching criteria
- Provides detailed property information and analysis
- **Location Analysis**:
- Price trends for different localities
- Rental yield analysis
- Investment potential assessment
- Top performing areas identification

View file

@ -0,0 +1,321 @@
from typing import Dict, List
from pydantic import BaseModel, Field
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from firecrawl import FirecrawlApp
import streamlit as st
class PropertyData(BaseModel):
"""Schema for property data extraction"""
building_name: str = Field(description="Name of the building/property", alias="Building_name")
property_type: str = Field(description="Type of property (commercial, residential, etc)", alias="Property_type")
location_address: str = Field(description="Complete address of the property")
price: str = Field(description="Price of the property", alias="Price")
description: str = Field(description="Detailed description of the property", alias="Description")
class PropertiesResponse(BaseModel):
"""Schema for multiple properties response"""
properties: List[PropertyData] = Field(description="List of property details")
class LocationData(BaseModel):
"""Schema for location price trends"""
location: str
price_per_sqft: float
percent_increase: float
rental_yield: float
class LocationsResponse(BaseModel):
"""Schema for multiple locations response"""
locations: List[LocationData] = Field(description="List of location data points")
class FirecrawlResponse(BaseModel):
"""Schema for Firecrawl API response"""
success: bool
data: Dict
status: str
expiresAt: str
class PropertyFindingAgent:
"""Agent responsible for finding properties and providing recommendations"""
def __init__(self, firecrawl_api_key: str, openai_api_key: str, model_id: str = "o3-mini"):
self.agent = Agent(
model=OpenAIChat(id=model_id, api_key=openai_api_key),
markdown=True,
description="I am a real estate expert who helps find and analyze properties based on user preferences."
)
self.firecrawl = FirecrawlApp(api_key=firecrawl_api_key)
def find_properties(
self,
city: str,
max_price: float,
property_category: str = "Residential",
property_type: str = "Flat"
) -> str:
"""Find and analyze properties based on user preferences"""
formatted_location = city.lower()
urls = [
f"https://www.squareyards.com/sale/property-for-sale-in-{formatted_location}/*",
f"https://www.99acres.com/property-in-{formatted_location}-ffid/*",
f"https://housing.com/in/buy/{formatted_location}/{formatted_location}",
# f"https://www.nobroker.in/property/sale/{city}/{formatted_location}",
]
property_type_prompt = "Flats" if property_type == "Flat" else "Individual Houses"
raw_response = self.firecrawl.extract(
urls=urls,
params={
'prompt': f"""Extract ONLY 10 OR LESS different {property_category} {property_type_prompt} from {city} that cost less than {max_price} crores.
Requirements:
- Property Category: {property_category} properties only
- Property Type: {property_type_prompt} only
- Location: {city}
- Maximum Price: {max_price} crores
- Include complete property details with exact location
- IMPORTANT: Return data for at least 3 different properties. MAXIMUM 10.
- Format as a list of properties with their respective details
""",
'schema': PropertiesResponse.model_json_schema()
}
)
print("Raw Property Response:", raw_response)
if isinstance(raw_response, dict) and raw_response.get('success'):
properties = raw_response['data'].get('properties', [])
else:
properties = []
print("Processed Properties:", properties)
analysis = self.agent.run(
f"""As a real estate expert, analyze these properties and market trends:
Properties Found in json format:
{properties}
**IMPORTANT INSTRUCTIONS:**
1. ONLY analyze properties from the above JSON data that match the user's requirements:
- Property Category: {property_category}
- Property Type: {property_type}
- Maximum Price: {max_price} crores
2. DO NOT create new categories or property types
3. From the matching properties, select 5-6 properties with prices closest to {max_price} crores
Please provide your analysis in this format:
🏠 SELECTED PROPERTIES
List only 5-6 best matching properties with prices closest to {max_price} crores
For each property include:
- Name and Location
- Price (with value analysis)
- Key Features
- Pros and Cons
💰 BEST VALUE ANALYSIS
Compare the selected properties based on:
- Price per sq ft
- Location advantage
- Amenities offered
📍 LOCATION INSIGHTS
Specific advantages of the areas where selected properties are located
💡 RECOMMENDATIONS
Top 3 properties from the selection with reasoning
Investment potential
Points to consider before purchase
🤝 NEGOTIATION TIPS
Property-specific negotiation strategies
Format your response in a clear, structured way using the above sections.
"""
)
return analysis.content
def get_location_trends(self, city: str) -> str:
"""Get price trends for different localities in the city"""
raw_response = self.firecrawl.extract([
f"https://www.99acres.com/property-rates-and-price-trends-in-{city.lower()}-prffid/*"
], {
'prompt': """Extract price trends data for ALL major localities in the city.
IMPORTANT:
- Return data for at least 5-10 different localities
- Include both premium and affordable areas
- Do not skip any locality mentioned in the source
- Format as a list of locations with their respective data
""",
'schema': LocationsResponse.model_json_schema(),
})
if isinstance(raw_response, dict) and raw_response.get('success'):
locations = raw_response['data'].get('locations', [])
analysis = self.agent.run(
f"""As a real estate expert, analyze these location price trends for {city}:
{locations}
Please provide:
1. A bullet-point summary of the price trends for each location
2. Identify the top 3 locations with:
- Highest price appreciation
- Best rental yields
- Best value for money
3. Investment recommendations:
- Best locations for long-term investment
- Best locations for rental income
- Areas showing emerging potential
4. Specific advice for investors based on these trends
Format the response as follows:
📊 LOCATION TRENDS SUMMARY
[Bullet points for each location]
🏆 TOP PERFORMING AREAS
[Bullet points for best areas]
💡 INVESTMENT INSIGHTS
[Bullet points with investment advice]
🎯 RECOMMENDATIONS
[Bullet points with specific recommendations]
"""
)
return analysis.content
return "No price trends data available"
def create_property_agent():
"""Create PropertyFindingAgent with API keys from session state"""
if 'property_agent' not in st.session_state:
st.session_state.property_agent = PropertyFindingAgent(
firecrawl_api_key=st.session_state.firecrawl_key,
openai_api_key=st.session_state.openai_key,
model_id=st.session_state.model_id
)
def main():
st.set_page_config(
page_title="AI Real Estate Agent",
page_icon="🏠",
layout="wide"
)
with st.sidebar:
st.title("🔑 API Configuration")
st.subheader("🤖 Model Selection")
model_id = st.selectbox(
"Choose OpenAI Model",
options=["o3-mini", "gpt-4o"],
help="Select the AI model to use. Choose gpt-4o if your api doesn't have access to o3-mini"
)
st.session_state.model_id = model_id
st.divider()
st.subheader("🔐 API Keys")
firecrawl_key = st.text_input(
"Firecrawl API Key",
type="password",
help="Enter your Firecrawl API key"
)
openai_key = st.text_input(
"OpenAI API Key",
type="password",
help="Enter your OpenAI API key"
)
if firecrawl_key and openai_key:
st.session_state.firecrawl_key = firecrawl_key
st.session_state.openai_key = openai_key
create_property_agent()
st.title("🏠 AI Real Estate Agent")
st.info(
"""
Welcome to the AI Real Estate Agent!
Enter your search criteria below to get property recommendations
and location insights.
"""
)
col1, col2 = st.columns(2)
with col1:
city = st.text_input(
"City",
placeholder="Enter city name (e.g., Bangalore)",
help="Enter the city where you want to search for properties"
)
property_category = st.selectbox(
"Property Category",
options=["Residential", "Commercial"],
help="Select the type of property you're interested in"
)
with col2:
max_price = st.number_input(
"Maximum Price (in Crores)",
min_value=0.1,
max_value=100.0,
value=5.0,
step=0.1,
help="Enter your maximum budget in Crores"
)
property_type = st.selectbox(
"Property Type",
options=["Flat", "Individual House"],
help="Select the specific type of property"
)
if st.button("🔍 Start Search", use_container_width=True):
if 'property_agent' not in st.session_state:
st.error("⚠️ Please enter your API keys in the sidebar first!")
return
if not city:
st.error("⚠️ Please enter a city name!")
return
try:
with st.spinner("🔍 Searching for properties..."):
property_results = st.session_state.property_agent.find_properties(
city=city,
max_price=max_price,
property_category=property_category,
property_type=property_type
)
st.success("✅ Property search completed!")
st.subheader("🏘️ Property Recommendations")
st.markdown(property_results)
st.divider()
with st.spinner("📊 Analyzing location trends..."):
location_trends = st.session_state.property_agent.get_location_trends(city)
st.success("✅ Location analysis completed!")
with st.expander("📈 Location Trends Analysis of the city"):
st.markdown(location_trends)
except Exception as e:
st.error(f"❌ An error occurred: {str(e)}")
if __name__ == "__main__":
main()

View file

@ -0,0 +1,5 @@
agno
firecrawl-py==1.9.0
pydantic
streamlit
openai

View file

@ -0,0 +1,51 @@
## AI Reasoning Agent
The AI Reasoning Agent leverages advanced AI models to provide insightful reasoning and decision-making capabilities. This agent is designed to assist users in various analytical tasks by processing information and generating structured outputs.
### Features
- **Advanced Reasoning**: Utilizes the Ollama model to perform complex reasoning tasks
- **Interactive Playground**: Provides a user-friendly interface for interacting with the reasoning agent
- **Markdown Support**: Outputs results in markdown format for easy readability and sharing
- **Customizable Agent**: Easily configurable to suit different reasoning scenarios
### How to Get Started
1. **Clone the repository**:
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd ai_agent_tutorials/ai_reasoning_agent
```
2. **Install the required packages**:
#### For Local AI Reasoning Agent
```bash
pip install -r requirements_local_ai_reasoning_agent.txt
```
3. **Run the application**:
```bash
python local_ai_reasoning_agent.py
```
### Using the Agent
1. **Access the Playground**:
- Open the provided URL to access the interactive playground
- The playground allows you to input queries and receive structured reasoning outputs
2. **Input Queries**:
- Enter your queries in the provided input field
- The agent processes the input and provides detailed reasoning and analysis
3. **View Results**:
- Results are displayed in markdown format
- Easily copy and share the outputs for further use
### Features in Detail
- **Reasoning Capabilities**:
- Handles a wide range of analytical tasks
- Provides clear and structured outputs
- Supports markdown for easy sharing and readability
- **Interactive Interface**:
- User-friendly playground for seamless interaction
- Real-time processing and output generation
- Configurable settings to tailor the agent's behavior

View file

@ -0,0 +1,12 @@
from agno.agent import Agent
from agno.models.ollama import Ollama
from agno.playground import Playground, serve_playground_app
reasoning_agent = Agent(name="Reasoning Agent", model=Ollama(id="qwq:32b"), markdown=True)
# UI for Reasoning agent
app = Playground(agents=[reasoning_agent]).get_app()
# Run the Playground app
if __name__ == "__main__":
serve_playground_app("local_ai_reasoning_agent:app", reload=True)

View file

@ -1,9 +1,9 @@
from phi.agent import Agent
from phi.model.openai import OpenAIChat
from phi.cli.console import console
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from rich.console import Console
regular_agent = Agent(model=OpenAIChat(id="gpt-4o-mini"), markdown=True)
console = Console()
reasoning_agent = Agent(
model=OpenAIChat(id="gpt-4o"),
reasoning=True,

View file

@ -0,0 +1,4 @@
agno
ollama
fastapi
uvicorn

View file

@ -0,0 +1,101 @@
# 💼 AI Recruitment Agent Team
A Streamlit application that simulates a full-service recruitment team using multiple AI agents to automate and streamline the hiring process. Each agent represents a different recruitment specialist role - from resume analysis and candidate evaluation to interview scheduling and communication - working together to provide comprehensive hiring solutions. The system combines the expertise of technical recruiters, HR coordinators, and scheduling specialists into a cohesive automated workflow.
## Features
#### Specialized AI Agents
- Technical Recruiter Agent: Analyzes resumes and evaluates technical skills
- Communication Agent: Handles professional email correspondence
- Scheduling Coordinator Agent: Manages interview scheduling and coordination
- Each agent has specific expertise and collaborates for comprehensive recruitment
#### End-to-End Recruitment Process
- Automated resume screening and analysis
- Role-specific technical evaluation
- Professional candidate communication
- Automated interview scheduling
- Integrated feedback system
## Important Things to do before running the application
- Create/Use a new Gmail account for the recruiter
- Enable 2-Step Verification and generate an App Password for the Gmail account
- The App Password is a 16 digit code (use without spaces) that should be generated here - [Google App Password](https://support.google.com/accounts/answer/185833?hl=en) Please go through the steps to generate the password - it will of the format - 'afec wejf awoj fwrv' (remove the spaces and enter it in the streamlit app)
- Create/ Use a Zoom account and go to the Zoom App Marketplace to get the API credentials :
[Zoom Marketplace](https://marketplace.zoom.us)
- Go to Developer Dashboard and create a new app - Select Server to Server OAuth and get the credentials, You see 3 credentials - Client ID, Client Secret and Account ID
- After that, you need to add a few scopes to the app - so that the zoom link of the candidate is sent and created through the mail.
- The Scopes are meeting:write:invite_links:admin, meeting:write:meeting:admin, meeting:write:meeting:master, meeting:write:invite_links:master, meeting:write:open_app:admin, user:read:email:admin, user:read:list_users:admin, billing:read:user_entitlement:admin, dashboard:read:list_meeting_participants:admin [last 3 are optional]
## How to Run
1. **Setup Environment**
```bash
# Clone the repository
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd ai_agent_tutorials/ai_recruitment_agent_team
# Install dependencies
pip install -r requirements.txt
```
2. **Configure API Keys**
- OpenAI API key for GPT-4o access
- Zoom API credentials (Account ID, Client ID, Client Secret)
- Email App Password of Recruiter's Email
3. **Run the Application**
```bash
streamlit run ai_recruitment_agent_team.py
```
## System Components
- **Resume Analyzer Agent**
- Skills matching algorithm
- Experience verification
- Technical assessment
- Selection decision making
- **Email Communication Agent**
- Professional email drafting
- Automated notifications
- Feedback communication
- Follow-up management
- **Interview Scheduler Agent**
- Zoom meeting coordination
- Calendar management
- Timezone handling
- Reminder system
- **Candidate Experience**
- Simple upload interface
- Real-time feedback
- Clear communication
- Streamlined process
## Technical Stack
- **Framework**: Phidata
- **Model**: OpenAI GPT-4o
- **Integration**: Zoom API, EmailTools Tool from Phidata
- **PDF Processing**: PyPDF2
- **Time Management**: pytz
- **State Management**: Streamlit Session State
## Disclaimer
This tool is designed to assist in the recruitment process but should not completely replace human judgment in hiring decisions. All automated decisions should be reviewed by human recruiters for final approval.
## Future Enhancements
- Integration with ATS systems
- Advanced candidate scoring
- Video interview capabilities
- Skills assessment integration
- Multi-language support

View file

@ -0,0 +1,521 @@
from typing import Literal, Tuple, Dict, Optional
import os
import time
import json
import requests
import PyPDF2
from datetime import datetime, timedelta
import pytz
import streamlit as st
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.email import EmailTools
from phi.tools.zoom import ZoomTool
from phi.utils.log import logger
from streamlit_pdf_viewer import pdf_viewer
class CustomZoomTool(ZoomTool):
def __init__(self, *, account_id: Optional[str] = None, client_id: Optional[str] = None, client_secret: Optional[str] = None, name: str = "zoom_tool"):
super().__init__(account_id=account_id, client_id=client_id, client_secret=client_secret, name=name)
self.token_url = "https://zoom.us/oauth/token"
self.access_token = None
self.token_expires_at = 0
def get_access_token(self) -> str:
if self.access_token and time.time() < self.token_expires_at:
return str(self.access_token)
headers = {"Content-Type": "application/x-www-form-urlencoded"}
data = {"grant_type": "account_credentials", "account_id": self.account_id}
try:
response = requests.post(self.token_url, headers=headers, data=data, auth=(self.client_id, self.client_secret))
response.raise_for_status()
token_info = response.json()
self.access_token = token_info["access_token"]
expires_in = token_info["expires_in"]
self.token_expires_at = time.time() + expires_in - 60
self._set_parent_token(str(self.access_token))
return str(self.access_token)
except requests.RequestException as e:
logger.error(f"Error fetching access token: {e}")
return ""
def _set_parent_token(self, token: str) -> None:
"""Helper method to set the token in the parent ZoomTool class"""
if token:
self._ZoomTool__access_token = token
# Role requirements as a constant dictionary
ROLE_REQUIREMENTS: Dict[str, str] = {
"ai_ml_engineer": """
Required Skills:
- Python, PyTorch/TensorFlow
- Machine Learning algorithms and frameworks
- Deep Learning and Neural Networks
- Data preprocessing and analysis
- MLOps and model deployment
- RAG, LLM, Finetuning and Prompt Engineering
""",
"frontend_engineer": """
Required Skills:
- React/Vue.js/Angular
- HTML5, CSS3, JavaScript/TypeScript
- Responsive design
- State management
- Frontend testing
""",
"backend_engineer": """
Required Skills:
- Python/Java/Node.js
- REST APIs
- Database design and management
- System architecture
- Cloud services (AWS/GCP/Azure)
- Kubernetes, Docker, CI/CD
"""
}
def init_session_state() -> None:
"""Initialize only necessary session state variables."""
defaults = {
'candidate_email': "", 'openai_api_key': "", 'resume_text': "", 'analysis_complete': False,
'is_selected': False, 'zoom_account_id': "", 'zoom_client_id': "", 'zoom_client_secret': "",
'email_sender': "", 'email_passkey': "", 'company_name': "", 'current_pdf': None
}
for key, value in defaults.items():
if key not in st.session_state:
st.session_state[key] = value
def create_resume_analyzer() -> Agent:
"""Creates and returns a resume analysis agent."""
if not st.session_state.openai_api_key:
st.error("Please enter your OpenAI API key first.")
return None
return Agent(
model=OpenAIChat(
id="gpt-4o",
api_key=st.session_state.openai_api_key
),
description="You are an expert technical recruiter who analyzes resumes.",
instructions=[
"Analyze the resume against the provided job requirements",
"Be lenient with AI/ML candidates who show strong potential",
"Consider project experience as valid experience",
"Value hands-on experience with key technologies",
"Return a JSON response with selection decision and feedback"
],
markdown=True
)
def create_email_agent() -> Agent:
return Agent(
model=OpenAIChat(
id="gpt-4o",
api_key=st.session_state.openai_api_key
),
tools=[EmailTools(
receiver_email=st.session_state.candidate_email,
sender_email=st.session_state.email_sender,
sender_name=st.session_state.company_name,
sender_passkey=st.session_state.email_passkey
)],
description="You are a professional recruitment coordinator handling email communications.",
instructions=[
"Draft and send professional recruitment emails",
"Act like a human writing an email and use all lowercase letters",
"Maintain a friendly yet professional tone",
"Always end emails with exactly: 'best,\nthe ai recruiting team'",
"Never include the sender's or receiver's name in the signature",
f"The name of the company is '{st.session_state.company_name}'"
],
markdown=True,
show_tool_calls=True
)
def create_scheduler_agent() -> Agent:
zoom_tools = CustomZoomTool(
account_id=st.session_state.zoom_account_id,
client_id=st.session_state.zoom_client_id,
client_secret=st.session_state.zoom_client_secret
)
return Agent(
name="Interview Scheduler",
model=OpenAIChat(
id="gpt-4o",
api_key=st.session_state.openai_api_key
),
tools=[zoom_tools],
description="You are an interview scheduling coordinator.",
instructions=[
"You are an expert at scheduling technical interviews using Zoom.",
"Schedule interviews during business hours (9 AM - 5 PM EST)",
"Create meetings with proper titles and descriptions",
"Ensure all meeting details are included in responses",
"Use ISO 8601 format for dates",
"Handle scheduling errors gracefully"
],
markdown=True,
show_tool_calls=True
)
def extract_text_from_pdf(pdf_file) -> str:
try:
pdf_reader = PyPDF2.PdfReader(pdf_file)
text = ""
for page in pdf_reader.pages:
text += page.extract_text()
return text
except Exception as e:
st.error(f"Error extracting PDF text: {str(e)}")
return ""
def analyze_resume(
resume_text: str,
role: Literal["ai_ml_engineer", "frontend_engineer", "backend_engineer"],
analyzer: Agent
) -> Tuple[bool, str]:
try:
response = analyzer.run(
f"""Please analyze this resume against the following requirements and provide your response in valid JSON format:
Role Requirements:
{ROLE_REQUIREMENTS[role]}
Resume Text:
{resume_text}
Your response must be a valid JSON object like this:
{{
"selected": true/false,
"feedback": "Detailed feedback explaining the decision",
"matching_skills": ["skill1", "skill2"],
"missing_skills": ["skill3", "skill4"],
"experience_level": "junior/mid/senior"
}}
Evaluation criteria:
1. Match at least 70% of required skills
2. Consider both theoretical knowledge and practical experience
3. Value project experience and real-world applications
4. Consider transferable skills from similar technologies
5. Look for evidence of continuous learning and adaptability
Important: Return ONLY the JSON object without any markdown formatting or backticks.
"""
)
assistant_message = next((msg.content for msg in response.messages if msg.role == 'assistant'), None)
if not assistant_message:
raise ValueError("No assistant message found in response.")
result = json.loads(assistant_message.strip())
if not isinstance(result, dict) or not all(k in result for k in ["selected", "feedback"]):
raise ValueError("Invalid response format")
return result["selected"], result["feedback"]
except (json.JSONDecodeError, ValueError) as e:
st.error(f"Error processing response: {str(e)}")
return False, f"Error analyzing resume: {str(e)}"
def send_selection_email(email_agent: Agent, to_email: str, role: str) -> None:
email_agent.run(
f"""
Send an email to {to_email} regarding their selection for the {role} position.
The email should:
1. Congratulate them on being selected
2. Explain the next steps in the process
3. Mention that they will receive interview details shortly
4. The name of the company is 'AI Recruiting Team'
"""
)
def send_rejection_email(email_agent: Agent, to_email: str, role: str, feedback: str) -> None:
"""
Send a rejection email with constructive feedback.
"""
email_agent.run(
f"""
Send an email to {to_email} regarding their application for the {role} position.
Use this specific style:
1. use all lowercase letters
2. be empathetic and human
3. mention specific feedback from: {feedback}
4. encourage them to upskill and try again
5. suggest some learning resources based on missing skills
6. end the email with exactly:
best,
the ai recruiting team
Do not include any names in the signature.
The tone should be like a human writing a quick but thoughtful email.
"""
)
def schedule_interview(scheduler: Agent, candidate_email: str, email_agent: Agent, role: str) -> None:
"""
Schedule interviews during business hours (9 AM - 5 PM IST).
"""
try:
# Get current time in IST
ist_tz = pytz.timezone('Asia/Kolkata')
current_time_ist = datetime.now(ist_tz)
tomorrow_ist = current_time_ist + timedelta(days=1)
interview_time = tomorrow_ist.replace(hour=11, minute=0, second=0, microsecond=0)
formatted_time = interview_time.strftime('%Y-%m-%dT%H:%M:%S')
meeting_response = scheduler.run(
f"""Schedule a 60-minute technical interview with these specifications:
- Title: '{role} Technical Interview'
- Date: {formatted_time}
- Timezone: IST (India Standard Time)
- Attendee: {candidate_email}
Important Notes:
- The meeting must be between 9 AM - 5 PM IST
- Use IST (UTC+5:30) timezone for all communications
- Include timezone information in the meeting details
"""
)
email_agent.run(
f"""Send an interview confirmation email with these details:
- Role: {role} position
- Meeting Details: {meeting_response}
Important:
- Clearly specify that the time is in IST (India Standard Time)
- Ask the candidate to join 5 minutes early
- Include timezone conversion link if possible
- Ask him to be confident and not so nervous and prepare well for the interview
"""
)
st.success("Interview scheduled successfully! Check your email for details.")
except Exception as e:
logger.error(f"Error scheduling interview: {str(e)}")
st.error("Unable to schedule interview. Please try again.")
def main() -> None:
st.title("AI Recruitment System")
init_session_state()
with st.sidebar:
st.header("Configuration")
# OpenAI Configuration
st.subheader("OpenAI Settings")
api_key = st.text_input("OpenAI API Key", type="password", value=st.session_state.openai_api_key, help="Get your API key from platform.openai.com")
if api_key: st.session_state.openai_api_key = api_key
st.subheader("Zoom Settings")
zoom_account_id = st.text_input("Zoom Account ID", type="password", value=st.session_state.zoom_account_id)
zoom_client_id = st.text_input("Zoom Client ID", type="password", value=st.session_state.zoom_client_id)
zoom_client_secret = st.text_input("Zoom Client Secret", type="password", value=st.session_state.zoom_client_secret)
st.subheader("Email Settings")
email_sender = st.text_input("Sender Email", value=st.session_state.email_sender, help="Email address to send from")
email_passkey = st.text_input("Email App Password", type="password", value=st.session_state.email_passkey, help="App-specific password for email")
company_name = st.text_input("Company Name", value=st.session_state.company_name, help="Name to use in email communications")
if zoom_account_id: st.session_state.zoom_account_id = zoom_account_id
if zoom_client_id: st.session_state.zoom_client_id = zoom_client_id
if zoom_client_secret: st.session_state.zoom_client_secret = zoom_client_secret
if email_sender: st.session_state.email_sender = email_sender
if email_passkey: st.session_state.email_passkey = email_passkey
if company_name: st.session_state.company_name = company_name
required_configs = {'OpenAI API Key': st.session_state.openai_api_key, 'Zoom Account ID': st.session_state.zoom_account_id,
'Zoom Client ID': st.session_state.zoom_client_id, 'Zoom Client Secret': st.session_state.zoom_client_secret,
'Email Sender': st.session_state.email_sender, 'Email Password': st.session_state.email_passkey,
'Company Name': st.session_state.company_name}
missing_configs = [k for k, v in required_configs.items() if not v]
if missing_configs:
st.warning(f"Please configure the following in the sidebar: {', '.join(missing_configs)}")
return
if not st.session_state.openai_api_key:
st.warning("Please enter your OpenAI API key in the sidebar to continue.")
return
role = st.selectbox("Select the role you're applying for:", ["ai_ml_engineer", "frontend_engineer", "backend_engineer"])
with st.expander("View Required Skills", expanded=True): st.markdown(ROLE_REQUIREMENTS[role])
# Add a "New Application" button before the resume upload
if st.button("📝 New Application"):
# Clear only the application-related states
keys_to_clear = ['resume_text', 'analysis_complete', 'is_selected', 'candidate_email', 'current_pdf']
for key in keys_to_clear:
if key in st.session_state:
st.session_state[key] = None if key == 'current_pdf' else ""
st.rerun()
resume_file = st.file_uploader("Upload your resume (PDF)", type=["pdf"], key="resume_uploader")
if resume_file is not None and resume_file != st.session_state.get('current_pdf'):
st.session_state.current_pdf = resume_file
st.session_state.resume_text = ""
st.session_state.analysis_complete = False
st.session_state.is_selected = False
st.rerun()
if resume_file:
st.subheader("Uploaded Resume")
col1, col2 = st.columns([4, 1])
with col1:
import tempfile, os
with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') as tmp_file:
tmp_file.write(resume_file.read())
tmp_file_path = tmp_file.name
resume_file.seek(0)
try: pdf_viewer(tmp_file_path)
finally: os.unlink(tmp_file_path)
with col2:
st.download_button(label="📥 Download", data=resume_file, file_name=resume_file.name, mime="application/pdf")
# Process the resume text
if not st.session_state.resume_text:
with st.spinner("Processing your resume..."):
resume_text = extract_text_from_pdf(resume_file)
if resume_text:
st.session_state.resume_text = resume_text
st.success("Resume processed successfully!")
else:
st.error("Could not process the PDF. Please try again.")
# Email input with session state
email = st.text_input(
"Candidate's email address",
value=st.session_state.candidate_email,
key="email_input"
)
st.session_state.candidate_email = email
# Analysis and next steps
if st.session_state.resume_text and email and not st.session_state.analysis_complete:
if st.button("Analyze Resume"):
with st.spinner("Analyzing your resume..."):
resume_analyzer = create_resume_analyzer()
email_agent = create_email_agent() # Create email agent here
if resume_analyzer and email_agent:
print("DEBUG: Starting resume analysis")
is_selected, feedback = analyze_resume(
st.session_state.resume_text,
role,
resume_analyzer
)
print(f"DEBUG: Analysis complete - Selected: {is_selected}, Feedback: {feedback}")
if is_selected:
st.success("Congratulations! Your skills match our requirements.")
st.session_state.analysis_complete = True
st.session_state.is_selected = True
st.rerun()
else:
st.warning("Unfortunately, your skills don't match our requirements.")
st.write(f"Feedback: {feedback}")
# Send rejection email
with st.spinner("Sending feedback email..."):
try:
send_rejection_email(
email_agent=email_agent,
to_email=email,
role=role,
feedback=feedback
)
st.info("We've sent you an email with detailed feedback.")
except Exception as e:
logger.error(f"Error sending rejection email: {e}")
st.error("Could not send feedback email. Please try again.")
if st.session_state.get('analysis_complete') and st.session_state.get('is_selected', False):
st.success("Congratulations! Your skills match our requirements.")
st.info("Click 'Proceed with Application' to continue with the interview process.")
if st.button("Proceed with Application", key="proceed_button"):
print("DEBUG: Proceed button clicked") # Debug
with st.spinner("🔄 Processing your application..."):
try:
print("DEBUG: Creating email agent") # Debug
email_agent = create_email_agent()
print(f"DEBUG: Email agent created: {email_agent}") # Debug
print("DEBUG: Creating scheduler agent") # Debug
scheduler_agent = create_scheduler_agent()
print(f"DEBUG: Scheduler agent created: {scheduler_agent}") # Debug
# 3. Send selection email
with st.status("📧 Sending confirmation email...", expanded=True) as status:
print(f"DEBUG: Attempting to send email to {st.session_state.candidate_email}") # Debug
send_selection_email(
email_agent,
st.session_state.candidate_email,
role
)
print("DEBUG: Email sent successfully") # Debug
status.update(label="✅ Confirmation email sent!")
# 4. Schedule interview
with st.status("📅 Scheduling interview...", expanded=True) as status:
print("DEBUG: Attempting to schedule interview") # Debug
schedule_interview(
scheduler_agent,
st.session_state.candidate_email,
email_agent,
role
)
print("DEBUG: Interview scheduled successfully") # Debug
status.update(label="✅ Interview scheduled!")
print("DEBUG: All processes completed successfully") # Debug
st.success("""
🎉 Application Successfully Processed!
Please check your email for:
1. Selection confirmation
2. Interview details with Zoom link 🔗
Next steps:
1. Review the role requirements
2. Prepare for your technical interview
3. Join the interview 5 minutes early
""")
except Exception as e:
print(f"DEBUG: Error occurred: {str(e)}") # Debug
print(f"DEBUG: Error type: {type(e)}") # Debug
import traceback
print(f"DEBUG: Full traceback: {traceback.format_exc()}") # Debug
st.error(f"An error occurred: {str(e)}")
st.error("Please try again or contact support.")
# Reset button
if st.sidebar.button("Reset Application"):
for key in st.session_state.keys():
if key != 'openai_api_key':
del st.session_state[key]
st.rerun()
if __name__ == "__main__":
main()

View file

@ -0,0 +1,13 @@
# Core dependencies
phidata
agno
streamlit==1.40.2
PyPDF2==3.0.1
streamlit-pdf-viewer==0.0.19
requests==2.32.3
pytz==2023.4
typing-extensions>=4.9.0
# Optional but recommended
black>=24.1.1 # for code formatting
python-dateutil>=2.8.2 # for date parsing

View file

@ -0,0 +1,80 @@
# AI Services Agency 👨‍💼
An AI application that simulates a full-service digital agency using multiple AI agents to analyze and plan software projects. Each agent represents a different role in the project lifecycle, from strategic planning to technical implementation.
## Demo:
https://github.com/user-attachments/assets/a0befa3a-f4c3-400d-9790-4b9e37254405
## Features
### Five specialized AI agents
- **CEO Agent**: Strategic leader and final decision maker
- Analyzes startup ideas using structured evaluation
- Makes strategic decisions across product, technical, marketing, and financial domains
- Uses AnalyzeStartupTool and MakeStrategicDecision tools
- **CTO Agent**: Technical architecture and feasibility expert
- Evaluates technical requirements and feasibility
- Provides architecture decisions
- Uses QueryTechnicalRequirements and EvaluateTechnicalFeasibility tools
- **Product Manager Agent**: Product strategy specialist
- Defines product strategy and roadmap
- Coordinates between technical and marketing teams
- Focuses on product-market fit
- **Developer Agent**: Technical implementation expert
- Provides detailed technical implementation guidance
- Suggests optimal tech stack and cloud solutions
- Estimates development costs and timelines
- **Client Success Agent**: Marketing strategy leader
- Develops go-to-market strategies
- Plans customer acquisition approaches
- Coordinates with product team
### Custom Tools
The agency uses specialized tools built with OpenAI Schema for structured analysis:
- **Analysis Tools**: AnalyzeProjectRequirements for market evaluation and analysis of startup idea
- **Technical Tools**: CreateTechnicalSpecification for technical assessment
### 🔄 Asynchronous Communication
The agency operates in async mode, enabling:
- Parallel processing of analyses from different agents
- Efficient multi-agent collaboration
- Real-time communication between agents
- Non-blocking operations for better performance
### 🔗 Agent Communication Flows
- CEO ↔️ All Agents (Strategic Oversight)
- CTO ↔️ Developer (Technical Implementation)
- Product Manager ↔️ Marketing Manager (Go-to-Market Strategy)
- Product Manager ↔️ Developer (Feature Implementation)
- (and more!)
## How to Run
Follow the steps below to set up and run the application:
Before anything else, Please get your OpenAI API Key here: https://platform.openai.com/api-keys
1. **Clone the Repository**:
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/ai_agent_tutorials/ai_services_agency
```
2. **Install the dependencies**:
```bash
pip install -r requirements.txt
```
3. **Run the Streamlit app**:
```bash
streamlit run ai_services_agency/agency.py
```
4. **Enter your OpenAI API Key** in the sidebar when prompted and start analyzing your startup idea!

View file

@ -0,0 +1,365 @@
from typing import List, Literal, Dict, Optional
from agency_swarm import Agent, Agency, set_openai_key, BaseTool
from pydantic import Field, BaseModel
import streamlit as st
class AnalyzeProjectRequirements(BaseTool):
project_name: str = Field(..., description="Name of the project")
project_description: str = Field(..., description="Project description and goals")
project_type: Literal["Web Application", "Mobile App", "API Development",
"Data Analytics", "AI/ML Solution", "Other"] = Field(...,
description="Type of project")
budget_range: Literal["$10k-$25k", "$25k-$50k", "$50k-$100k", "$100k+"] = Field(...,
description="Budget range for the project")
class ToolConfig:
name = "analyze_project"
description = "Analyzes project requirements and feasibility"
one_call_at_a_time = True
def run(self) -> str:
"""Analyzes project and stores results in shared state"""
if self._shared_state.get("project_analysis", None) is not None:
raise ValueError("Project analysis already exists. Please proceed with technical specification.")
analysis = {
"name": self.project_name,
"type": self.project_type,
"complexity": "high",
"timeline": "6 months",
"budget_feasibility": "within range",
"requirements": ["Scalable architecture", "Security", "API integration"]
}
self._shared_state.set("project_analysis", analysis)
return "Project analysis completed. Please proceed with technical specification."
class CreateTechnicalSpecification(BaseTool):
architecture_type: Literal["monolithic", "microservices", "serverless", "hybrid"] = Field(
...,
description="Proposed architecture type"
)
core_technologies: str = Field(
...,
description="Comma-separated list of main technologies and frameworks"
)
scalability_requirements: Literal["high", "medium", "low"] = Field(
...,
description="Scalability needs"
)
class ToolConfig:
name = "create_technical_spec"
description = "Creates technical specifications based on project analysis"
one_call_at_a_time = True
def run(self) -> str:
"""Creates technical specification based on analysis"""
project_analysis = self._shared_state.get("project_analysis", None)
if project_analysis is None:
raise ValueError("Please analyze project requirements first using AnalyzeProjectRequirements tool.")
spec = {
"project_name": project_analysis["name"],
"architecture": self.architecture_type,
"technologies": self.core_technologies.split(","),
"scalability": self.scalability_requirements
}
self._shared_state.set("technical_specification", spec)
return f"Technical specification created for {project_analysis['name']}."
def init_session_state() -> None:
"""Initialize session state variables"""
if 'messages' not in st.session_state:
st.session_state.messages = []
if 'api_key' not in st.session_state:
st.session_state.api_key = None
def main() -> None:
st.set_page_config(page_title="AI Services Agency", layout="wide")
init_session_state()
st.title("🚀 AI Services Agency")
# API Configuration
with st.sidebar:
st.header("🔑 API Configuration")
openai_api_key = st.text_input(
"OpenAI API Key",
type="password",
help="Enter your OpenAI API key to continue"
)
if openai_api_key:
st.session_state.api_key = openai_api_key
st.success("API Key accepted!")
else:
st.warning("⚠️ Please enter your OpenAI API Key to proceed")
st.markdown("[Get your API key here](https://platform.openai.com/api-keys)")
return
# Initialize agents with the provided API key
set_openai_key(st.session_state.api_key)
api_headers = {"Authorization": f"Bearer {st.session_state.api_key}"}
# Project Input Form
with st.form("project_form"):
st.subheader("Project Details")
project_name = st.text_input("Project Name")
project_description = st.text_area(
"Project Description",
help="Describe the project, its goals, and any specific requirements"
)
col1, col2 = st.columns(2)
with col1:
project_type = st.selectbox(
"Project Type",
["Web Application", "Mobile App", "API Development",
"Data Analytics", "AI/ML Solution", "Other"]
)
timeline = st.selectbox(
"Expected Timeline",
["1-2 months", "3-4 months", "5-6 months", "6+ months"]
)
with col2:
budget_range = st.selectbox(
"Budget Range",
["$10k-$25k", "$25k-$50k", "$50k-$100k", "$100k+"]
)
priority = st.selectbox(
"Project Priority",
["High", "Medium", "Low"]
)
tech_requirements = st.text_area(
"Technical Requirements (optional)",
help="Any specific technical requirements or preferences"
)
special_considerations = st.text_area(
"Special Considerations (optional)",
help="Any additional information or special requirements"
)
submitted = st.form_submit_button("Analyze Project")
if submitted and project_name and project_description:
try:
# Set OpenAI key
set_openai_key(st.session_state.api_key)
# Create agents
ceo = Agent(
name="Project Director",
description="You are a CEO of multiple companies in the past and have a lot of experience in evaluating projects and making strategic decisions.",
instructions="""
You are an experienced CEO who evaluates projects. Follow these steps strictly:
1. FIRST, use the AnalyzeProjectRequirements tool with:
- project_name: The name from the project details
- project_description: The full project description
- project_type: The type of project (Web Application, Mobile App, etc)
- budget_range: The specified budget range
2. WAIT for the analysis to complete before proceeding.
3. Review the analysis results and provide strategic recommendations.
""",
tools=[AnalyzeProjectRequirements],
api_headers=api_headers,
temperature=0.7,
max_prompt_tokens=25000
)
cto = Agent(
name="Technical Architect",
description="Senior technical architect with deep expertise in system design.",
instructions="""
You are a technical architect. Follow these steps strictly:
1. WAIT for the project analysis to be completed by the CEO.
2. Use the CreateTechnicalSpecification tool with:
- architecture_type: Choose from monolithic/microservices/serverless/hybrid
- core_technologies: List main technologies as comma-separated values
- scalability_requirements: Choose high/medium/low based on project needs
3. Review the technical specification and provide additional recommendations.
""",
tools=[CreateTechnicalSpecification],
api_headers=api_headers,
temperature=0.5,
max_prompt_tokens=25000
)
product_manager = Agent(
name="Product Manager",
description="Experienced product manager focused on delivery excellence.",
instructions="""
- Manage project scope and timeline giving the roadmap of the project
- Define product requirements and you should give potential products and features that can be built for the startup
""",
api_headers=api_headers,
temperature=0.4,
max_prompt_tokens=25000
)
developer = Agent(
name="Lead Developer",
description="Senior developer with full-stack expertise.",
instructions="""
- Plan technical implementation
- Provide effort estimates
- Review technical feasibility
""",
api_headers=api_headers,
temperature=0.3,
max_prompt_tokens=25000
)
client_manager = Agent(
name="Client Success Manager",
description="Experienced client manager focused on project delivery.",
instructions="""
- Ensure client satisfaction
- Manage expectations
- Handle feedback
""",
api_headers=api_headers,
temperature=0.6,
max_prompt_tokens=25000
)
# Create agency
agency = Agency(
[
ceo, cto, product_manager, developer, client_manager,
[ceo, cto],
[ceo, product_manager],
[ceo, developer],
[ceo, client_manager],
[cto, developer],
[product_manager, developer],
[product_manager, client_manager]
],
async_mode='threading',
shared_files='shared_files'
)
# Prepare project info
project_info = {
"name": project_name,
"description": project_description,
"type": project_type,
"timeline": timeline,
"budget": budget_range,
"priority": priority,
"technical_requirements": tech_requirements,
"special_considerations": special_considerations
}
st.session_state.messages.append({"role": "user", "content": str(project_info)})
# Create tabs and run analysis
with st.spinner("AI Services Agency is analyzing your project..."):
try:
# Get analysis from each agent using agency.get_completion()
ceo_response = agency.get_completion(
message=f"""Analyze this project using the AnalyzeProjectRequirements tool:
Project Name: {project_name}
Project Description: {project_description}
Project Type: {project_type}
Budget Range: {budget_range}
Use these exact values with the tool and wait for the analysis results.""",
recipient_agent=ceo
)
cto_response = agency.get_completion(
message=f"""Review the project analysis and create technical specifications using the CreateTechnicalSpecification tool.
Choose the most appropriate:
- architecture_type (monolithic/microservices/serverless/hybrid)
- core_technologies (comma-separated list)
- scalability_requirements (high/medium/low)
Base your choices on the project requirements and analysis.""",
recipient_agent=cto
)
pm_response = agency.get_completion(
message=f"Analyze project management aspects: {str(project_info)}",
recipient_agent=product_manager,
additional_instructions="Focus on product-market fit and roadmap development, and coordinate with technical and marketing teams."
)
developer_response = agency.get_completion(
message=f"Analyze technical implementation based on CTO's specifications: {str(project_info)}",
recipient_agent=developer,
additional_instructions="Provide technical implementation details, optimal tech stack you would be using including the costs of cloud services (if any) and feasibility feedback, and coordinate with product manager and CTO to build the required products for the startup."
)
client_response = agency.get_completion(
message=f"Analyze client success aspects: {str(project_info)}",
recipient_agent=client_manager,
additional_instructions="Provide detailed go-to-market strategy and customer acquisition plan, and coordinate with product manager."
)
# Create tabs for different analyses
tabs = st.tabs([
"CEO's Project Analysis",
"CTO's Technical Specification",
"Product Manager's Plan",
"Developer's Implementation",
"Client Success Strategy"
])
with tabs[0]:
st.markdown("## CEO's Strategic Analysis")
st.markdown(ceo_response)
st.session_state.messages.append({"role": "assistant", "content": ceo_response})
with tabs[1]:
st.markdown("## CTO's Technical Specification")
st.markdown(cto_response)
st.session_state.messages.append({"role": "assistant", "content": cto_response})
with tabs[2]:
st.markdown("## Product Manager's Plan")
st.markdown(pm_response)
st.session_state.messages.append({"role": "assistant", "content": pm_response})
with tabs[3]:
st.markdown("## Lead Developer's Development Plan")
st.markdown(developer_response)
st.session_state.messages.append({"role": "assistant", "content": developer_response})
with tabs[4]:
st.markdown("## Client Success Strategy")
st.markdown(client_response)
st.session_state.messages.append({"role": "assistant", "content": client_response})
except Exception as e:
st.error(f"Error during analysis: {str(e)}")
st.error("Please check your inputs and API key and try again.")
except Exception as e:
st.error(f"Error during analysis: {str(e)}")
st.error("Please check your API key and try again.")
# Add history management in sidebar
with st.sidebar:
st.subheader("Options")
if st.checkbox("Show Analysis History"):
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
if st.button("Clear History"):
st.session_state.messages = []
st.rerun()
if __name__ == "__main__":
main()

View file

@ -0,0 +1,3 @@
python-dotenv==1.0.1
agency-swarm==0.4.1
streamlit

View file

@ -0,0 +1,42 @@
## 📈 AI Startup Trend Analysis Agent
The AI Startup Trend Analysis Agent is tool for budding entrepreneurs that generates actionable insights by identifying nascent trends, potential market gaps, and growth opportunities in specific sectors. Entrepreneurs can use these data-driven insights to validate ideas, spot market opportunities, and make informed decisions about their startup ventures. It combines Newspaper4k and DuckDuckGo to scan and analyze startup-focused articles and market data. Using Claude 3.5 Sonnet, it processes this information to extract emerging patterns and enable entrepreneurs to identify promising startup opportunities.
### Features
- **User Prompt**: Entrepreneurs can input specific startup sectors or technologies of interest for research.
- **News Collection**: This agent gathers recent startup news, funding rounds, and market analyses using DuckDuckGo.
- **Summary Generation**: Concise summaries of verified information are generated using Newspaper4k.
- **Trend Analysis**: The system identifies emerging patterns in startup funding, technology adoption, and market opportunities across analyzed stories.
- **Streamlit UI**: The application features a user-friendly interface built with Streamlit for easy interaction.
### How to Get Started
1. **Clone the repository**:
```bash
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
cd awesome-llm-apps/ai_agent_tutorials/ai_startup_trend_analysis_agent
```
2. **Create and activate a virtual environment**:
```bash
# For macOS/Linux
python -m venv venv
source venv/bin/activate
# For Windows
python -m venv venv
.\venv\Scripts\activate
```
3. **Install the required packages**:
```bash
pip install -r requirements.txt
```
4. **Run the application**:
```bash
streamlit run startup_trends_agent.py
```
### Important Note
- The system specifically uses Claude's API for advanced language processing. You can obtain your Anthropic API key from [Anthropic's website](https://www.anthropic.com/api).

Some files were not shown because too many files have changed in this diff Show more