import streamlit as st from ibm_watsonx_ai import APIClient from ibm_watsonx_ai import Credentials from ibm_watsonx_ai.foundation_models import ModelInference from ibm_watsonx_ai.foundation_models.utils.enums import ModelTypes, DecodingMethods from ibm_watsonx_ai.metanames import GenTextParamsMetaNames as GenParams import os # Set up page configuration st.set_page_config(page_title="ProductProse - AI Product Description Generator", layout="wide") # Initialize session state to track API responses, user feedback, and history if 'generated_description' not in st.session_state: st.session_state.generated_description = None if 'translated_description' not in st.session_state: st.session_state.translated_description = None if 'customized_description' not in st.session_state: st.session_state.customized_description = None if 'feedback_history' not in st.session_state: st.session_state.feedback_history = [] # Sidebar for product data input with st.sidebar: st.title("Product Data Input") product_name = st.text_input("Product Name", placeholder="e.g., Smart Home Hub") features = st.text_area("Product Features", placeholder="e.g., Voice Control, Energy Efficient, Compact Design") benefits = st.text_area("Product Benefits", placeholder="e.g., Saves time, Reduces energy usage, Easy to install") specifications = st.text_area("Product Specifications", placeholder="e.g., Dimensions: 10x5x3 inches, Weight: 1.5 lbs") # Select target language for translation target_language = st.selectbox("Target Language for Translation", ["French", "Spanish", "German", "Chinese", "Japanese"]) # Main app title and description st.markdown("# ProductProse - AI Product Description Generator") st.markdown(""" Welcome to ProductProse, an AI-powered tool for generating and customizing product descriptions using IBM Granite LLMs. Simply input your product data and let the AI do the rest, including generating descriptions, translating them into multiple languages, and customizing them to match your brand tone and style. """) # UI Enhancement: Color-coded sections for clarity def section_header(title, color): st.markdown(f'

{title}

', unsafe_allow_html=True) # IBM WatsonX API Setup project_id = os.getenv('WATSONX_PROJECT_ID') api_key = os.getenv('WATSONX_API_KEY') if api_key and project_id: credentials = Credentials(url="https://us-south.ml.cloud.ibm.com", api_key=api_key) client = APIClient(credentials) client.set.default_project(project_id) # Tone Selection for Description Customization tone_example = st.sidebar.selectbox("Tone Example (Modify as needed)", ["Formal", "Casual", "Professional", "Playful"]) st.sidebar.markdown("_Example: Choose a tone to match your brand's style._") # Keyword Input for SEO Optimization seo_keywords_example = st.sidebar.text_area("SEO Keywords (comma-separated)", placeholder="e.g., wireless, fast charging, Bluetooth") st.sidebar.markdown("_Example: Add keywords that enhance search engine optimization._") # Step 1: Generate Product Description section_header("Step 1: Generate Product Description", "blue") if st.button("Generate Description"): if product_name and features and benefits and specifications: # Prompt engineering for Granite-13B-Instruct prompt = f""" You are an AI that generates high-quality product descriptions. Based on the following details, generate a professional and engaging product description:\n Product Name: {product_name}\n Features: {features}\n Benefits: {benefits}\n Specifications: {specifications}\n Generate only the final product description text, without including any instruction or prompt context. """ try: model = ModelInference(model_id=ModelTypes.GRANITE_13B_INSTRUCT_V2, params={ GenParams.DECODING_METHOD: DecodingMethods.GREEDY, GenParams.MIN_NEW_TOKENS: 50, GenParams.MAX_NEW_TOKENS: 200, GenParams.STOP_SEQUENCES: ["\n"] }, credentials=credentials, project_id=project_id) with st.spinner("Generating product description..."): description_response = model.generate_text(prompt=prompt) st.session_state.generated_description = description_response st.session_state.translated_description = None # Clear previous translations st.session_state.customized_description = None # Clear previous customizations st.success("Product description generated!") st.write(description_response) except Exception as e: st.error(f"An error occurred while generating the description: {e}") else: st.warning("Please fill in all the product data fields before generating a description.") # Step 2: Translate Product Description section_header("Step 2: Translate Product Description", "green") if st.session_state.generated_description: if st.button("Translate Description"): try: # Translate the description using Granite-20B-Multilingual prompt = f"Translate the following product description into {target_language}:\n{st.session_state.generated_description}" model = ModelInference(model_id=ModelTypes.GRANITE_20B_MULTILINGUAL, params={ GenParams.DECODING_METHOD: DecodingMethods.GREEDY, GenParams.MIN_NEW_TOKENS: 50, GenParams.MAX_NEW_TOKENS: 200, GenParams.STOP_SEQUENCES: ["\n"] }, credentials=credentials, project_id=project_id) with st.spinner(f"Translating product description to {target_language}..."): translation_response = model.generate_text(prompt=prompt) st.session_state.translated_description = translation_response st.success(f"Product description translated to {target_language}!") st.write(translation_response) except Exception as e: st.error(f"An error occurred while translating the description: {e}") # Display previous results if st.session_state.generated_description: st.subheader("Generated Product Description") st.write(st.session_state.generated_description) if st.session_state.translated_description: st.subheader(f"Translated Product Description ({target_language})") st.write(st.session_state.translated_description) # Step 3: Customize Product Description via Chat Interface section_header("Step 3: Customize Product Description", "orange") customization_prompt = st.text_input("Customize the product description", placeholder="e.g., Make the tone more playful and mention our eco-friendly packaging") if st.session_state.generated_description and customization_prompt: if st.button("Customize Description"): try: # Customize the description using Granite-13B-Chat prompt = f"Customize the following product description with a {tone_example} tone, using the following SEO keywords: {seo_keywords_example}.\nProduct Description:\n{st.session_state.generated_description}\nCustomization Request: {customization_prompt}\nGenerate only the final customized product description." model = ModelInference(model_id=ModelTypes.GRANITE_13B_CHAT_V2, params={ GenParams.DECODING_METHOD: DecodingMethods.GREEDY, GenParams.MIN_NEW_TOKENS: 50, GenParams.MAX_NEW_TOKENS: 200, GenParams.STOP_SEQUENCES: ["\n"] }, credentials=credentials, project_id=project_id) with st.spinner("Customizing product description..."): customization_response = model.generate_text(prompt=prompt) st.session_state.customized_description = customization_response st.success("Product description customized!") st.write(customization_response) except Exception as e: st.error(f"An error occurred while customizing the description: {e}") # Display customized result if available if st.session_state.customized_description: st.subheader("Customized Product Description") st.write(st.session_state.customized_description) # Option to translate the customized description if it hasn't been translated yet if st.session_state.translated_description: if st.button("Translate Customized Description"): try: # Translate the customized description using Granite-20B-Multilingual prompt = f"Translate the following customized product description into {target_language}:\n{st.session_state.customized_description}" model = ModelInference(model_id=ModelTypes.GRANITE_20B_MULTILINGUAL, params={ GenParams.DECODING_METHOD: DecodingMethods.GREEDY, GenParams.MIN_NEW_TOKENS: 50, GenParams.MAX_NEW_TOKENS: 200, GenParams.STOP_SEQUENCES: ["\n"] }, credentials=credentials, project_id=project_id) with st.spinner(f"Translating customized product description to {target_language}..."): customized_translation_response = model.generate_text(prompt=prompt) st.session_state.translated_customized_description = customized_translation_response st.success(f"Customized product description translated to {target_language}!") st.write(customized_translation_response) except Exception as e: st.error(f"An error occurred while translating the customized description: {e}") # Display the translated customized description if available if 'translated_customized_description' in st.session_state: st.subheader(f"Translated Customized Product Description ({target_language})") st.write(st.session_state.translated_customized_description) # Step 4: Feedback and Quality Scoring section_header("Step 4: Provide Feedback", "purple") feedback_rating = st.slider("Rate the quality of the generated product description (1 = Poor, 5 = Excellent)", 1, 5, 3) feedback_comments = st.text_area("Additional Comments") if st.button("Submit Feedback"): # Save the feedback in session state feedback_entry = { "rating": feedback_rating, "comments": feedback_comments, "description": st.session_state.generated_description, "customized_description": st.session_state.customized_description if st.session_state.customized_description else "N/A", "translated_description": st.session_state.translated_description if st.session_state.translated_description else "N/A" } st.session_state.feedback_history.append(feedback_entry) st.success("Thank you for your feedback!") # Display the feedback summary st.subheader("Feedback Summary") for i, feedback in enumerate(st.session_state.feedback_history, 1): st.write(f"**Feedback {i}:**") st.write(f"Rating: {feedback['rating']}") st.write(f"Comments: {feedback['comments']}") st.write(f"Generated Description: {feedback['description']}") st.write(f"Customized Description: {feedback['customized_description']}") st.write(f"Translated Description: {feedback['translated_description']}") st.markdown("---") else: st.error("IBM WatsonX API credentials are not set. Please check your environment variables.")