Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
|
@@ -8,6 +8,26 @@ from langchain_community.tools import DuckDuckGoSearchRun
|
|
| 8 |
from langchain_openai import OpenAI
|
| 9 |
from typing import Optional, Type
|
| 10 |
from pydantic import Field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
class SearchTool(BaseTool):
|
| 13 |
name: str = "Search"
|
|
@@ -17,146 +37,142 @@ class SearchTool(BaseTool):
|
|
| 17 |
|
| 18 |
def _run(self, query: str) -> str:
|
| 19 |
"""Execute the search tool"""
|
| 20 |
-
|
|
|
|
|
|
|
|
|
|
| 21 |
|
| 22 |
def _arun(self, query: str) -> str:
|
| 23 |
"""Async implementation"""
|
| 24 |
raise NotImplementedError("Async not implemented")
|
| 25 |
|
| 26 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
|
| 28 |
-
def
|
| 29 |
-
"""
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
os.environ['OPENAI_API_KEY'] = st.secrets['OPENAI_API_KEY']
|
| 33 |
-
return True
|
| 34 |
-
else:
|
| 35 |
-
st.error("OpenAI API key not found in secrets!")
|
| 36 |
-
return False
|
| 37 |
-
except Exception as e:
|
| 38 |
-
st.error(f"Error setting up API keys: {str(e)}")
|
| 39 |
-
return False
|
| 40 |
|
| 41 |
-
def
|
| 42 |
-
"""
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
goal='Select meaningful spiritual quotes and validate their authenticity',
|
| 52 |
-
backstory="""You are an expert in world philosophies and spiritual traditions.""",
|
| 53 |
-
tools=[search_tool],
|
| 54 |
-
llm=llm,
|
| 55 |
-
verbose=True
|
| 56 |
-
)
|
| 57 |
-
|
| 58 |
-
content_creator = Agent(
|
| 59 |
-
role='Content Creator',
|
| 60 |
-
goal='Create engaging visual descriptions for spiritual quotes',
|
| 61 |
-
backstory="""You are a creative content specialist.""",
|
| 62 |
-
tools=[search_tool],
|
| 63 |
-
llm=llm,
|
| 64 |
-
verbose=True
|
| 65 |
-
)
|
| 66 |
-
|
| 67 |
-
content_validator = Agent(
|
| 68 |
-
role='Content Validator',
|
| 69 |
-
goal='Ensure content aligns with spiritual traditions',
|
| 70 |
-
backstory="""You are an expert in multiple spiritual traditions.""",
|
| 71 |
-
tools=[search_tool],
|
| 72 |
-
llm=llm,
|
| 73 |
-
verbose=True
|
| 74 |
-
)
|
| 75 |
-
|
| 76 |
-
return quote_curator, content_creator, content_validator
|
| 77 |
|
| 78 |
def main():
|
| 79 |
-
st.set_page_config(
|
| 80 |
-
page_title="Spiritual Content Generator",
|
| 81 |
-
page_icon="🕉️",
|
| 82 |
-
layout="wide"
|
| 83 |
-
)
|
| 84 |
-
|
| 85 |
-
# Setup API keys at startup
|
| 86 |
-
if not setup_api_keys():
|
| 87 |
-
st.warning("""
|
| 88 |
-
Please set up the OpenAI API key in your Hugging Face Space:
|
| 89 |
-
1. Go to your Space Settings
|
| 90 |
-
2. Click on 'Secrets'
|
| 91 |
-
3. Add OPENAI_API_KEY
|
| 92 |
-
""")
|
| 93 |
-
st.stop()
|
| 94 |
|
| 95 |
-
# Initialize session state
|
| 96 |
-
if '
|
| 97 |
-
st.session_state.
|
| 98 |
-
if 'generation_history' not in st.session_state:
|
| 99 |
-
st.session_state.generation_history = []
|
| 100 |
|
| 101 |
-
#
|
| 102 |
-
st.
|
| 103 |
-
st.markdown("""
|
| 104 |
-
Generate inspiring spiritual content combining quotes and insights from various philosophical traditions.
|
| 105 |
-
""")
|
| 106 |
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
try:
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 144 |
except Exception as e:
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
|
|
|
|
|
|
|
|
|
| 149 |
|
| 150 |
-
with
|
| 151 |
-
st.header("
|
| 152 |
-
|
| 153 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
|
| 155 |
-
with
|
| 156 |
-
st.header("
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
|
| 161 |
if __name__ == "__main__":
|
| 162 |
main()
|
|
|
|
| 8 |
from langchain_openai import OpenAI
|
| 9 |
from typing import Optional, Type
|
| 10 |
from pydantic import Field
|
| 11 |
+
import logging
|
| 12 |
+
import sys
|
| 13 |
+
|
| 14 |
+
# Set up logging
|
| 15 |
+
logging.basicConfig(level=logging.INFO)
|
| 16 |
+
logger = logging.getLogger(__name__)
|
| 17 |
+
|
| 18 |
+
# Custom StreamHandler to capture logs for Streamlit
|
| 19 |
+
class StreamlitHandler(logging.StreamHandler):
|
| 20 |
+
def __init__(self):
|
| 21 |
+
logging.StreamHandler.__init__(self)
|
| 22 |
+
self.logs = []
|
| 23 |
+
|
| 24 |
+
def emit(self, record):
|
| 25 |
+
msg = self.format(record)
|
| 26 |
+
self.logs.append(msg)
|
| 27 |
+
|
| 28 |
+
# Initialize the custom handler
|
| 29 |
+
streamlit_handler = StreamlitHandler()
|
| 30 |
+
logger.addHandler(streamlit_handler)
|
| 31 |
|
| 32 |
class SearchTool(BaseTool):
|
| 33 |
name: str = "Search"
|
|
|
|
| 37 |
|
| 38 |
def _run(self, query: str) -> str:
|
| 39 |
"""Execute the search tool"""
|
| 40 |
+
logger.info(f"Searching for: {query}")
|
| 41 |
+
result = self.search.run(query)
|
| 42 |
+
logger.info(f"Search completed. Result length: {len(result)}")
|
| 43 |
+
return result
|
| 44 |
|
| 45 |
def _arun(self, query: str) -> str:
|
| 46 |
"""Async implementation"""
|
| 47 |
raise NotImplementedError("Async not implemented")
|
| 48 |
|
| 49 |
+
# Sample quotes database
|
| 50 |
+
SPIRITUAL_QUOTES = [
|
| 51 |
+
{
|
| 52 |
+
"text": "Be the change you wish to see in the world.",
|
| 53 |
+
"author": "Mahatma Gandhi",
|
| 54 |
+
"tradition": "Hinduism"
|
| 55 |
+
},
|
| 56 |
+
{
|
| 57 |
+
"text": "The journey of a thousand miles begins with one step.",
|
| 58 |
+
"author": "Lao Tzu",
|
| 59 |
+
"tradition": "Taoism"
|
| 60 |
+
}
|
| 61 |
+
]
|
| 62 |
|
| 63 |
+
def generate_image_prompt(quote, author, tradition):
|
| 64 |
+
"""Generate a detailed prompt for image creation"""
|
| 65 |
+
logger.info(f"Generating image prompt for quote by {author}")
|
| 66 |
+
return f"Create a serene, spiritual image that represents: '{quote}' - From {tradition} tradition. Style: Minimalistic, inspirational, Instagram-worthy."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
|
| 68 |
+
def select_background_music(tradition):
|
| 69 |
+
"""Select appropriate background music based on tradition"""
|
| 70 |
+
logger.info(f"Selecting music for {tradition} tradition")
|
| 71 |
+
music_mapping = {
|
| 72 |
+
"Hinduism": "indian_flute.mp3",
|
| 73 |
+
"Buddhism": "tibetan_bells.mp3",
|
| 74 |
+
"Taoism": "chinese_zither.mp3",
|
| 75 |
+
"default": "meditation_ambient.mp3"
|
| 76 |
+
}
|
| 77 |
+
return music_mapping.get(tradition, music_mapping["default"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
|
| 79 |
def main():
|
| 80 |
+
st.set_page_config(page_title="Spiritual Content Generator", layout="wide")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
|
| 82 |
+
# Initialize session state for logs
|
| 83 |
+
if 'logs' not in st.session_state:
|
| 84 |
+
st.session_state.logs = []
|
|
|
|
|
|
|
| 85 |
|
| 86 |
+
# Tabs
|
| 87 |
+
tab1, tab2, tab3 = st.tabs(["Content Generator", "Debug Logs", "Settings"])
|
|
|
|
|
|
|
|
|
|
| 88 |
|
| 89 |
+
with tab1:
|
| 90 |
+
st.title("🕉️ Spiritual Content Generator")
|
| 91 |
+
|
| 92 |
+
# Content Generation Area
|
| 93 |
+
col1, col2 = st.columns([2, 1])
|
| 94 |
+
|
| 95 |
+
with col1:
|
| 96 |
+
st.header("Generated Content")
|
| 97 |
+
if st.button("Generate New Content"):
|
| 98 |
+
with st.spinner("Generating content..."):
|
| 99 |
try:
|
| 100 |
+
# Log the start of generation
|
| 101 |
+
logger.info("Starting content generation process")
|
| 102 |
+
|
| 103 |
+
# 1. Select a quote
|
| 104 |
+
quote = SPIRITUAL_QUOTES[0] # For demo, using first quote
|
| 105 |
+
logger.info(f"Selected quote: {quote['text']}")
|
| 106 |
+
|
| 107 |
+
# 2. Generate image prompt
|
| 108 |
+
image_prompt = generate_image_prompt(
|
| 109 |
+
quote['text'],
|
| 110 |
+
quote['author'],
|
| 111 |
+
quote['tradition']
|
| 112 |
+
)
|
| 113 |
+
|
| 114 |
+
# 3. Select background music
|
| 115 |
+
music = select_background_music(quote['tradition'])
|
| 116 |
+
|
| 117 |
+
# 4. Combine everything
|
| 118 |
+
content_package = {
|
| 119 |
+
"quote": quote,
|
| 120 |
+
"image_prompt": image_prompt,
|
| 121 |
+
"background_music": music,
|
| 122 |
+
"generated_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
# Store in session state
|
| 126 |
+
st.session_state.current_content = content_package
|
| 127 |
+
logger.info("Content package generated successfully")
|
| 128 |
+
|
| 129 |
+
# Display the generated content
|
| 130 |
+
st.success("Content generated successfully!")
|
| 131 |
+
st.json(content_package)
|
| 132 |
+
|
| 133 |
except Exception as e:
|
| 134 |
+
logger.error(f"Error during generation: {str(e)}")
|
| 135 |
+
st.error(f"Error generating content: {str(e)}")
|
| 136 |
+
|
| 137 |
+
with col2:
|
| 138 |
+
st.header("Preview")
|
| 139 |
+
st.info("Image preview will appear here")
|
| 140 |
+
st.audio("sample_music.mp3", format='audio/mp3')
|
| 141 |
|
| 142 |
+
with tab2:
|
| 143 |
+
st.header("Debug Logs")
|
| 144 |
+
st.text("Recent activity logs:")
|
| 145 |
+
|
| 146 |
+
# Display logs
|
| 147 |
+
for log in streamlit_handler.logs:
|
| 148 |
+
if "ERROR" in log:
|
| 149 |
+
st.error(log)
|
| 150 |
+
elif "WARNING" in log:
|
| 151 |
+
st.warning(log)
|
| 152 |
+
else:
|
| 153 |
+
st.text(log)
|
| 154 |
+
|
| 155 |
+
if st.button("Clear Logs"):
|
| 156 |
+
streamlit_handler.logs = []
|
| 157 |
|
| 158 |
+
with tab3:
|
| 159 |
+
st.header("Settings")
|
| 160 |
+
st.subheader("API Configuration")
|
| 161 |
+
|
| 162 |
+
# API key status
|
| 163 |
+
if 'OPENAI_API_KEY' in st.secrets:
|
| 164 |
+
st.success("OpenAI API key is configured")
|
| 165 |
+
else:
|
| 166 |
+
st.error("OpenAI API key is missing")
|
| 167 |
+
|
| 168 |
+
# Image Generation settings
|
| 169 |
+
st.subheader("Image Generation")
|
| 170 |
+
st.selectbox("Image Style", ["Minimalistic", "Abstract", "Nature-inspired", "Sacred Geometry"])
|
| 171 |
+
|
| 172 |
+
# Music settings
|
| 173 |
+
st.subheader("Music Settings")
|
| 174 |
+
st.checkbox("Enable background music", value=True)
|
| 175 |
+
st.slider("Music Volume", 0, 100, 50)
|
| 176 |
|
| 177 |
if __name__ == "__main__":
|
| 178 |
main()
|