nmcamacho commited on
Commit
7e0e6b2
·
verified ·
1 Parent(s): d250466
Files changed (1) hide show
  1. app.py +94 -0
app.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import numpy as np
4
+ import faiss
5
+ from openai import OpenAI
6
+
7
+ client = OpenAI()
8
+
9
+ def row_to_text(row):
10
+ return (
11
+ f"Clinic: {row['Account_Name']}\n"
12
+ f"Region: {row['Region']}\n"
13
+ f"Account Manager: {row['Account_Manager']}\n"
14
+ f"Revenue: €{row['Revenue']}\n"
15
+ f"Last Purchase: {row['Last_Purchase_Date']}\n"
16
+ f"Churn Risk: {row['Churn_Risk']}\n"
17
+ f"Satisfaction Score: {row['Satisfaction_Score']}/10\n"
18
+ f"Product Interest: {row['Product_Interest']}\n"
19
+ f"Notes: {row['Account_Notes']}"
20
+ )
21
+
22
+ def get_embedding(text):
23
+ response = client.embeddings.create(
24
+ input=[text],
25
+ model="text-embedding-3-small"
26
+ )
27
+ return response.data[0].embedding
28
+
29
+ def contextual_pitch_assistant(csv_file, query):
30
+ df = pd.read_csv(csv_file.name)
31
+ text_chunks = df.apply(row_to_text, axis=1).tolist()
32
+ embeddings = [get_embedding(t) for t in text_chunks]
33
+
34
+ dim = len(embeddings[0])
35
+ index = faiss.IndexFlatL2(dim)
36
+ index.add(np.array(embeddings).astype('float32'))
37
+
38
+ q_emb = np.array([get_embedding(query)]).astype('float32')
39
+ D, I = index.search(q_emb, 3)
40
+ retrieved = [text_chunks[i] for i in I[0]]
41
+
42
+ prompt = f"""
43
+ You are an expert in B2B sales and digital pitching for dental clinics.
44
+ Based on the following CRM insights and query, generate:
45
+ 1) A short HTML email pitch (subject + body) ready to send.
46
+ 2) A DALL·E 3 prompt for a matching header image.
47
+
48
+ Query:
49
+ {query}
50
+
51
+ CRM data:
52
+ {'---'.join(retrieved)}
53
+ """
54
+
55
+ response = client.chat.completions.create(
56
+ model="gpt-4o-mini",
57
+ messages=[{"role": "user", "content": prompt}],
58
+ temperature=0.7
59
+ )
60
+
61
+ output_text = response.choices[0].message.content
62
+
63
+ import re
64
+ match = re.search(r"(Image prompt|DALL·E prompt)[:\-]\s*(.*)", output_text)
65
+ image_prompt = match.group(2).strip() if match else "modern dental clinic interior with dentist and patient"
66
+
67
+ image = client.images.generate(
68
+ model="gpt-image-1",
69
+ prompt=image_prompt,
70
+ size="1024x1024"
71
+ )
72
+ image_url = image.data[0].url
73
+
74
+ html = f"""
75
+ <div style='font-family:Arial,sans-serif;max-width:600px;margin:auto;padding:16px;background:#ffffff;
76
+ border-radius:12px;box-shadow:0 2px 8px rgba(0,0,0,0.1);'>
77
+ <img src="{image_url}" style="width:100%;border-radius:8px;margin-bottom:16px;">
78
+ {output_text}
79
+ </div>
80
+ """
81
+ return html
82
+
83
+ app = gr.Interface(
84
+ fn=contextual_pitch_assistant,
85
+ inputs=[
86
+ gr.File(label="Upload CRM CSV (5–100 rows)", file_types=[".csv"]),
87
+ gr.Textbox(label="Sales Query", placeholder="e.g. Which clinic is best for our imaging subscription?")
88
+ ],
89
+ outputs=gr.HTML(label="Email Pitch Preview"),
90
+ title="Contextual Pitch Assistant for Dental Sales",
91
+ description="Upload CRM data and get a personalized contextual pitch with generated imagery."
92
+ )
93
+
94
+ app.launch()