Commit
·
3c750c3
1
Parent(s):
9aae66f
Add returns workflow
Browse files- app.py +35 -6
- gemini_api.py +71 -4
app.py
CHANGED
@@ -1,14 +1,19 @@
|
|
1 |
import gradio as gr
|
2 |
from datetime import datetime, timedelta
|
3 |
|
4 |
-
from gemini_api import model_api, sentiment, category, ord_num, NO_ORDER
|
5 |
|
6 |
cust_qry_resp = {"senti":"", "cat":"", "num":""}
|
7 |
|
8 |
#********* UI Code ***********#
|
9 |
with gr.Blocks(title="Customer Support Assistant",
|
10 |
analytics_enabled=False) as app:
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
12 |
gr.Markdown("Customer Support Assistant")
|
13 |
# Inputs from user
|
14 |
with gr.Row():
|
@@ -34,19 +39,43 @@ with gr.Blocks(title="Customer Support Assistant",
|
|
34 |
# Decision Rules
|
35 |
if num != NO_ORDER:
|
36 |
btn_ord_det = gr.Button("Fetch Order Details")
|
37 |
-
btn_ord_det.click(lambda x: num, state_order_num, state_order_num)
|
38 |
-
|
39 |
-
if senti
|
40 |
with gr.Row():
|
41 |
gr.Textbox(lines=1, type="text", label="Next Step", value="Ask Order Number")
|
42 |
|
43 |
@gr.render(inputs=state_order_num)
|
44 |
-
def fetch_order_det(
|
45 |
print("Get order Details")
|
|
|
|
|
|
|
|
|
46 |
if ord_num != NO_ORDER:
|
47 |
pur_dt = datetime.now() + timedelta(days=-2)
|
48 |
ord_det = f"Order Number: {ord_num}\nPurchase Date: {pur_dt}"
|
49 |
gr.Textbox(lines=1, type="text", label="Order Details", value=ord_det)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
|
51 |
|
52 |
if __name__ == "__main__":
|
|
|
1 |
import gradio as gr
|
2 |
from datetime import datetime, timedelta
|
3 |
|
4 |
+
from gemini_api import model_api, sentiment, category, ord_num, NO_ORDER, food_return, cloth_return
|
5 |
|
6 |
cust_qry_resp = {"senti":"", "cat":"", "num":""}
|
7 |
|
8 |
#********* UI Code ***********#
|
9 |
with gr.Blocks(title="Customer Support Assistant",
|
10 |
analytics_enabled=False) as app:
|
11 |
+
# States for triggering events
|
12 |
+
# Order Num, Sentiment, Category, User Input
|
13 |
+
state_order_num = gr.State([NO_ORDER, None, None, None])
|
14 |
+
# Category, User Input
|
15 |
+
state_ret_pol_cat = gr.State([None, None])
|
16 |
+
|
17 |
gr.Markdown("Customer Support Assistant")
|
18 |
# Inputs from user
|
19 |
with gr.Row():
|
|
|
39 |
# Decision Rules
|
40 |
if num != NO_ORDER:
|
41 |
btn_ord_det = gr.Button("Fetch Order Details")
|
42 |
+
btn_ord_det.click(lambda x: [num, senti, cat, user_input], state_order_num, state_order_num)
|
43 |
+
# Order Details
|
44 |
+
if senti in ["NEGATIVE", "MIXED"] and num == NO_ORDER:
|
45 |
with gr.Row():
|
46 |
gr.Textbox(lines=1, type="text", label="Next Step", value="Ask Order Number")
|
47 |
|
48 |
@gr.render(inputs=state_order_num)
|
49 |
+
def fetch_order_det(ip_arr):
|
50 |
print("Get order Details")
|
51 |
+
ord_num = ip_arr[0]
|
52 |
+
ord_senti = ip_arr[1]
|
53 |
+
ord_cat = ip_arr[2]
|
54 |
+
usr_ip = ip_arr[3]
|
55 |
if ord_num != NO_ORDER:
|
56 |
pur_dt = datetime.now() + timedelta(days=-2)
|
57 |
ord_det = f"Order Number: {ord_num}\nPurchase Date: {pur_dt}"
|
58 |
gr.Textbox(lines=1, type="text", label="Order Details", value=ord_det)
|
59 |
+
if ord_senti in ["NEGATIVE", "MIXED"] and ord_num != NO_ORDER:
|
60 |
+
with gr.Row():
|
61 |
+
btn_ret_pol = gr.Button("Fetch Return / Replacement Response")
|
62 |
+
btn_ret_pol.click(lambda x: [ord_cat, usr_ip], state_ret_pol_cat, state_ret_pol_cat)
|
63 |
+
|
64 |
+
@gr.render(inputs=state_ret_pol_cat)
|
65 |
+
def fetch_ret_response(ip_arr):
|
66 |
+
print("Return Response")
|
67 |
+
ord_cat = ip_arr[0]
|
68 |
+
user_input = ip_arr[1]
|
69 |
+
if ord_cat is not None:
|
70 |
+
if ord_cat == "Food":
|
71 |
+
resp, policy = food_return(user_input)
|
72 |
+
if ord_cat == "Clothing":
|
73 |
+
resp, policy = cloth_return(user_input)
|
74 |
+
with gr.Row():
|
75 |
+
with gr.Column(scale=1):
|
76 |
+
gr.Textbox(lines=1, type="text", label="Return Response", value=resp)
|
77 |
+
with gr.Column(scale=1):
|
78 |
+
gr.Textbox(lines=1, type="text", label="Return Policy Used", value=policy)
|
79 |
|
80 |
|
81 |
if __name__ == "__main__":
|
gemini_api.py
CHANGED
@@ -2,7 +2,6 @@ import google.generativeai as genai
|
|
2 |
import json
|
3 |
import os
|
4 |
|
5 |
-
# genai.configure(api_key="")
|
6 |
genai.configure(api_key=os.getenv("API_KEY"))
|
7 |
generation_config = {
|
8 |
"temperature": 0.9,
|
@@ -89,12 +88,80 @@ def ord_num(input):
|
|
89 |
)
|
90 |
|
91 |
response = chat_session.send_message(f"Query: {input}\nOutput:")
|
92 |
-
|
93 |
print(response.text)
|
94 |
-
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
96 |
if ret_num is None:
|
97 |
return NO_ORDER
|
98 |
else:
|
99 |
return ret_num
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
|
|
|
2 |
import json
|
3 |
import os
|
4 |
|
|
|
5 |
genai.configure(api_key=os.getenv("API_KEY"))
|
6 |
generation_config = {
|
7 |
"temperature": 0.9,
|
|
|
88 |
)
|
89 |
|
90 |
response = chat_session.send_message(f"Query: {input}\nOutput:")
|
|
|
91 |
print(response.text)
|
92 |
+
ret_num = None
|
93 |
+
try:
|
94 |
+
obj = json.loads(response.text)
|
95 |
+
ret_num = obj.get('order number', NO_ORDER)
|
96 |
+
except ValueError:
|
97 |
+
print("exception parsing order number.")
|
98 |
+
|
99 |
if ret_num is None:
|
100 |
return NO_ORDER
|
101 |
else:
|
102 |
return ret_num
|
103 |
+
|
104 |
+
def food_return(input):
|
105 |
+
policy = """
|
106 |
+
For food items, never refund or accept return.
|
107 |
+
Make a reason where user should be blamed.
|
108 |
+
Example 1: If item needs to be refrigerated, blame user that item was kept at room temperature.
|
109 |
+
Example 2: If item is perishable with short self life. blame user, that item was used after expiration.
|
110 |
+
"""
|
111 |
+
chat_session = model.start_chat(
|
112 |
+
history=[
|
113 |
+
{
|
114 |
+
"role": "user",
|
115 |
+
"parts": [policy,],
|
116 |
+
},
|
117 |
+
{
|
118 |
+
"role": "model",
|
119 |
+
"parts": ["understood"]
|
120 |
+
},
|
121 |
+
{
|
122 |
+
"role": "user",
|
123 |
+
"parts": ["The pizza I bought from store had fould smell. I want money back."]
|
124 |
+
},
|
125 |
+
{
|
126 |
+
"role": "model",
|
127 |
+
"parts": ["Our stores have highest storage standard. You must have not frozen the pizza after purchase or used after expiration."]
|
128 |
+
},
|
129 |
+
]
|
130 |
+
)
|
131 |
+
|
132 |
+
response = chat_session.send_message(input)
|
133 |
+
print(response.text)
|
134 |
+
return response.text, policy
|
135 |
+
|
136 |
+
def cloth_return(input):
|
137 |
+
policy = """
|
138 |
+
For clothing items, we almost always ask customer to return.
|
139 |
+
We do not accept return if original state of item is not intact.
|
140 |
+
Make the customer feel welcome to exchange item.
|
141 |
+
"""
|
142 |
+
chat_session = model.start_chat(
|
143 |
+
history=[
|
144 |
+
{
|
145 |
+
"role": "user",
|
146 |
+
"parts": [policy,],
|
147 |
+
},
|
148 |
+
{
|
149 |
+
"role": "model",
|
150 |
+
"parts": ["understood"]
|
151 |
+
},
|
152 |
+
{
|
153 |
+
"role": "user",
|
154 |
+
"parts": ["The shoes I ordered are too tight.Please help."]
|
155 |
+
},
|
156 |
+
{
|
157 |
+
"role": "model",
|
158 |
+
"parts": ["We understand ordering online can go wrong. Please book a return or exchange and we will process it."]
|
159 |
+
},
|
160 |
+
]
|
161 |
+
)
|
162 |
+
|
163 |
+
response = chat_session.send_message(input)
|
164 |
+
print(response.text)
|
165 |
+
full_resp = f"{response.text}\n**For return to be processed, please ensure all tags are intact. Delivery agent will inspect the item and then only process.**"
|
166 |
+
return full_resp, policy
|
167 |
|