import gradio as gr from sentence_transformers import SentenceTransformer, util import transformers from transformers import pipeline import webbrowser import openai import os os.environ["TOKENIZERS_PARALLELISM"] = "false" # Initialize paths and model identifiers for easy configuration and maintenance filename = "output_composting_details.txt" # Path to the file storing chess-specific details retrieval_model_name = 'output/sentence-transformer-finetuned/' openai.api_key = os.environ["OPENAI_API_KEY"] # Attempt to load the necessary models and provide feedback on success or failure try: retrieval_model = SentenceTransformer(retrieval_model_name) print("Models loaded successfully.") except Exception as e: print(f"Failed to load models: {e}") def load_and_preprocess_text(filename): """ Load and preprocess text from a file, removing empty lines and stripping whitespace. """ try: with open(filename, 'r', encoding='utf-8') as file: segments = [line.strip() for line in file if line.strip()] print("Text loaded and preprocessed successfully.") return segments except Exception as e: print(f"Failed to load or preprocess text: {e}") return [] segments = load_and_preprocess_text(filename) def find_relevant_segment(user_query, segments): """ Find the most relevant text segment for a user's query using cosine similarity among sentence embeddings. This version finds the best match based on the content of the query. """ try: # Lowercase the query for better matching lower_query = user_query.lower() # Encode the query and the segments query_embedding = retrieval_model.encode(lower_query) segment_embeddings = retrieval_model.encode(segments) # Compute cosine similarities between the query and the segments similarities = util.pytorch_cos_sim(query_embedding, segment_embeddings)[0] # Find the index of the most similar segment best_idx = similarities.argmax() # Return the most relevant segment return segments[best_idx] except Exception as e: print(f"Error in finding relevant segment: {e}") return "" def generate_response(user_query, relevant_segment): """ Generate a response emphasizing the bot's capability to provide information related to composting food. """ try: system_message = "You are a chatbot specialized in providing information about food composting tips, tricks, and basics." user_message = f"Here's the information on composting: {relevant_segment}" messages = [ {"role": "system", "content": system_message}, {"role": "user", "content": user_message} ] response = openai.ChatCompletion.create( model="gpt-4o", messages=messages, max_tokens=200, temperature=0.5, top_p=1, frequency_penalty=0.5, presence_penalty=0.5 ) return response['choices'][0]['message']['content'].strip() except Exception as e: print(f"Error in generating response: {e}") return f"Error in generating response: {e}" def query_model(question): """ Process a question, find relevant information, and generate a response. """ if question == "": return "Welcome to CompBot! Ask me anything about composting tips, tricks, and basics!" relevant_segment = find_relevant_segment(question, segments) if not relevant_segment: return "Could not find specific information. Please refine your question." response = generate_response(question, relevant_segment) return response # Define the welcome message and specific topics the chatbot can provide information about welcome_message = """ <span style="color:#836953; font-size:24px; font-family:Roboto;">🌱Welcome to CompBot!</span> """""" ## Your AI-driven assistant for all composting-related queries. """ topics = """ ### Feel free to ask me anything from the topics below! - Components of composting - Green and brown materials - The composting process - Common strategies - Uses of compost - Tips for successful composting - Sustainability """ # Define the HTML iframe content podcast_iframe = ''' <div style="height:10px;"></div> <iframe style="border-radius:12px" src="https://open.spotify.com/embed/episode/1Emjgqf8PfwD42kvyKvtfW?utm_source=generator&theme=0" width="100%" height="152" frameBorder="0" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe> <div style="height:20px;"></div> <iframe style="border-radius:12px" src="https://open.spotify.com/embed/episode/6m83iwiAwCOu5yaW8LOT1v?utm_source=generator&theme=0" width="100%" height="152" frameBorder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe> ''' youtube_iframe = ''' <iframe width="560" height="315" src="https://www.youtube.com/embed/MryNKPPvFbk" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> ''' def display_image(): return "https://huggingface.co/spaces/dogutcu/composting-how-tos/resolve/main/compbot.jpeg" custom_css = """ <style> .textbox-question { background-color: #E8F0FE !important; /* Light blue background */ } .textbox-answer { background-color: #F1F8E9 !important; /* Light green background */ } </style> """ theme = gr.themes.Base().set( background_fill_primary='#AFC9AD', # Light cyan background background_fill_primary_dark='#AFC9AD', # Dark teal background background_fill_secondary='#ffccbc', # Light orange background background_fill_secondary_dark='#d84315', # Dark orange background border_color_accent='#ffab40', # Accent border color border_color_accent_dark='#ff6d00', # Dark accent border color border_color_accent_subdued='#ff8a65', # Subdued accent border color border_color_primary='#2a2a2a', # Primary border color block_border_color='#2a2a2a', # Block border color button_primary_background_fill='#2a2a2a', # Primary button background color button_primary_background_fill_dark='#2a2a2a' # Dark primary button background color ) # Setup the Gradio Blocks interface with custom layout components with gr.Blocks(theme=theme) as demo: gr.HTML(custom_css) gr.Image(display_image(), show_label = False, show_share_button = False, show_download_button = False, width=300, height=200) gr.Markdown(welcome_message) # Display the formatted welcome message with gr.Row(): with gr.Column(): gr.Markdown(topics) # Show the topics on the left side gr.HTML(youtube_iframe) # Embed the iframe on the left side with gr.Row(): with gr.Column(): question = gr.Textbox(label="Your question", placeholder="What would you like to know?") answer = gr.Textbox(label="CompBot Response", placeholder="CompBot will respond here...", interactive=False, lines=16) submit_button = gr.Button("Submit") submit_button.click(fn=query_model, inputs=question, outputs=answer) # Launch the Gradio app to allow user interaction demo.launch(share=True)