GPT-5 tüm varyantları buluyor - sadece ilk eşleşmeyi değil
Browse files- smart_warehouse.py +93 -49
smart_warehouse.py
CHANGED
@@ -6,7 +6,7 @@ import os
|
|
6 |
import json
|
7 |
|
8 |
def get_warehouse_stock_smart(user_message):
|
9 |
-
"""Let GPT-5 intelligently find products in XML
|
10 |
|
11 |
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
|
12 |
|
@@ -26,7 +26,7 @@ def get_warehouse_stock_smart(user_message):
|
|
26 |
|
27 |
# Create a simplified product list for GPT
|
28 |
products_summary = []
|
29 |
-
for i, product_block in enumerate(all_products):
|
30 |
name_match = re.search(r'<ProductName><!\[CDATA\[(.*?)\]\]></ProductName>', product_block)
|
31 |
variant_match = re.search(r'<ProductVariant><!\[CDATA\[(.*?)\]\]></ProductVariant>', product_block)
|
32 |
|
@@ -38,15 +38,23 @@ def get_warehouse_stock_smart(user_message):
|
|
38 |
}
|
39 |
products_summary.append(product_info)
|
40 |
|
41 |
-
# Let GPT-5 find
|
42 |
smart_prompt = f"""User is asking: "{user_message}"
|
43 |
|
44 |
-
Find
|
|
|
|
|
|
|
|
|
45 |
{json.dumps(products_summary, ensure_ascii=False, indent=2)}
|
46 |
|
47 |
-
Return
|
48 |
-
|
49 |
-
|
|
|
|
|
|
|
|
|
50 |
|
51 |
headers = {
|
52 |
"Content-Type": "application/json",
|
@@ -56,11 +64,11 @@ If asking about size (S, M, L, XL), match the variant field."""
|
|
56 |
payload = {
|
57 |
"model": "gpt-5-chat-latest",
|
58 |
"messages": [
|
59 |
-
{"role": "system", "content": "You are a product matcher. Return only
|
60 |
{"role": "user", "content": smart_prompt}
|
61 |
],
|
62 |
"temperature": 0,
|
63 |
-
"max_tokens":
|
64 |
}
|
65 |
|
66 |
try:
|
@@ -73,19 +81,75 @@ If asking about size (S, M, L, XL), match the variant field."""
|
|
73 |
|
74 |
if response.status_code == 200:
|
75 |
result = response.json()
|
76 |
-
|
|
|
|
|
|
|
77 |
|
78 |
try:
|
79 |
-
|
80 |
-
|
81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
|
83 |
-
#
|
84 |
-
|
85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
|
87 |
-
except (ValueError, IndexError):
|
88 |
-
print(f"DEBUG -
|
89 |
return None
|
90 |
else:
|
91 |
print(f"GPT API error: {response.status_code}")
|
@@ -95,35 +159,15 @@ If asking about size (S, M, L, XL), match the variant field."""
|
|
95 |
print(f"Error calling GPT: {e}")
|
96 |
return None
|
97 |
|
98 |
-
def
|
99 |
-
"""
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
stock = int(wh_stock.strip())
|
109 |
-
if stock > 0:
|
110 |
-
# Format warehouse name nicely
|
111 |
-
if "CADDEBOSTAN" in wh_name:
|
112 |
-
display = "Caddebostan mağazası"
|
113 |
-
elif "ORTAKÖY" in wh_name:
|
114 |
-
display = "Ortaköy mağazası"
|
115 |
-
elif "ALSANCAK" in wh_name:
|
116 |
-
display = "İzmir Alsancak mağazası"
|
117 |
-
elif "BAHCEKOY" in wh_name or "BAHÇEKÖY" in wh_name:
|
118 |
-
display = "Bahçeköy mağazası"
|
119 |
-
else:
|
120 |
-
display = wh_name.replace("MAGAZA DEPO", "").strip()
|
121 |
-
|
122 |
-
warehouse_info.append(f"{display}: {stock} adet")
|
123 |
-
except:
|
124 |
-
pass
|
125 |
-
|
126 |
-
if warehouse_info:
|
127 |
-
return warehouse_info
|
128 |
else:
|
129 |
-
return
|
|
|
6 |
import json
|
7 |
|
8 |
def get_warehouse_stock_smart(user_message):
|
9 |
+
"""Let GPT-5 intelligently find ALL matching products in XML"""
|
10 |
|
11 |
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
|
12 |
|
|
|
26 |
|
27 |
# Create a simplified product list for GPT
|
28 |
products_summary = []
|
29 |
+
for i, product_block in enumerate(all_products):
|
30 |
name_match = re.search(r'<ProductName><!\[CDATA\[(.*?)\]\]></ProductName>', product_block)
|
31 |
variant_match = re.search(r'<ProductVariant><!\[CDATA\[(.*?)\]\]></ProductVariant>', product_block)
|
32 |
|
|
|
38 |
}
|
39 |
products_summary.append(product_info)
|
40 |
|
41 |
+
# Let GPT-5 find ALL matching products
|
42 |
smart_prompt = f"""User is asking: "{user_message}"
|
43 |
|
44 |
+
Find ALL products that match this query from the list below.
|
45 |
+
If user asks about specific size (S, M, L, XL), return only that size.
|
46 |
+
If user asks generally (without size), return ALL variants of the product.
|
47 |
+
|
48 |
+
Products list:
|
49 |
{json.dumps(products_summary, ensure_ascii=False, indent=2)}
|
50 |
|
51 |
+
Return index numbers of ALL matching products as comma-separated list (e.g., "5,8,12,15").
|
52 |
+
If no products found, return: -1
|
53 |
+
|
54 |
+
Examples:
|
55 |
+
- "madone sl 6 var mı" -> Return ALL Madone SL 6 variants (all sizes)
|
56 |
+
- "madone sl 6 S beden" -> Return only S size variant
|
57 |
+
- "madone sl 6 gen 8" -> Return ALL variants of Madone SL 6 Gen 8"""
|
58 |
|
59 |
headers = {
|
60 |
"Content-Type": "application/json",
|
|
|
64 |
payload = {
|
65 |
"model": "gpt-5-chat-latest",
|
66 |
"messages": [
|
67 |
+
{"role": "system", "content": "You are a product matcher. Find ALL matching products. Return only index numbers."},
|
68 |
{"role": "user", "content": smart_prompt}
|
69 |
],
|
70 |
"temperature": 0,
|
71 |
+
"max_tokens": 100
|
72 |
}
|
73 |
|
74 |
try:
|
|
|
81 |
|
82 |
if response.status_code == 200:
|
83 |
result = response.json()
|
84 |
+
indices_str = result['choices'][0]['message']['content'].strip()
|
85 |
+
|
86 |
+
if indices_str == "-1":
|
87 |
+
return ["Ürün bulunamadı"]
|
88 |
|
89 |
try:
|
90 |
+
# Parse multiple indices
|
91 |
+
indices = [int(idx.strip()) for idx in indices_str.split(',')]
|
92 |
+
|
93 |
+
# Aggregate warehouse info from all matching products
|
94 |
+
all_warehouses = {}
|
95 |
+
product_names = []
|
96 |
+
|
97 |
+
for idx in indices:
|
98 |
+
if 0 <= idx < len(all_products):
|
99 |
+
product_block = all_products[idx]
|
100 |
+
|
101 |
+
# Get product name and variant
|
102 |
+
name_match = re.search(r'<ProductName><!\[CDATA\[(.*?)\]\]></ProductName>', product_block)
|
103 |
+
variant_match = re.search(r'<ProductVariant><!\[CDATA\[(.*?)\]\]></ProductVariant>', product_block)
|
104 |
+
|
105 |
+
if name_match:
|
106 |
+
product_desc = name_match.group(1)
|
107 |
+
if variant_match and variant_match.group(1):
|
108 |
+
product_desc += f" ({variant_match.group(1)})"
|
109 |
+
product_names.append(product_desc)
|
110 |
+
|
111 |
+
# Get warehouse stock
|
112 |
+
warehouse_regex = r'<Warehouse>.*?<Name><!\[CDATA\[(.*?)\]\]></Name>.*?<Stock>(.*?)</Stock>.*?</Warehouse>'
|
113 |
+
warehouses = re.findall(warehouse_regex, product_block, re.DOTALL)
|
114 |
+
|
115 |
+
for wh_name, wh_stock in warehouses:
|
116 |
+
try:
|
117 |
+
stock = int(wh_stock.strip())
|
118 |
+
if stock > 0:
|
119 |
+
# Format warehouse name
|
120 |
+
display_name = format_warehouse_name(wh_name)
|
121 |
+
|
122 |
+
if display_name not in all_warehouses:
|
123 |
+
all_warehouses[display_name] = 0
|
124 |
+
all_warehouses[display_name] += stock
|
125 |
+
except:
|
126 |
+
pass
|
127 |
|
128 |
+
# Format result
|
129 |
+
if product_names:
|
130 |
+
result = []
|
131 |
+
|
132 |
+
# Show product variants found
|
133 |
+
if len(product_names) > 1:
|
134 |
+
result.append(f"Bulunan {len(product_names)} varyant:")
|
135 |
+
for name in product_names[:5]: # Show first 5 variants
|
136 |
+
result.append(f"• {name}")
|
137 |
+
if len(product_names) > 5:
|
138 |
+
result.append(f"... ve {len(product_names) - 5} varyant daha")
|
139 |
+
result.append("")
|
140 |
+
|
141 |
+
# Show aggregated warehouse stock
|
142 |
+
if all_warehouses:
|
143 |
+
result.append("Toplam stok durumu:")
|
144 |
+
for warehouse, total_stock in sorted(all_warehouses.items()):
|
145 |
+
result.append(f"{warehouse}: {total_stock} adet")
|
146 |
+
else:
|
147 |
+
result.append("Hiçbir mağazada stok yok")
|
148 |
+
|
149 |
+
return result
|
150 |
|
151 |
+
except (ValueError, IndexError) as e:
|
152 |
+
print(f"DEBUG - Error parsing indices: {e}")
|
153 |
return None
|
154 |
else:
|
155 |
print(f"GPT API error: {response.status_code}")
|
|
|
159 |
print(f"Error calling GPT: {e}")
|
160 |
return None
|
161 |
|
162 |
+
def format_warehouse_name(wh_name):
|
163 |
+
"""Format warehouse name nicely"""
|
164 |
+
if "CADDEBOSTAN" in wh_name:
|
165 |
+
return "Caddebostan mağazası"
|
166 |
+
elif "ORTAKÖY" in wh_name:
|
167 |
+
return "Ortaköy mağazası"
|
168 |
+
elif "ALSANCAK" in wh_name:
|
169 |
+
return "İzmir Alsancak mağazası"
|
170 |
+
elif "BAHCEKOY" in wh_name or "BAHÇEKÖY" in wh_name:
|
171 |
+
return "Bahçeköy mağazası"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
else:
|
173 |
+
return wh_name.replace("MAGAZA DEPO", "").strip()
|