AmpParth commited on
Commit
6b76852
·
verified ·
1 Parent(s): e5cfe53

Upload 4 files

Browse files
Files changed (4) hide show
  1. .env +2 -0
  2. Dockerfile +14 -0
  3. app.py +208 -0
  4. requirements.txt +8 -0
.env ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ DEEPGRAM_API_KEY='43044985b4f715eda085e2b5e974f14edb2abf81'
2
+ OPENAI_API_KEY='9b3fd60a04ff4517be88e57bb91f205f'
Dockerfile ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use the official Python 3.10.9 image
2
+ FROM python:3.10.9
3
+
4
+ # Copy the current directory contents into the container at .
5
+ COPY . .
6
+
7
+ # Set the working directory to /
8
+ WORKDIR /
9
+
10
+ # Install requirements.txt
11
+ RUN pip install --no-cache-dir --upgrade -r /requirements.txt
12
+
13
+ # Start the FastAPI app on port 7860, the default port expected by Spaces
14
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from pydantic import BaseModel
4
+ import openai
5
+ from dotenv import load_dotenv
6
+ import os
7
+
8
+ # Load environment variables from .env file
9
+ load_dotenv()
10
+
11
+ # Configure OpenAI for Azure
12
+ openai.api_type = "azure"
13
+ openai.api_base = "https://amplifai-openai.openai.azure.com/"
14
+ openai.api_version = "2023-07-01-preview"
15
+ openai.api_key = os.getenv("OPENAI_API_KEY")
16
+
17
+ app = FastAPI()
18
+
19
+ class Prompt(BaseModel):
20
+ text: str
21
+
22
+ class GenerateResponse(BaseModel):
23
+ text: str
24
+ class GenerateResponse2(BaseModel):
25
+ text: dict
26
+
27
+ #Summarize function
28
+ def summarize_text(text: str):
29
+ response = openai.Completion.create(
30
+ engine="AmplifAI-Chat",
31
+ prompt="The data is a pre-recorded conversation between a call center agent and a customer. Identify the following: keywords/metrics about the conversation, a summary of the conversation including details, points of improvement for the agent, and coaching advice. Output should be in the format Keywords/Metrics: ,\n Summary: , \nPoints of Improvement: ,\nCoaching Advice:. \n Data: " + text,
32
+ temperature=0.7,
33
+ max_tokens=750,
34
+ top_p=1.0,
35
+ frequency_penalty=0.0,
36
+ presence_penalty=0.0
37
+ )
38
+ if response.choices:
39
+ summary = response.choices[0].text.strip()
40
+ return GenerateResponse(text=summary)
41
+ else:
42
+ return "No response from the API."
43
+
44
+
45
+ # QA Automation function
46
+ def qa_automation(text: str):
47
+ questions = [
48
+ "Did the agent verify the identity of the caller clearly? Provide Details.",
49
+ "Did the agent resolve the Primary reason of the call? Provide Details.",
50
+ "Was the agent courteous? Provide Details.",
51
+ # "Did the agent get a promise to pay? Provide Details."
52
+ "Rate the satisfaction of the customer on a scale of 10. 0 being worse and 10 being best.",
53
+ "Rate the customer effort on a scale of 0-10. 0 being the most effort spent by the customer and 10 being least effort:",
54
+ "How could the agent have made the call easier for the customer?"
55
+ ]
56
+ answers = []
57
+ for question in questions:
58
+ response = openai.Completion.create(
59
+ engine="AmplifAI-Chat",
60
+ prompt=f"Question: {question}\nTranscript: {text}\nAnswer:",
61
+ temperature=0.2,
62
+ max_tokens=100,
63
+ top_p=1.0,
64
+ frequency_penalty=0.0,
65
+ presence_penalty=0.0,
66
+ stop=["\n"]
67
+ )
68
+ answer = response.choices[0].text.strip()
69
+ # Split the answer into the main answer (Yes/No) and the details
70
+ if "Yes" in answer:
71
+ main_answer, details = answer.split("Yes", 1)
72
+ main_answer += "Yes"
73
+ elif "No" in answer:
74
+ main_answer, details = answer.split("No", 1)
75
+ main_answer += "No"
76
+ else:
77
+ main_answer = answer
78
+ details = "No additional details provided."
79
+
80
+ # Format the answer with the "Comments:" tag in bold and on a new line
81
+ formatted_answer = f"**{question}** {main_answer}\n\n**Comments:** {details}"
82
+
83
+ answers.append(formatted_answer)
84
+ return GenerateResponse(text = ("\n\n".join(answers)))
85
+
86
+
87
+ def check_agent_steps(text: str):
88
+ categories = {
89
+ "Introduction": [
90
+ "Greet the customer politely.",
91
+ "Identify yourself and your company.",
92
+ "Verify the customer's identity to ensure confidentiality."
93
+ ],
94
+ "Purpose of the Call": [
95
+ "State the purpose of the call clearly.",
96
+ "Mention the specific account or debt in question."
97
+ ],
98
+ "Account Review": [
99
+ "Provide details of outstanding debt, the amount, due date, and charges or fees.",
100
+ "Confirm whether the customer acknowledges the debt."
101
+ ],
102
+ "Listen to the Customer": [
103
+ "Give the customer an opportunity to explain their situation.",
104
+ "Show empathy and understanding."
105
+ ],
106
+ "Payment Discussion": [
107
+ "Ask the customer about their ability to pay the outstanding amount.",
108
+ "Discuss payment options and negotiate a payment plan if necessary.",
109
+ "Set clear terms for the payment plan, including amounts and due dates."
110
+ ],
111
+ "Confirmation": [
112
+ "Confirm the agreed-upon payment plan or next steps.",
113
+ "Provide details on how the payment can be made (e.g., online, phone, mail)."
114
+ ],
115
+ "Documentation": [
116
+ "Inform the customer that the call is recorded for compliance/training purposes.",
117
+ "Offer to send a written confirmation of any agreements made during the call."
118
+ ],
119
+ "Closing": [
120
+ "Thank the customer for their time and cooperation.",
121
+ "Provide a contact number for any further questions or concerns.",
122
+ "End the call politely."
123
+ ]
124
+ }
125
+
126
+ # Initialize a dictionary to store the results
127
+ results = {category: {} for category in categories}
128
+
129
+ # Iterate through each category and its questions
130
+ for category, questions in categories.items():
131
+ for question in questions:
132
+ # print("Checking question:", question)
133
+ response = openai.Completion.create(
134
+ engine="AmplifAI-Chat",
135
+ prompt=f"Based on the transcript, did the agent follow the step: {question}? Provide a 'Yes' or 'No' answer.\nTranscript: {text}\nAnswer: ",
136
+ temperature=0.2,
137
+ max_tokens=10,
138
+ top_p=1.0,
139
+ frequency_penalty=0.0,
140
+ presence_penalty=0.0,
141
+ stop=["\n"]
142
+ )
143
+ answer = response.choices[0].text.strip()
144
+ # emoji_answer = '✅' if answer == "Yes" else '❌'
145
+ # print("Answer:", answer)
146
+ results[category][question] = answer
147
+ return GenerateResponse2(text=results)
148
+
149
+ def custom_qa_automation(text: str, custom_question: str):
150
+ # Ensure the custom question ends with "Provide Details."
151
+ if not custom_question.strip().endswith("Provide Details."):
152
+ custom_question = custom_question.strip() + " Provide Details."
153
+
154
+ response = openai.Completion.create(
155
+ engine="AmplifAI-Chat",
156
+ prompt=f"Question: {custom_question}\nTranscript: {text}\nAnswer:",
157
+ temperature=0.2,
158
+ max_tokens=100,
159
+ top_p=1.0,
160
+ frequency_penalty=0.0,
161
+ presence_penalty=0.0,
162
+ stop=["\n"]
163
+ )
164
+ answer = response.choices[0].text.strip()
165
+ # Split the answer into the main answer (Yes/No) and the details
166
+ if "Yes" in answer:
167
+ main_answer, details = answer.split("Yes", 1)
168
+ main_answer += "Yes"
169
+ elif "No" in answer:
170
+ main_answer, details = answer.split("No", 1)
171
+ main_answer += "No"
172
+ else:
173
+ main_answer = answer
174
+ details = "No additional details provided."
175
+
176
+ # Format the answer with the "Comments:" tag in bold and on a new line
177
+ formatted_answer = f"**{custom_question}** {main_answer}\n\n**Comments:** {details}"
178
+
179
+ return GenerateResponse(text=formatted_answer)
180
+
181
+
182
+ app.add_middleware(
183
+ CORSMiddleware,
184
+ allow_origins=["*"],
185
+ allow_credentials=True,
186
+ allow_methods=["*"],
187
+ allow_headers=["*"],
188
+ )
189
+
190
+ @app.get("/", tags=["Home"])
191
+ def api_home():
192
+ return {'detail': 'Welcome to FastAPI TextGen Tutorial!'}
193
+
194
+ @app.post("/api/summarize", summary="Generate text from prompt", tags=["Generate"], response_model=GenerateResponse)
195
+ def inference(input_prompt: Prompt):
196
+ return summarize_text(text=input_prompt.text)
197
+
198
+ @app.post("/api/qautomation", summary="Generate text from prompt", tags=["Generate"], response_model=GenerateResponse)
199
+ def inference(input_prompt: Prompt):
200
+ return qa_automation(text=input_prompt.text)
201
+
202
+ @app.post("/api/verify-call-flow", summary="Generate text from prompt", tags=["Generate"], response_model=GenerateResponse2)
203
+ def inference(input_prompt: Prompt):
204
+ return check_agent_steps(text=input_prompt.text)
205
+
206
+ @app.post("/api/custom-qa", summary="Generate text from prompt", tags=["Generate"], response_model=GenerateResponse)
207
+ def inference(input_prompt: Prompt, question: Prompt):
208
+ return custom_qa_automation(text=input_prompt.text, custom_question=question.text)
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ fastapi==0.99.1
2
+ uvicorn
3
+ requests
4
+ langchain
5
+ openai==0.28.0
6
+ pillow==10.2.0
7
+ pydantic
8
+ python-dotenv