Strongich commited on
Commit
49a0cfc
·
1 Parent(s): 9224663
app.py CHANGED
@@ -3,17 +3,17 @@ import gradio as gr
3
  from openai import OpenAI
4
  import os
5
  import dotenv
6
-
7
 
8
  dotenv.load_dotenv()
9
 
10
  client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
11
 
12
  script_dir = os.path.dirname(os.path.abspath(__file__))
13
-
14
  printer_1 = """
15
  # PrintPronto
16
- Product: Business card
17
 
18
  Color:
19
  - Black (default)
@@ -23,7 +23,7 @@ Color:
23
  - Pink
24
 
25
  Sizes:
26
- 3.5x2: multiplier 1.0
27
  2.5x2.5: multiplier 0.95
28
  2.125x3.375: multiplier 0.9
29
  Custom size: This vendor doesn't support custom sizes
@@ -36,24 +36,91 @@ Base Prices (Quantity,Price per Unit $):
36
  100, 0.23
37
  250, 0.2
38
  500, 0.19
39
- 1000, 0.175
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  """
41
 
42
  printer_2 = """
43
  # BannerLord
44
- Product: Business card
45
 
46
  Color:
47
  - Black (default)
48
  - Blue
49
 
50
  Sizes:
51
- 3.5x2: multiplier 1.0
52
  2.5x2.5: multiplier 0.95
53
  2.125x3.375: multiplier 0.9
54
  3x2: multiplier 1.5
55
  4x3: multiplier 1.5
56
- Custom size: multiplier 2.0
57
 
58
  Material:
59
  - Standard (default)
@@ -63,24 +130,92 @@ Base Prices (Quantity,Price per Unit $):
63
  100, 0.25
64
  250, 0.22
65
  500, 0.2
66
- 1000, 0.185
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  """
68
 
69
  printer_3 = """
70
  # PrintMaster
71
- Product: Business card
 
72
  Color:
73
  - Black (default)
74
  - Blue
75
  - Brown
76
 
77
  Sizes:
78
- 3.5x2: multiplier 1.0
79
  2.5x2.5: multiplier 0.95
80
  2.125x3.375: multiplier 0.9
81
  3x2: multiplier 1.5
82
  4x3: multiplier 1.5
83
- Custom size: multiplier 2.0
84
 
85
  Material:
86
  - Standard (default)
@@ -89,36 +224,178 @@ Material:
89
  Base Prices (Quantity,Price per Unit $):
90
  100, 0.21
91
  250, 0.2
92
- 500, 0.18
93
- 1000, 0.17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  """
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  def find_best_price(request):
98
  chat_prompt = (
99
- "You are a customer assistant and you have to find the best price for the customer. "
100
  "Here are the prices and options from the printers:\n"
101
  f"Printer 1: {printer_1}\n"
102
  f"Printer 2: {printer_2}\n"
103
  f"Printer 3: {printer_3}\n"
104
- "For each request, you should:\n"
105
  "1. Check if the requested size is available. If not, check if vendor supports custom sizes.\n"
 
 
106
  "2. Calculate the final price by:\n"
107
  " - Finding the nearest lower quantity in the base price list.\n"
108
  " - Multiplying by the size multiplier\n"
109
- " - Multiplying by the user requested amount. IMPORTANT. Do no multiply by nearest lower quantity!"
110
  "3. Do not use linear interpolation for quantities - use the nearest lower quantity pricing.\n\n"
111
  "Example:\n"
112
- "User: I want to print 600 business cards, 6x6 cm size, \n"
113
  "Answer:\n"
114
- "PrintPronto: Doesn't support custom size\n"
115
- "###\n"
116
- "BannerLord: amount (600) * multiplier for custom size (2.0) * price per unit for nearest pack size ($0.2). Total for 600: $240\n"
117
- "###\n"
118
- "PrintMaster: amount (600) * multiplier for custom size (2.0) * price per unit for nearest pack size ($0.18). Total for 600: $216\n\n"
119
- "If user haven't specified one of the parameters, use the default one"
120
- "Your response should display ONLY final pricing for each available option, nothing more"
121
- "The '###' symbol must separate each printer's price calculation.\n"
 
 
 
 
 
 
 
 
 
 
122
  )
123
 
124
  chat_response = client.chat.completions.create(
@@ -127,51 +404,82 @@ def find_best_price(request):
127
  {"role": "system", "content": chat_prompt},
128
  {"role": "user", "content": request},
129
  ],
 
130
  )
131
 
132
  chat_text = chat_response.choices[0].message.content
 
 
 
 
 
 
 
 
 
 
 
133
 
134
- html_page = render_html_page(chat_text)
135
 
136
- chat_text = chat_text.replace("###", "")
137
  return html_page, chat_text
138
 
139
 
140
- def render_html_page(chat_text):
141
- formatting_prompt = (
142
- "format this text for product card. It needs to be like this:\n"
143
- "Vendor name 1: $price for 'amount'"
144
- "###"
145
- "Vendor name 2: $price for 'amount'"
146
- "###"
147
- "And so on for the rest of the vendors"
 
 
 
 
 
 
 
148
  )
149
 
150
- chat_response = client.chat.completions.create(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  model="gpt-4o-mini",
152
  messages=[
153
- {"role": "system", "content": formatting_prompt},
154
- {"role": "user", "content": chat_text},
155
  ],
156
  )
157
- formatted_text = chat_response.choices[0].message.content
158
- images = [
159
- os.path.join(script_dir, "public/src/painted-edge-business-card-05.png"),
160
- os.path.join(
161
- script_dir, "public/src/painted-edge-cards---w-brown-box-_4-4-color_.png"
162
- ),
163
- os.path.join(script_dir, "public/src/silk-business-card-03_1.png"),
164
- ]
165
- product_links = [
166
- "https://www.example.com/product_image.jpg",
167
- "https://www.example.com/product_image.jpg",
168
- "https://www.example.com/product_image.jpg",
169
- ]
170
 
171
- # Split chat_text into product descriptions
172
- product_descriptions = formatted_text.split("###")
173
 
174
- # Generate HTML content
 
 
 
 
 
175
  html_content = """
176
  <html>
177
  <head>
@@ -185,7 +493,6 @@ def render_html_page(chat_text):
185
  text-align: center;
186
  width: 200px;
187
  display: inline-block;
188
- vertical-align: top;
189
  }
190
  .product-card img {
191
  max-width: 100%;
@@ -206,30 +513,30 @@ def render_html_page(chat_text):
206
  </head>
207
  <body>
208
  """
209
-
210
- for i, description in enumerate(product_descriptions):
211
- if (
212
- "Doesn't support" in description.lower()
213
- or "Not available" in description.lower()
214
- ):
215
- continue
216
- image = images[i % len(images)]
 
 
 
217
  with open(image, "rb") as img_file:
218
  base64_image = base64.b64encode(img_file.read()).decode("utf-8")
219
 
220
- product_link = product_links[i % len(product_links)]
221
  html_content += f"""
222
  <div class="product-card">
223
  <img src="data:image/jpeg;base64,{base64_image}" alt="Product Image">
224
- <p>{description}</p>
225
- <a href="{product_link}" target="_blank"><button>Buy Now</button></a>
 
226
  </div>
227
  """
228
 
229
- html_content += """
230
- </body>
231
- </html>
232
- """
233
  return html_content
234
 
235
 
@@ -247,7 +554,7 @@ iface = gr.Interface(
247
  ],
248
  title="Get Instant Quote",
249
  description=f"""
250
- <div style="display: flex; justify-content: center; align-items: center; text-align: center; margin-bottom: 20px;">
251
  <img src="data:image/svg+xml;base64,{base64_logo}" alt="Logo" style="width: 150px; height: auto;">
252
  </div>
253
  """,
@@ -256,7 +563,7 @@ iface = gr.Interface(
256
 
257
 
258
  def auth_function(username, password):
259
- valid_users = {"admin": "demo4anthony1", "user1": "pass456"}
260
  return username in valid_users and valid_users[username] == password
261
 
262
 
 
3
  from openai import OpenAI
4
  import os
5
  import dotenv
6
+ import re
7
 
8
  dotenv.load_dotenv()
9
 
10
  client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
11
 
12
  script_dir = os.path.dirname(os.path.abspath(__file__))
13
+ COMPANIES = ["PrintPronto", "BannerLord", "PrintMaster"]
14
  printer_1 = """
15
  # PrintPronto
16
+ ## Product: Business cards
17
 
18
  Color:
19
  - Black (default)
 
23
  - Pink
24
 
25
  Sizes:
26
+ 3.5x2: multiplier 1.0 (default)
27
  2.5x2.5: multiplier 0.95
28
  2.125x3.375: multiplier 0.9
29
  Custom size: This vendor doesn't support custom sizes
 
36
  100, 0.23
37
  250, 0.2
38
  500, 0.19
39
+ 1000, 0.17
40
+
41
+ ## Product: Fabric Banners
42
+
43
+ Sizes:
44
+ 2.5x4: multiplier 1.0
45
+ 4x4: multiplier 1.1
46
+ 2.5x6: multiplier 1.0 (default)
47
+ 2.5x8: multiplier 1.2
48
+ 4x6: multiplier 1.5
49
+ Custom size: This vendor doesn't support custom sizes
50
+
51
+ Base Prices (Quantity,Price per Unit $):
52
+ 1, 230.00
53
+ 5, 210.00
54
+ 10, 201.50
55
+ 25, 195.26
56
+
57
+ ## Product: Bumper Stickers
58
+
59
+ Shapes:
60
+ Rectangles: multiplier 1.0
61
+ Squares: multiplier 1.0
62
+ Circles: multiplier 1.0
63
+ Ovals: multiplier 1.0
64
+ Rounded Rectangles: multiplier 1.0
65
+ Custom shape: This vendor doesn't support custom shapes
66
+
67
+ Sizes:
68
+ 2x3: multiplier 1.0
69
+ 2x4: multiplier 1.1
70
+ 3x4: multiplier 1.0 (default)
71
+ 3x6: multiplier 1.2
72
+ 2x8: multiplier 1.5
73
+ Custom size: This vendor doesn't support custom sizes
74
+
75
+ Base Prices (Quantity,Price per Unit $):
76
+ 50, 1.80
77
+ 100, 1.10
78
+ 250, 0.80
79
+ 500, 0.44
80
+ 1000, 0.24
81
+
82
+ ## Product: Paper Stickers
83
+
84
+ Shapes:
85
+ Rectangles: multiplier 1.0
86
+ Squares: multiplier 1.0
87
+ Circles: multiplier 1.0
88
+ Ovals: multiplier 1.0
89
+ Custom size: This vendor doesn't support custom shapes
90
+
91
+ Sizes:
92
+ 0.79: multiplier 1.0 (default)
93
+ 1: multiplier 1.1
94
+ 1.18: multiplier 1.0
95
+ 1.26: multiplier 1.2
96
+ 1.38: multiplier 1.5
97
+ Custom size: This vendor doesn't support custom sizes
98
+
99
+ Material:
100
+ - Gloss Paper (default)
101
+ - Matte Paper
102
+
103
+ Base Prices (Quantity,Price per Unit $):
104
+ 250, 0,40
105
+ 500, 0.22
106
+ 1000, 0.12
107
  """
108
 
109
  printer_2 = """
110
  # BannerLord
111
+ ## Product: Business cards
112
 
113
  Color:
114
  - Black (default)
115
  - Blue
116
 
117
  Sizes:
118
+ 3.5x2: multiplier 1.0 (default)
119
  2.5x2.5: multiplier 0.95
120
  2.125x3.375: multiplier 0.9
121
  3x2: multiplier 1.5
122
  4x3: multiplier 1.5
123
+ Custom size: This vendor supports custom sizes with a multiplier of 2.0
124
 
125
  Material:
126
  - Standard (default)
 
130
  100, 0.25
131
  250, 0.22
132
  500, 0.2
133
+ 1000, 0.19
134
+
135
+ ## Product: Fabric Banners
136
+
137
+ Sizes:
138
+ 2.5x4: multiplier 1.0
139
+ 4x4: multiplier 1.1
140
+ 2.5x6: multiplier 1.0 (default)
141
+ 2.5x8: multiplier 1.2
142
+ 4x6: multiplier 1.5
143
+ Custom size: This vendor supports custom sizes with a multiplier of 2.5
144
+
145
+ Base Prices (Quantity,Price per Unit $):
146
+ 1, 228.00
147
+ 5, 205.00
148
+ 10, 204.90
149
+ 25, 193.56
150
+
151
+ ## Product: Bumper Stickers
152
+
153
+ Shapes:
154
+ Rectangles: multiplier 1.0
155
+ Squares: multiplier 1.0
156
+ Circles: multiplier 1.0
157
+ Ovals: multiplier 1.0
158
+ Rounded Rectangles: multiplier 1.0
159
+ Custom shape: This vendor supports custom shapes with a multiplier of 1.5
160
+
161
+ Sizes:
162
+ 2x3: multiplier 1.0
163
+ 2x4: multiplier 1.1
164
+ 3x4: multiplier 1.0 (default)
165
+ 3x6: multiplier 1.2
166
+ 2x8: multiplier 1.5
167
+ Custom size: This vendor supports custom sizes with a multiplier of 2.0
168
+
169
+ Base Prices (Quantity,Price per Unit $):
170
+ 50, 1.90
171
+ 100, 1.15
172
+ 250, 0.85
173
+ 500, 0.45
174
+ 1000, 0.25
175
+
176
+ ## Product: Paper Stickers
177
+
178
+ Shapes:
179
+ Rectangles: multiplier 1.0
180
+ Squares: multiplier 1.0
181
+ Circles: multiplier 1.0
182
+ Ovals: multiplier 1.0
183
+ Custom size: This vendor supports custom sizes with a multiplier of 2.0
184
+
185
+ Sizes:
186
+ 0.79: multiplier 1.0 (default)
187
+ 1: multiplier 1.1
188
+ 1.18: multiplier 1.0
189
+ 1.26: multiplier 1.2
190
+ 1.38: multiplier 1.5
191
+ Custom size: This vendor supports custom sizes with a multiplier of 2.0
192
+
193
+ Material:
194
+ - Gloss Paper (default)
195
+ - Matte Paper
196
+
197
+ Base Prices (Quantity,Price per Unit $):
198
+ 250, 0.42
199
+ 500, 0.23
200
+ 1000, 0.13
201
  """
202
 
203
  printer_3 = """
204
  # PrintMaster
205
+ ## Product: Business cards
206
+
207
  Color:
208
  - Black (default)
209
  - Blue
210
  - Brown
211
 
212
  Sizes:
213
+ 3.5x2: multiplier 1.0 (default)
214
  2.5x2.5: multiplier 0.95
215
  2.125x3.375: multiplier 0.9
216
  3x2: multiplier 1.5
217
  4x3: multiplier 1.5
218
+ Custom size: This vendor supports custom sizes with a multiplier of 2.0
219
 
220
  Material:
221
  - Standard (default)
 
224
  Base Prices (Quantity,Price per Unit $):
225
  100, 0.21
226
  250, 0.2
227
+ 500, 0.19
228
+ 1000, 0.18
229
+
230
+ ## Product: Fabric Banners
231
+
232
+ Sizes:
233
+ 2.5x4: multiplier 1.0 (default)
234
+ 4x4: multiplier 1.1
235
+ 2.5x6: multiplier 1.0
236
+ 2.5x8: multiplier 1.2
237
+ 4x6: multiplier 1.5
238
+ Custom size: This vendor supports custom sizes with a multiplier of 2.2
239
+
240
+ Base Prices (Quantity,Price per Unit $):
241
+ 1, 231.00
242
+ 5, 209.50
243
+ 10, 203.45
244
+ 25, 194.00
245
+
246
+ ## Product: Bumper Stickers
247
+
248
+ Shapes:
249
+ Rectangles: multiplier 1.0
250
+ Squares: multiplier 1.0
251
+ Circles: multiplier 1.0
252
+ Ovals: multiplier 1.0
253
+ Rounded Rectangles: multiplier 1.0
254
+ Custom shape: This vendor supports custom shapes with a multiplier of 1.5
255
+
256
+ Sizes:
257
+ 2x3: multiplier 1.0 (default)
258
+ 2x4: multiplier 1.1
259
+ 3x4: multiplier 1.0
260
+ 3x6: multiplier 1.2
261
+ 2x8: multiplier 1.5
262
+ Custom size: This vendor supports custom sizes with a multiplier of 2.0
263
+
264
+ Base Prices (Quantity,Price per Unit $):
265
+ 50, 1.85
266
+ 100, 1.10
267
+ 250, 0.82
268
+ 500, 0.43
269
+ 1000, 0.23
270
+
271
+ ## Product: Paper Stickers
272
+
273
+ Shapes:
274
+ Rectangles: multiplier 1.0
275
+ Squares: multiplier 1.0
276
+ Circles: multiplier 1.0
277
+ Ovals: multiplier 1.0
278
+ Custom size: This vendor supports custom sizes with a multiplier of 2.0
279
+
280
+ Sizes:
281
+ 0.79: multiplier 1.0 (default)
282
+ 1: multiplier 1.1
283
+ 1.18: multiplier 1.0
284
+ 1.26: multiplier 1.2
285
+ 1.38: multiplier 1.5
286
+ Custom size: This vendor supports custom sizes with a multiplier of 2.0
287
+
288
+ Material:
289
+ - Gloss Paper (default)
290
+ - Matte Paper
291
+
292
+ Base Prices (Quantity,Price per Unit $):
293
+ 250, 0.40
294
+ 500, 0.21
295
+ 1000, 0.11
296
  """
297
 
298
+ IMAGES = {
299
+ "Business Cards": {
300
+ "images": [
301
+ os.path.join(script_dir, "public/src/painted-edge-business-card-05.png"),
302
+ os.path.join(
303
+ script_dir,
304
+ "public/src/painted-edge-cards---w-brown-box-_4-4-color_.png",
305
+ ),
306
+ os.path.join(script_dir, "public/src/silk-business-card-03_1.png"),
307
+ ],
308
+ "links": [
309
+ "https://www.example.com/product_image.jpg",
310
+ "https://www.example.com/product_image.jpg",
311
+ "https://www.example.com/product_image.jpg",
312
+ ],
313
+ },
314
+ "Fabric Banners": {
315
+ "images": [
316
+ os.path.join(script_dir, "public/src/03.jpg"),
317
+ os.path.join(
318
+ script_dir,
319
+ "public/src/fabric-banner-01.webp",
320
+ ),
321
+ os.path.join(script_dir, "public/src/fabric-banner-02.webp"),
322
+ ],
323
+ "links": [
324
+ "https://www.example.com/product_image.jpg",
325
+ "https://www.example.com/product_image.jpg",
326
+ "https://www.example.com/product_image.jpg",
327
+ ],
328
+ },
329
+ "Bumper Stickers": {
330
+ "images": [
331
+ os.path.join(script_dir, "public/src/clear-bumper-sticker.jpg"),
332
+ os.path.join(
333
+ script_dir,
334
+ "public/src/copy_of_untitled_design_9_.webp",
335
+ ),
336
+ os.path.join(script_dir, "public/src/removable-bumper-stickers.jpg"),
337
+ ],
338
+ "links": [
339
+ "https://www.example.com/product_image.jpg",
340
+ "https://www.example.com/product_image.jpg",
341
+ "https://www.example.com/product_image.jpg",
342
+ ],
343
+ },
344
+ "Paper Stickers": {
345
+ "images": [
346
+ os.path.join(script_dir, "public/src/us_images_1_.webp"),
347
+ os.path.join(
348
+ script_dir,
349
+ "public/src/copy_of_us_images_1__1.webp",
350
+ ),
351
+ os.path.join(script_dir, "public/src/copy_of_us_images_1__1.webp"),
352
+ ],
353
+ "links": [
354
+ "https://www.example.com/product_image.jpg",
355
+ "https://www.example.com/product_image.jpg",
356
+ "https://www.example.com/product_image.jpg",
357
+ ],
358
+ },
359
+ }
360
+
361
 
362
  def find_best_price(request):
363
  chat_prompt = (
364
+ "You are a customer assistant tasked with finding the best price for multiple items from different printers.\n"
365
  "Here are the prices and options from the printers:\n"
366
  f"Printer 1: {printer_1}\n"
367
  f"Printer 2: {printer_2}\n"
368
  f"Printer 3: {printer_3}\n"
369
+ "For each product in request, you should:\n"
370
  "1. Check if the requested size is available. If not, check if vendor supports custom sizes.\n"
371
+ "If user hasn't specified one of the parameters (size, shape, etc), use the default one.\n"
372
+ "Use custom size multiplier only if user requested size and vendor supports custom sizes.\n"
373
  "2. Calculate the final price by:\n"
374
  " - Finding the nearest lower quantity in the base price list.\n"
375
  " - Multiplying by the size multiplier\n"
376
+ " - Multiplying by the user requested amount. IMPORTANT. Do not multiply by nearest lower quantity!\n"
377
  "3. Do not use linear interpolation for quantities - use the nearest lower quantity pricing.\n\n"
378
  "Example:\n"
379
+ "User: I want 25 banners in size 6x6, 2000 business cards and 5000 circle stickers in size 6x6 on matte paper\n"
380
  "Answer:\n"
381
+ "Banners:\n"
382
+ "- PrintPronto: Doesn't support custom size\n"
383
+ "- BannerLord: amount (25) * multiplier for custom size (2.5) * price per unit for nearest pack size ($193.56). Total for 25: $12097.50\n"
384
+ "- PrintMaster: amount (25) * multiplier for custom size (2.2) * price per unit for nearest pack size ($194.00). Total for 25: $10670.00\n\n"
385
+ "Business cards:\n"
386
+ "- PrintPronto: amount (2000) * multiplier for default size (1.0) * price per unit for nearest pack size ($0.17). Total for 2000: $340.00\n"
387
+ "- BannerLord: amount (2000) * multiplier for default size (1.0) * price per unit for nearest pack size ($0.19). Total for 2000: $380.00\n"
388
+ "- PrintMaster: amount (2000) * multiplier for default size (1.0) * price per unit for nearest pack size ($0.18). Total for 2000: $360.00\n\n"
389
+ " Paper stickers:\n"
390
+ "- PrintPronto: Doesn't support custom size\n"
391
+ "- BannerLord: amount (5000) * multiplier for circle shape (1.0) * multiplier for custom size (2.0) * price per unit for nearest pack size ($0.13). Total for 5000: $1300.00\n"
392
+ "- PrintMaster: amount (5000) * multiplier for circle shape (1.0) * multiplier for custom size (2.0) * price per unit for nearest pack size ($0.11). Total for 5000: $1100.00\n\n"
393
+ "Your response should display ONLY final pricing for each available option, nothing more.\n"
394
+ "At the end of your response, write summary in the following format:\n"
395
+ "Full order quote: *all items, that user's requested*\n"
396
+ "- Printer1: $price of full request\n"
397
+ "- Printer2: $price of full request\n"
398
+ "- Printer3: $price of full request\n"
399
  )
400
 
401
  chat_response = client.chat.completions.create(
 
404
  {"role": "system", "content": chat_prompt},
405
  {"role": "user", "content": request},
406
  ],
407
+ temperature=0.5,
408
  )
409
 
410
  chat_text = chat_response.choices[0].message.content
411
+ chat_text = chat_text.replace("###", "")
412
+
413
+ images_to_use = extract_requested_products(
414
+ request=request, product_names=list(IMAGES.keys())
415
+ )
416
+ if images_to_use is None:
417
+ html_page = (
418
+ "<html><body><h3>Requested product is not available.</h3></body></html>"
419
+ )
420
+ chat_text = "Requested product is not available."
421
+ return html_page, chat_text
422
 
423
+ html_page = render_html_page(chat_text, images_to_use)
424
 
 
425
  return html_page, chat_text
426
 
427
 
428
+ def extract_total_prices(text):
429
+ """
430
+ Extracts total prices and availability information from a text block,
431
+ preserving the order of appearance.
432
+
433
+ Args:
434
+ text: The input text.
435
+
436
+ Returns:
437
+ A list of strings containing prices and availability messages in order.
438
+ """
439
+ results = []
440
+ # Combine patterns using the OR operator | and capture groups
441
+ pattern = (
442
+ r"(Total for \d+: (\$\d+(?:,\d{3})*(?:\.\d{2})?))|(Doesn't support custom size)"
443
  )
444
 
445
+ matches = re.findall(pattern, text)
446
+
447
+ for match in matches:
448
+ # Check which group matched
449
+ if match[0]: # Price match
450
+ results.append(match[1])
451
+ elif match[2]: # Availability match
452
+ results.append(match[2])
453
+ return results
454
+
455
+
456
+ def extract_requested_products(request, product_names):
457
+ product_list = "\n".join(f"- {product}" for product in product_names)
458
+ prompt = (
459
+ "Here are the available product names:\n"
460
+ f"{product_list}\n"
461
+ "Identify any products explicitly or implicitly mentioned in the user's request. "
462
+ "If no products match, respond with 'None'. Output the result as a Python list. "
463
+ "Your response should contain only the list or 'None'."
464
+ )
465
+
466
+ response = client.chat.completions.create(
467
  model="gpt-4o-mini",
468
  messages=[
469
+ {"role": "system", "content": prompt},
470
+ {"role": "user", "content": request},
471
  ],
472
  )
473
+ response_text = response.choices[0].message.content
474
+ return eval(response_text)
 
 
 
 
 
 
 
 
 
 
 
475
 
 
 
476
 
477
+ def render_html_page(chat_text, images_to_use):
478
+ if images_to_use is None:
479
+ return "<html><body><h3>Requested product is not available.</h3></body></html>"
480
+
481
+ # product_descriptions = chat_text.split("\n")
482
+
483
  html_content = """
484
  <html>
485
  <head>
 
493
  text-align: center;
494
  width: 200px;
495
  display: inline-block;
 
496
  }
497
  .product-card img {
498
  max-width: 100%;
 
513
  </head>
514
  <body>
515
  """
516
+ processed_images = [
517
+ image for img in images_to_use for image in IMAGES[img]["images"]
518
+ ]
519
+ processed_links = [link for img in images_to_use for link in IMAGES[img]["links"]]
520
+ print(chat_text)
521
+ processed_prices = extract_total_prices(chat_text)
522
+ print(processed_prices)
523
+ # print(product_descriptions)
524
+ for i in range(len(processed_images)):
525
+ print(i)
526
+ image = processed_images[i]
527
  with open(image, "rb") as img_file:
528
  base64_image = base64.b64encode(img_file.read()).decode("utf-8")
529
 
 
530
  html_content += f"""
531
  <div class="product-card">
532
  <img src="data:image/jpeg;base64,{base64_image}" alt="Product Image">
533
+ <p>{COMPANIES[i % 3]+': '+processed_prices[i]}</p>
534
+ <a href="{processed_links[i]}" target="_blank"><button>Buy Now</button></a>
535
+
536
  </div>
537
  """
538
 
539
+ html_content += "</body></html>"
 
 
 
540
  return html_content
541
 
542
 
 
554
  ],
555
  title="Get Instant Quote",
556
  description=f"""
557
+ <div style="display: flex; justify-content: center; align-items: center; text-align: center; margin-bottom: 20px;">
558
  <img src="data:image/svg+xml;base64,{base64_logo}" alt="Logo" style="width: 150px; height: auto;">
559
  </div>
560
  """,
 
563
 
564
 
565
  def auth_function(username, password):
566
+ valid_users = {"admin": "demo4anthony1", "user": "strongpassword123"}
567
  return username in valid_users and valid_users[username] == password
568
 
569
 
public/src/03.jpg ADDED
public/src/clear-bumper-sticker.jpg ADDED
public/src/copy_of_untitled_design_9_.webp ADDED
public/src/copy_of_us_images.jpg ADDED
public/src/copy_of_us_images_1__1.webp ADDED
public/src/fabric-banner-01.webp ADDED
public/src/fabric-banner-02.webp ADDED
public/src/removable-bumper-stickers.jpg ADDED
public/src/us_images_1_.webp ADDED