added logging and some smooooooth animations

This commit is contained in:
tcsenpai 2024-09-17 12:35:52 +02:00
parent 993d1267f0
commit 5275985873
7 changed files with 121 additions and 16 deletions

3
.gitignore vendored
View File

@ -8,6 +8,9 @@ env/
venv/ venv/
ENV/ ENV/
# Logs
logs/
# Streamlit # Streamlit
.streamlit/ .streamlit/

View File

@ -4,15 +4,18 @@
## Features ## Features
- [x] Using Llama-3.1 70b on Groq to create o1-like reasoning chains
- [x] Using Ollama to create o1-like reasoning chains
- [x] Using Perplexity to create o1-like reasoning chains
- [x] Using an unified interface to try out different providers - [x] Using an unified interface to try out different providers
- [x] Configuring the app from the sidebar
## Providers
- [x] Ollama (local)
- [x] Perplexity (remote, requires API key)
- [x] Groq (remote, requires API key)
## Work in progress ## Work in progress
- [ ] Add more providers - [ ] Add more providers
- [ ] Use something like LiteLLM to unify models code and avoid repeating code for each provider
## Example ## Example
@ -61,12 +64,12 @@ To use the launcher, follow these instructions:
cp example.env .env cp example.env .env
``` ```
3. Edit the .env file with your API keys / models preferences. 3. Edit the .env file with your API keys / models preferences (or do it from the app's configuration menu)
4. Run the main interface 4. Run the main interface
``` ```
streamlit run main.py streamlit run app/main.py
``` ```
--- ---

Binary file not shown.

27
app/logger.py Normal file
View File

@ -0,0 +1,27 @@
import logging
import os
from datetime import datetime
def setup_logger():
# Create a logs directory if it doesn't exist
log_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'logs')
os.makedirs(log_dir, exist_ok=True)
# Create a unique log file name based on the current timestamp
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
log_file = os.path.join(log_dir, f"multi1_{timestamp}.log")
# Configure the logger
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler(log_file),
logging.StreamHandler() # This will also print logs to console
]
)
return logging.getLogger('multi1')
# Create a global logger instance
logger = setup_logger()

View File

@ -3,6 +3,7 @@ from dotenv import load_dotenv
from api_handlers import OllamaHandler, PerplexityHandler, GroqHandler from api_handlers import OllamaHandler, PerplexityHandler, GroqHandler
from utils import generate_response from utils import generate_response
from config_menu import config_menu, display_config from config_menu import config_menu, display_config
from logger import logger
import os import os
# Load environment variables # Load environment variables
@ -36,6 +37,7 @@ def get_api_handler(backend, config):
return GroqHandler(config['GROQ_API_KEY'], config['GROQ_MODEL']) return GroqHandler(config['GROQ_API_KEY'], config['GROQ_MODEL'])
def main(): def main():
logger.info("Starting the application")
setup_page() setup_page()
st.sidebar.markdown('<h3 class="sidebar-title">⚙️ Settings</h3>', unsafe_allow_html=True) st.sidebar.markdown('<h3 class="sidebar-title">⚙️ Settings</h3>', unsafe_allow_html=True)
@ -44,26 +46,35 @@ def main():
backend = st.sidebar.selectbox("Choose AI Backend", ["Ollama", "Perplexity AI", "Groq"]) backend = st.sidebar.selectbox("Choose AI Backend", ["Ollama", "Perplexity AI", "Groq"])
display_config(backend, config) display_config(backend, config)
api_handler = get_api_handler(backend, config) api_handler = get_api_handler(backend, config)
logger.info(f"Selected backend: {backend}")
user_query = st.text_input("💬 Enter your query:", placeholder="e.g., How many 'R's are in the word strawberry?") user_query = st.text_input("💬 Enter your query:", placeholder="e.g., How many 'R's are in the word strawberry?")
if user_query: if user_query:
logger.info(f"Received user query: {user_query}")
st.write("🔍 Generating response...") st.write("🔍 Generating response...")
response_container = st.empty() response_container = st.empty()
time_container = st.empty() time_container = st.empty()
try:
for steps, total_thinking_time in generate_response(user_query, api_handler): for steps, total_thinking_time in generate_response(user_query, api_handler):
with response_container.container(): with response_container.container():
for title, content, _ in steps: for title, content, _ in steps:
if title.startswith("Final Answer"): if title.startswith("Final Answer"):
st.markdown(f'<h3 class="expander-title">🎯 {title}</h3>', unsafe_allow_html=True) st.markdown(f'<h3 class="expander-title">🎯 {title}</h3>', unsafe_allow_html=True)
st.markdown(f'<div>{content}</div>', unsafe_allow_html=True) st.markdown(f'<div>{content}</div>', unsafe_allow_html=True)
logger.info(f"Final answer generated: {content}")
else: else:
with st.expander(f"📝 {title}", expanded=True): with st.expander(f"📝 {title}", expanded=True):
st.markdown(f'<div>{content}</div>', unsafe_allow_html=True) st.markdown(f'<div>{content}</div>', unsafe_allow_html=True)
logger.debug(f"Step completed: {title}")
if total_thinking_time is not None: if total_thinking_time is not None:
time_container.markdown(f'<p class="thinking-time">⏱️ Total thinking time: {total_thinking_time:.2f} seconds</p>', unsafe_allow_html=True) time_container.markdown(f'<p class="thinking-time">⏱️ Total thinking time: {total_thinking_time:.2f} seconds</p>', unsafe_allow_html=True)
logger.info(f"Total thinking time: {total_thinking_time:.2f} seconds")
except Exception as e:
logger.error(f"Error generating response: {str(e)}", exc_info=True)
st.error("An error occurred while generating the response. Please try again.")
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -27,3 +27,64 @@ h1, h2, h3, h4, h5, h6 {
font-family: -apple-system, BlinkMacSystemFont, sans-serif; font-family: -apple-system, BlinkMacSystemFont, sans-serif;
font-weight: bold; font-weight: bold;
} }
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideIn {
from { transform: translateY(20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
/* Apply fade-in animation to main content */
.main .block-container {
animation: fadeIn 0.5s ease-out;
}
/* Apply slide-in animation to expanders */
.streamlit-expanderHeader {
animation: slideIn 0.3s ease-out;
transition: background-color 0.3s ease;
}
/* Smooth transition for expander content */
.streamlit-expanderContent {
transition: max-height 0.3s ease-out, opacity 0.3s ease-out;
}
/* Pulse animation for thinking time */
.thinking-time {
animation: pulse 2s infinite;
}
/* Hover effect for buttons */
.stButton > button {
transition: all 0.3s ease;
}
.stButton > button:hover {
transform: translateY(-2px);
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
/* Smooth transition for selectbox */
.stSelectbox {
transition: all 0.3s ease;
}
/* Subtle hover effect for text input */
.stTextInput > div > div > input {
transition: all 0.3s ease;
}
.stTextInput > div > div > input:hover {
box-shadow: 0 0 0 1px rgba(49, 51, 63, 0.2);
}