|
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 |
|
|
|
|
|
st.set_page_config(page_title="ProductProse - AI Product Description Generator", layout="wide") |
|
|
|
|
|
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 = [] |
|
|
|
|
|
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") |
|
|
|
|
|
target_language = st.selectbox("Target Language for Translation", ["French", "Spanish", "German", "Chinese", "Japanese"]) |
|
|
|
|
|
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. |
|
""") |
|
|
|
|
|
def section_header(title, color): |
|
st.markdown(f'<h2 style="color:{color};">{title}</h2>', unsafe_allow_html=True) |
|
|
|
|
|
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_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._") |
|
|
|
|
|
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._") |
|
|
|
|
|
section_header("Step 1: Generate Product Description", "blue") |
|
if st.button("Generate Description"): |
|
if product_name and features and benefits and specifications: |
|
|
|
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 |
|
st.session_state.customized_description = None |
|
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.") |
|
|
|
|
|
section_header("Step 2: Translate Product Description", "green") |
|
if st.session_state.generated_description: |
|
if st.button("Translate Description"): |
|
try: |
|
|
|
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}") |
|
|
|
|
|
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) |
|
|
|
|
|
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: |
|
|
|
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}") |
|
|
|
|
|
if st.session_state.customized_description: |
|
st.subheader("Customized Product Description") |
|
st.write(st.session_state.customized_description) |
|
|
|
|
|
if st.session_state.translated_description: |
|
if st.button("Translate Customized Description"): |
|
try: |
|
|
|
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}") |
|
|
|
|
|
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) |
|
|
|
|
|
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"): |
|
|
|
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!") |
|
|
|
|
|
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.") |