hormozi / app.py
laudes's picture
Upload app.py
e16ad81 verified
import os
import openai
import logging
import json
from dotenv import load_dotenv
import gradio as gr
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
from langsmith import traceable
from langsmith.wrappers import wrap_openai
# Initialize OpenAI client
client = wrap_openai(openai.Client())
# Load environment variables
load_dotenv()
# Load the OpenAI API key
openai.api_key = os.getenv("OPENAI_API_KEY")
if not openai.api_key:
raise ValueError("Error: OPENAI_API_KEY not found in environment variables")
openai.model = os.getenv("OPENAI_MODEL_NAME")
##############################################
# Function to calculate cost based on token usage
def ydcoza_cost(tokens_out):
t_cost = tokens_out * 6.2 / 1000000 # Rough Estimate For gpt-4o
return t_cost
##############################################
# Function to retrieve prompt from a local file
def get_prompts():
local_file_path = "custom_prompts/hormozi_prompt_vector_storage.md"
try:
with open(local_file_path, 'r') as file:
prompt = file.read()
except FileNotFoundError:
print(f"Prompt not found: {local_file_path}")
prompt = ""
except Exception as e:
print(f"An error occurred: {e}")
prompt = ""
return prompt
##############################################
# Load summary sections and generate embeddings
with open('summary_sections.json', 'r') as file:
summary_sections = json.load(file)
# Generate embeddings for each section using 'text-embedding-3-small' model
for section in summary_sections:
response = client.embeddings.create(
model="text-embedding-3-small",
input=section["content"]
)
section["embedding"] = response.data[0].embedding
# Store the embeddings for later use in similarity search
knowledge_base = summary_sections
##############################################
# Function to find the most similar entry in the knowledge base to a given query embedding
def find_most_similar(query_embedding, knowledge_base, top_k=1):
"""
Finds the most similar entries in the knowledge base to the query embedding.
Returns the top_k most similar entries.
"""
embeddings = [entry["embedding"] for entry in knowledge_base]
similarities = cosine_similarity([query_embedding], embeddings)
most_similar_indices = np.argsort(similarities[0])[::-1][:top_k]
return [knowledge_base[idx] for idx in most_similar_indices]
##############################################
# Function to reformulate user input based on specific guidelines
def reformulate_input(user_input):
# Define the prompt that instructs the AI to refine the user's input
ydcoza_prompt_input = f"# IDENTITY and PURPOSE\nYou are a writing expert. You refine the input text to enhance clarity, coherence and structure\n\n# Steps\nYou are presented with a business idea if the idea is not well structured / formulated, improve on it\n\n# OUTPUT INSTRUCTIONS\n- Write a short description not exceeding 170 words or 1200 character. Make use of bulletpoints to highlight key information\n - NOTE: You are not to give ideas or suggestion just write an improved description of the proposed business idea.\n - Output in markdown format"
# Request the AI to generate the reformulated input
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": ydcoza_prompt_input},
{"role": "user", "content": user_input}
]
)
reformulated_input = response.choices[0].message.content
return f"### The Improved Description\n\n" + reformulated_input
##############################################
# Function to generate the final response based on the reformulated input
def generate_openai_response(reformulated):
logging.info("Generating response from OpenAI API for the prompt")
# Generate embedding for the reformulated query
query_response = client.embeddings.create(
model="text-embedding-3-small",
input=reformulated
)
query_embedding = query_response.data[0].embedding
# Find the most relevant content from the knowledge base
relevant_content = find_most_similar(query_embedding, knowledge_base, top_k=1)
relevant_text = relevant_content[0]['content']
# Combine the relevant content and reformulated input to create the final prompt
prompt = get_prompts()
full_prompt = f"""{prompt}\n\n#USER INPUT\n\n#RELEVANT INFORMATION\n{relevant_text}"""
# Generate the final output from OpenAI's model
messages = [
{"role": "system", "content": full_prompt},
{"role": "user", "content": reformulated}
]
try:
response = client.chat.completions.create(
model=openai.model,
messages=messages,
temperature=1,
top_p=1,
frequency_penalty=0,
presence_penalty=0
)
assistant_message = response.choices[0].message.content
tokens_used = response.usage.total_tokens
cost_per_call = ydcoza_cost(tokens_used)
# Return the assistant's message and the cost of the API call
return assistant_message, f"<p class='cost_per_call'>Tokens Consumed: {tokens_used} ; Cost per call: ${cost_per_call:.6f}</p>"
except Exception as e:
logging.error(f"Error generating OpenAI response: {e}")
return f"Error occurred: {str(e)}", ""
##############################################
# Gradio callback functions to handle the different stages of the process
# This function handles the reformulation of the user's input
def start_process(user_input):
reformulated = reformulate_input(user_input)
return reformulated, gr.update(visible=False), gr.update(visible=True), gr.update(visible=True)
# This function generates the final offer and handles the cost information
def continue_process(reformulated):
final_output, cost_message = generate_openai_response(reformulated)
return final_output, cost_message, gr.update(visible=True), gr.update(visible=True), gr.update(visible=False)
##############################################
# Function to load users from a file
def load_auth_users(file_path):
auth_users = []
try:
with open(file_path, 'r') as file:
lines = file.readlines()
for line in lines:
# Strip any extra spaces or newline characters
line = line.strip()
if line: # Skip empty lines
username, password = line.split(',')
auth_users.append((username.strip(), password.strip()))
except FileNotFoundError:
print(f"Error: File not found - {file_path}")
except Exception as e:
print(f"An error occurred while loading auth users: {e}")
return auth_users
# Path to your auth users file
auth_users_file = "auth_users.txt"
# Load the auth users
auth_users = load_auth_users(auth_users_file)
if not auth_users:
raise ValueError("No valid users found. Please check your auth_users.txt file.")
# print(f"An error occurred while loading auth users: {e}")
##############################################
# Gradio interface setup
with gr.Blocks(theme=gr.themes.Soft(font=[gr.themes.GoogleFont("Ubuntu"), "Arial", "sans-serif"],text_size='sm')) as ydcoza_face:
with gr.Row():
# Text input for user to describe their business idea
text_input = gr.Textbox(lines=5, label="Tell me about your business idea, what you have in mind etc.", placeholder="eg. I want to open an Ice cream factory in Santorini Greece ...")
# Pre Defined Inputs
with gr.Row():
examples = gr.Examples(examples=["I want to open an Ice Cream Factory in Piraeus Greece", "If I'm interested in clothing and sales, I might consider starting an online reseller business. Although it takes time, dedication, and an eye for fashion, I can start my business as a side hustle and eventually turn it into a full-time resale business. I could begin by using online store websites like Poshmark and Mercari to sell my unwanted clothing and items, then expand to my own resale website.", "The demand for online education has opened up possibilities for me as an entrepreneur. Since this is an online venture, I can choose any subject I know about and teach a course regardless of my location. If I don’t have advanced knowledge in any particular subject, I could consider teaching English as a foreign language online to students in China", "If I enjoy cleaning, I can easily turn that into a business. With a few staff members, a variety of cleaning supplies, and transportation, I can offer cleaning services to homeowners, apartment complexes, and commercial properties. Most cleaning services charge between $25 to $50 per hour. These services are straightforward businesses that require relatively little overhead; I simply need planning, dedication, and marketing to attract customers."],example_labels=["Short Idea","Clothing & Sales","Online Education","Cleaning Busines"], label="Demo Business Ideas",inputs=[text_input])
# Initial HTML block with instructions
with gr.Row():
big_block_01 = gr.HTML("""
<span class="ydcoza_improve_on_description">We now have a polished version of your description, we'll craft a compelling Hormozi Offer from it.</span>
""", visible=False)
# Button to start the process
with gr.Row():
start_button = gr.Button("Let's Start The Process", elem_id='ydcoza_gradio_button', interactive=False)
# Output for the improved business description
with gr.Row():
desc_output = gr.Markdown(label="Improved Description", elem_id='ydcoza_markdown_output_desc')
# HTML block for the final Hormozi offer message (initially hidden)
with gr.Row():
big_block_03 = gr.HTML("""
<span class="ydcoza_hormozi_offer_out">Awesome! Here's your Hormozi-Styled Offer. I hope it sparks some inspiration and wish you the best of luck with your venture!"</span>
""", visible=False)
# Output for the final generated response
with gr.Row():
markdown_output = gr.Markdown(label="Response", elem_id='ydcoza_markdown_output', visible=False)
# Output for the cost information (initially hidden)
with gr.Row():
html_output_cost = gr.HTML(elem_id='ydcoza_cost_output', visible=False)
# with gr.Row():
# logout_button = gr.Button("Logout", link="/logout", elem_id='ydcoza_gradio_button')
# Enable button when text is entered
def update_button_state(text):
if text.strip():
return gr.update(interactive=True)
else:
return gr.update(interactive=False)
text_input.change(fn=update_button_state, inputs=text_input, outputs=start_button)
# Setup button click to trigger the process
start_button.click(start_process, inputs=[text_input], outputs=[desc_output, start_button, markdown_output, big_block_01]).then(
continue_process, inputs=[desc_output], outputs=[markdown_output, html_output_cost, big_block_03, html_output_cost, start_button]
)
# Launch the Gradio interface
if __name__ == "__main__":
# ydcoza_face.launch(auth=auth_users, auth_message="Demo Login, Username: admin & Password: 1234")
ydcoza_face.launch()