rasa-pro 3.13.1a6__py3-none-any.whl → 3.13.1a7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rasa-pro might be problematic. Click here for more details.
- rasa/cli/project_templates/finance/actions/database.py +108 -65
- rasa/cli/project_templates/finance/tests/conversation_repair/cancellations.yml +12 -0
- rasa/cli/project_templates/finance/tests/conversation_repair/cannot_handle.yml +7 -0
- rasa/cli/project_templates/finance/tests/conversation_repair/chitchat.yml +7 -0
- rasa/cli/project_templates/finance/tests/conversation_repair/clarification.yml +9 -0
- rasa/cli/project_templates/finance/tests/conversation_repair/completion.yml +18 -0
- rasa/cli/project_templates/finance/tests/conversation_repair/corrections.yml +17 -0
- rasa/cli/project_templates/finance/tests/conversation_repair/digressions.yml +32 -0
- rasa/cli/project_templates/finance/tests/conversation_repair/human_handoff.yml +21 -0
- rasa/cli/project_templates/finance/tests/conversation_repair/skipping_collect_steps.yml +16 -0
- rasa/cli/project_templates/finance/tests/demo_scripts/main.yml +16 -0
- rasa/cli/project_templates/finance/tests/happy_paths/balance_verification.yml +15 -0
- rasa/cli/project_templates/finance/tests/happy_paths/banking_questions.yml +12 -0
- rasa/cli/project_templates/finance/tests/happy_paths/card_blocking.yml +52 -0
- rasa/cli/project_templates/finance/tests/happy_paths/money_transfer.yml +136 -0
- rasa/cli/project_templates/finance/tests/happy_paths/payee_management.yml +27 -0
- rasa/cli/project_templates/finance/tests/happy_paths/user_greeted.yml +5 -0
- rasa/cli/project_templates/plain/domain.yml +1 -1
- rasa/cli/project_templates/telco/actions/actions_billing.py +115 -70
- rasa/cli/project_templates/telco/actions/actions_get_data_from_db.py +26 -11
- rasa/core/policies/enterprise_search_policy.py +1 -1
- rasa/dialogue_understanding/generator/flow_retrieval.py +10 -9
- rasa/version.py +1 -1
- {rasa_pro-3.13.1a6.dist-info → rasa_pro-3.13.1a7.dist-info}/METADATA +1 -1
- {rasa_pro-3.13.1a6.dist-info → rasa_pro-3.13.1a7.dist-info}/RECORD +28 -13
- rasa/cli/project_templates/finance/requirements.txt +0 -1
- {rasa_pro-3.13.1a6.dist-info → rasa_pro-3.13.1a7.dist-info}/NOTICE +0 -0
- {rasa_pro-3.13.1a6.dist-info → rasa_pro-3.13.1a7.dist-info}/WHEEL +0 -0
- {rasa_pro-3.13.1a6.dist-info → rasa_pro-3.13.1a7.dist-info}/entry_points.txt +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import csv
|
|
1
2
|
import logging
|
|
3
|
+
from datetime import datetime
|
|
2
4
|
from pathlib import Path
|
|
3
5
|
from typing import Any, Dict, List, Optional
|
|
4
6
|
|
|
5
|
-
import pandas as pd
|
|
6
|
-
|
|
7
7
|
|
|
8
8
|
class Database:
|
|
9
9
|
def __init__(self, csv_path: Optional[Path] = None) -> None:
|
|
@@ -28,14 +28,39 @@ class Database:
|
|
|
28
28
|
|
|
29
29
|
return logger
|
|
30
30
|
|
|
31
|
+
def _read_csv(self, filename: str) -> List[Dict[str, Any]]:
|
|
32
|
+
"""Read CSV file and return list of dictionaries."""
|
|
33
|
+
try:
|
|
34
|
+
with open(self.csv_path / filename, "r", newline="") as csvfile:
|
|
35
|
+
reader = csv.DictReader(csvfile)
|
|
36
|
+
return list(reader)
|
|
37
|
+
except Exception as e:
|
|
38
|
+
self.logger.error(f"Error reading CSV file {filename}: {e}")
|
|
39
|
+
return []
|
|
40
|
+
|
|
41
|
+
def _write_csv(self, filename: str, data: List[Dict[str, Any]]) -> bool:
|
|
42
|
+
"""Write list of dictionaries to CSV file."""
|
|
43
|
+
try:
|
|
44
|
+
if not data:
|
|
45
|
+
return True
|
|
46
|
+
|
|
47
|
+
with open(self.csv_path / filename, "w", newline="") as csvfile:
|
|
48
|
+
writer = csv.DictWriter(csvfile, fieldnames=data[0].keys())
|
|
49
|
+
writer.writeheader()
|
|
50
|
+
writer.writerows(data)
|
|
51
|
+
return True
|
|
52
|
+
except Exception as e:
|
|
53
|
+
self.logger.error(f"Error writing CSV file {filename}: {e}")
|
|
54
|
+
return False
|
|
55
|
+
|
|
31
56
|
def get_user_by_name(self, username: str) -> Optional[Dict[str, Any]]:
|
|
32
57
|
"""Get user information by username."""
|
|
33
58
|
try:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return
|
|
59
|
+
users = self._read_csv("users.csv")
|
|
60
|
+
for user in users:
|
|
61
|
+
if user["name"] == username:
|
|
62
|
+
return user
|
|
63
|
+
return None
|
|
39
64
|
except Exception as e:
|
|
40
65
|
self.logger.error(f"Error getting user by name: {e}")
|
|
41
66
|
return None
|
|
@@ -43,11 +68,11 @@ class Database:
|
|
|
43
68
|
def get_user_by_id(self, user_id: int) -> Optional[Dict[str, Any]]:
|
|
44
69
|
"""Get user information by user_id."""
|
|
45
70
|
try:
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return
|
|
71
|
+
users = self._read_csv("users.csv")
|
|
72
|
+
for user in users:
|
|
73
|
+
if int(user["id"]) == user_id:
|
|
74
|
+
return user
|
|
75
|
+
return None
|
|
51
76
|
except Exception as e:
|
|
52
77
|
self.logger.error(f"Error getting user by id: {e}")
|
|
53
78
|
return None
|
|
@@ -57,13 +82,14 @@ class Database:
|
|
|
57
82
|
) -> Optional[Dict[str, Any]]:
|
|
58
83
|
"""Get account information by user_id and account number."""
|
|
59
84
|
try:
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
85
|
+
accounts = self._read_csv("accounts.csv")
|
|
86
|
+
for account in accounts:
|
|
87
|
+
if (
|
|
88
|
+
int(account["user_id"]) == user_id
|
|
89
|
+
and account["number"] == account_number
|
|
90
|
+
):
|
|
91
|
+
return account
|
|
92
|
+
return None
|
|
67
93
|
except Exception as e:
|
|
68
94
|
self.logger.error(f"Error getting account: {e}")
|
|
69
95
|
return None
|
|
@@ -71,9 +97,10 @@ class Database:
|
|
|
71
97
|
def get_accounts_by_user(self, user_id: int) -> List[Dict[str, Any]]:
|
|
72
98
|
"""Get all accounts for a user."""
|
|
73
99
|
try:
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
100
|
+
accounts = self._read_csv("accounts.csv")
|
|
101
|
+
return [
|
|
102
|
+
account for account in accounts if int(account["user_id"]) == user_id
|
|
103
|
+
]
|
|
77
104
|
except Exception as e:
|
|
78
105
|
self.logger.error(f"Error getting accounts by user: {e}")
|
|
79
106
|
return []
|
|
@@ -81,9 +108,8 @@ class Database:
|
|
|
81
108
|
def get_payees_by_user(self, user_id: int) -> List[Dict[str, Any]]:
|
|
82
109
|
"""Get all payees for a user."""
|
|
83
110
|
try:
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return payees_data.to_dict("records")
|
|
111
|
+
payees = self._read_csv("payees.csv")
|
|
112
|
+
return [payee for payee in payees if int(payee["user_id"]) == user_id]
|
|
87
113
|
except Exception as e:
|
|
88
114
|
self.logger.error(f"Error getting payees by user: {e}")
|
|
89
115
|
return []
|
|
@@ -93,11 +119,11 @@ class Database:
|
|
|
93
119
|
) -> Optional[Dict[str, Any]]:
|
|
94
120
|
"""Get payee information by name and user_id."""
|
|
95
121
|
try:
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return
|
|
122
|
+
payees = self._read_csv("payees.csv")
|
|
123
|
+
for payee in payees:
|
|
124
|
+
if payee["name"] == payee_name and int(payee["user_id"]) == user_id:
|
|
125
|
+
return payee
|
|
126
|
+
return None
|
|
101
127
|
except Exception as e:
|
|
102
128
|
self.logger.error(f"Error getting payee by name and user: {e}")
|
|
103
129
|
return None
|
|
@@ -105,9 +131,8 @@ class Database:
|
|
|
105
131
|
def get_cards_by_user(self, user_id: int) -> List[Dict[str, Any]]:
|
|
106
132
|
"""Get all cards for a user."""
|
|
107
133
|
try:
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return cards_data.to_dict("records")
|
|
134
|
+
cards = self._read_csv("cards.csv")
|
|
135
|
+
return [card for card in cards if int(card["user_id"]) == user_id]
|
|
111
136
|
except Exception as e:
|
|
112
137
|
self.logger.error(f"Error getting cards by user: {e}")
|
|
113
138
|
return []
|
|
@@ -115,11 +140,11 @@ class Database:
|
|
|
115
140
|
def get_card_by_number(self, card_number: str) -> Optional[Dict[str, Any]]:
|
|
116
141
|
"""Get card information by card number."""
|
|
117
142
|
try:
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
return
|
|
143
|
+
cards = self._read_csv("cards.csv")
|
|
144
|
+
for card in cards:
|
|
145
|
+
if card["number"] == card_number:
|
|
146
|
+
return card
|
|
147
|
+
return None
|
|
123
148
|
except Exception as e:
|
|
124
149
|
self.logger.error(f"Error getting card by number: {e}")
|
|
125
150
|
return None
|
|
@@ -127,10 +152,12 @@ class Database:
|
|
|
127
152
|
def update_card_status(self, card_number: str, status: str) -> bool:
|
|
128
153
|
"""Update card status."""
|
|
129
154
|
try:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
155
|
+
cards = self._read_csv("cards.csv")
|
|
156
|
+
for card in cards:
|
|
157
|
+
if card["number"] == card_number:
|
|
158
|
+
card["status"] = status
|
|
159
|
+
break
|
|
160
|
+
return self._write_csv("cards.csv", cards)
|
|
134
161
|
except Exception as e:
|
|
135
162
|
self.logger.error(f"Error updating card status: {e}")
|
|
136
163
|
return False
|
|
@@ -146,27 +173,28 @@ class Database:
|
|
|
146
173
|
) -> bool:
|
|
147
174
|
"""Add a new payee."""
|
|
148
175
|
try:
|
|
149
|
-
|
|
176
|
+
payees = self._read_csv("payees.csv")
|
|
150
177
|
|
|
151
178
|
# Get the next ID
|
|
152
|
-
next_id =
|
|
179
|
+
next_id = 1
|
|
180
|
+
if payees:
|
|
181
|
+
next_id = max(int(payee["id"]) for payee in payees) + 1
|
|
153
182
|
|
|
154
183
|
# Create new payee record
|
|
155
184
|
new_payee = {
|
|
156
|
-
"id": next_id,
|
|
157
|
-
"user_id": user_id,
|
|
185
|
+
"id": str(next_id),
|
|
186
|
+
"user_id": str(user_id),
|
|
158
187
|
"name": name,
|
|
159
188
|
"sort_code": sort_code,
|
|
160
189
|
"account_number": account_number,
|
|
161
190
|
"type": payee_type,
|
|
162
191
|
"reference": reference,
|
|
163
|
-
"added_at":
|
|
192
|
+
"added_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
|
164
193
|
}
|
|
165
194
|
|
|
166
|
-
# Add to
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
return True
|
|
195
|
+
# Add to list and save
|
|
196
|
+
payees.append(new_payee)
|
|
197
|
+
return self._write_csv("payees.csv", payees)
|
|
170
198
|
except Exception as e:
|
|
171
199
|
self.logger.error(f"Error adding payee: {e}")
|
|
172
200
|
return False
|
|
@@ -174,10 +202,15 @@ class Database:
|
|
|
174
202
|
def remove_payee(self, payee_name: str, user_id: int) -> bool:
|
|
175
203
|
"""Remove a payee."""
|
|
176
204
|
try:
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
205
|
+
payees = self._read_csv("payees.csv")
|
|
206
|
+
payees = [
|
|
207
|
+
payee
|
|
208
|
+
for payee in payees
|
|
209
|
+
if not (
|
|
210
|
+
payee["name"] == payee_name and int(payee["user_id"]) == user_id
|
|
211
|
+
)
|
|
212
|
+
]
|
|
213
|
+
return self._write_csv("payees.csv", payees)
|
|
181
214
|
except Exception as e:
|
|
182
215
|
self.logger.error(f"Error removing payee: {e}")
|
|
183
216
|
return False
|
|
@@ -198,8 +231,7 @@ class Database:
|
|
|
198
231
|
def get_branches(self) -> List[Dict[str, Any]]:
|
|
199
232
|
"""Get all branches."""
|
|
200
233
|
try:
|
|
201
|
-
|
|
202
|
-
return df.to_dict("records")
|
|
234
|
+
return self._read_csv("branches.csv")
|
|
203
235
|
except Exception as e:
|
|
204
236
|
self.logger.error(f"Error getting branches: {e}")
|
|
205
237
|
return []
|
|
@@ -207,9 +239,12 @@ class Database:
|
|
|
207
239
|
def get_advisors_by_branch(self, branch_id: int) -> List[Dict[str, Any]]:
|
|
208
240
|
"""Get all advisors for a branch."""
|
|
209
241
|
try:
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
242
|
+
advisors = self._read_csv("advisors.csv")
|
|
243
|
+
return [
|
|
244
|
+
advisor
|
|
245
|
+
for advisor in advisors
|
|
246
|
+
if int(advisor["branch_id"]) == branch_id
|
|
247
|
+
]
|
|
213
248
|
except Exception as e:
|
|
214
249
|
self.logger.error(f"Error getting advisors by branch: {e}")
|
|
215
250
|
return []
|
|
@@ -217,17 +252,25 @@ class Database:
|
|
|
217
252
|
def get_appointments_by_advisor(self, advisor_id: int) -> List[Dict[str, Any]]:
|
|
218
253
|
"""Get all appointments for an advisor."""
|
|
219
254
|
try:
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
255
|
+
appointments = self._read_csv("appointments.csv")
|
|
256
|
+
return [
|
|
257
|
+
appointment
|
|
258
|
+
for appointment in appointments
|
|
259
|
+
if int(appointment["advisor_id"]) == advisor_id
|
|
260
|
+
]
|
|
223
261
|
except Exception as e:
|
|
224
262
|
self.logger.error(f"Error getting appointments by advisor: {e}")
|
|
225
263
|
return []
|
|
226
264
|
|
|
227
|
-
def __enter__(self):
|
|
265
|
+
def __enter__(self) -> "Database":
|
|
228
266
|
"""Enter the runtime context related to this object."""
|
|
229
267
|
return self
|
|
230
268
|
|
|
231
|
-
def __exit__(
|
|
269
|
+
def __exit__(
|
|
270
|
+
self,
|
|
271
|
+
exc_type: Optional[type],
|
|
272
|
+
exc_value: Optional[BaseException],
|
|
273
|
+
traceback: Optional[Any],
|
|
274
|
+
) -> None:
|
|
232
275
|
"""Exit the runtime context related to this object."""
|
|
233
276
|
self.logger.info("Database connection closed")
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
test_cases:
|
|
2
|
+
- test_case: conversation_repair_simple_cancellation
|
|
3
|
+
steps:
|
|
4
|
+
- user: "hello"
|
|
5
|
+
- utter: utter_chitchat
|
|
6
|
+
- user: "who are my payees"
|
|
7
|
+
- bot: "You are authorised to transfer money to: Amy, Fitness Gym and William"
|
|
8
|
+
- user: "I want to transfer 55 to Amy"
|
|
9
|
+
- utter: utter_transfer_money_understand
|
|
10
|
+
- bot: "Which account would you like to transfer money from?"
|
|
11
|
+
- user: "sorry, I want to cancel that"
|
|
12
|
+
- utter: utter_flow_cancelled_rasa
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
test_cases:
|
|
2
|
+
- test_case: conversation_repair_chitchat
|
|
3
|
+
steps:
|
|
4
|
+
- user: "hello,"
|
|
5
|
+
- utter: utter_chitchat
|
|
6
|
+
- user: "How can we solve world hunger?"
|
|
7
|
+
- bot: "Based on the provided documents and the context of the recent conversation, the question about solving world hunger is not directly addressed. If you have any specific questions related to the documents or conversation context, feel free to ask for more information."
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
test_cases:
|
|
2
|
+
- test_case: conversation_repair_clarification
|
|
3
|
+
steps:
|
|
4
|
+
- user: "hello"
|
|
5
|
+
- utter: utter_chitchat
|
|
6
|
+
- user: "payee"
|
|
7
|
+
- utter: utter_clarification_options_rasa
|
|
8
|
+
- user: "view a list"
|
|
9
|
+
- bot: "You are authorised to transfer money to: Robert, James and Food Market"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
test_cases:
|
|
2
|
+
- test_case: conversation_repair_completion
|
|
3
|
+
steps:
|
|
4
|
+
- user: "hello"
|
|
5
|
+
- utter: utter_chitchat
|
|
6
|
+
- user: "Who are my payees"
|
|
7
|
+
- bot: "You are authorised to transfer money to: Amy, Fitness Gym and William"
|
|
8
|
+
- user: "I want to transfer money to William"
|
|
9
|
+
- utter: utter_transfer_money_understand
|
|
10
|
+
- bot: "Which account would you like to transfer money from?"
|
|
11
|
+
- user: "78901234"
|
|
12
|
+
- utter: utter_ask_amount
|
|
13
|
+
- user: "120"
|
|
14
|
+
- utter: utter_ask_timing
|
|
15
|
+
- user: "/SetSlots(timing=now)"
|
|
16
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
17
|
+
- user: "yes"
|
|
18
|
+
- utter: utter_transfer_successful
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
test_cases:
|
|
2
|
+
- test_case: conversation_repair_corrections
|
|
3
|
+
steps:
|
|
4
|
+
- user: "who are my payees"
|
|
5
|
+
- bot: "You are authorised to transfer money to: Amy, Fitness Gym and William"
|
|
6
|
+
- user: "I want to transfer 55 to Amy"
|
|
7
|
+
- utter: utter_transfer_money_understand
|
|
8
|
+
- bot: "Which account would you like to transfer money from?"
|
|
9
|
+
- user: "67890123"
|
|
10
|
+
- utter: utter_ask_timing
|
|
11
|
+
- user: "/SetSlots(timing=now)"
|
|
12
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
13
|
+
- user: "Sorry, I meant 65 and from Current"
|
|
14
|
+
- utter: utter_corrected_previous_input
|
|
15
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
16
|
+
- user: "yes"
|
|
17
|
+
- utter: utter_transfer_successful
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
test_cases:
|
|
2
|
+
- test_case: conversation_repair_digressions
|
|
3
|
+
steps:
|
|
4
|
+
- user: "I want to transfer money"
|
|
5
|
+
- utter: utter_transfer_money_understand
|
|
6
|
+
- bot: "Which account would you like to transfer money from?"
|
|
7
|
+
- user: "who are my payees"
|
|
8
|
+
- bot: "You are authorised to transfer money to: Richard, Susan and Electric Company"
|
|
9
|
+
- utter: utter_flow_continue_interrupted
|
|
10
|
+
- bot: "Which account would you like to transfer money from?"
|
|
11
|
+
- user: "I would like to add Brad as a payee"
|
|
12
|
+
- utter: utter_ask_account_number
|
|
13
|
+
- user: "123456"
|
|
14
|
+
- utter: utter_ask_payee_type
|
|
15
|
+
- user: "/SetSlots(payee_type=person)"
|
|
16
|
+
- utter: utter_ask_reference
|
|
17
|
+
- user: "Facebook Marketplace"
|
|
18
|
+
- utter: utter_ask_confirm_payee_details
|
|
19
|
+
- user: "/SetSlots(confirm_payee_details=True)"
|
|
20
|
+
- utter: utter_payee_added_success
|
|
21
|
+
- utter: utter_flow_continue_interrupted
|
|
22
|
+
- bot: "Which account would you like to transfer money from?"
|
|
23
|
+
- user: "12345678"
|
|
24
|
+
- utter: utter_ask_payee_name
|
|
25
|
+
- user: "Brad"
|
|
26
|
+
- utter: utter_ask_amount
|
|
27
|
+
- user: "55.23"
|
|
28
|
+
- utter: utter_ask_timing
|
|
29
|
+
- user: "immediate"
|
|
30
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
31
|
+
- user: "yup"
|
|
32
|
+
- utter: utter_transfer_successful
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
test_cases:
|
|
2
|
+
- test_case: conversation_repair_human_handoff
|
|
3
|
+
steps:
|
|
4
|
+
- user: "hello"
|
|
5
|
+
- utter: utter_chitchat
|
|
6
|
+
- user: "i want to transfer 999 from savings"
|
|
7
|
+
- utter: utter_transfer_money_understand
|
|
8
|
+
- utter: utter_ask_payee_name
|
|
9
|
+
- user: "who are my payees"
|
|
10
|
+
- bot: "You are authorised to transfer money to: Amy, Fitness Gym and William"
|
|
11
|
+
- utter: utter_flow_continue_interrupted
|
|
12
|
+
- utter: utter_ask_payee_name
|
|
13
|
+
- user: "Amy"
|
|
14
|
+
- utter: utter_ask_timing
|
|
15
|
+
- user: "/SetSlots(timing=now)"
|
|
16
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
17
|
+
- user: "I want to talk to a human"
|
|
18
|
+
- utter: utter_human_handoff_not_available
|
|
19
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
20
|
+
- user: "no"
|
|
21
|
+
- utter: utter_cancel_transfer
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
test_cases:
|
|
2
|
+
- test_case: conversation_repair_skipping_collect_step
|
|
3
|
+
steps:
|
|
4
|
+
- user: "I want to transfer 55 to Amy from savings right now"
|
|
5
|
+
- utter: utter_transfer_money_understand
|
|
6
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
7
|
+
- user: "sorry, I meant 65"
|
|
8
|
+
- utter: utter_corrected_previous_input
|
|
9
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
10
|
+
- user: "sorry, I meant in the future"
|
|
11
|
+
- utter: utter_corrected_previous_input
|
|
12
|
+
- utter: utter_ask_payment_date
|
|
13
|
+
- user: "12/12/2025"
|
|
14
|
+
- utter: utter_ask_confirm_future_payment
|
|
15
|
+
- user: "yes"
|
|
16
|
+
- utter: utter_payment_scheduled
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
test_cases:
|
|
2
|
+
- test_case: A simple test scripts used in standard demos for Starterpack - Financial Services (en)
|
|
3
|
+
steps:
|
|
4
|
+
- user: "I want to transfer money"
|
|
5
|
+
- utter: utter_transfer_money_understand
|
|
6
|
+
- bot: "Which account would you like to transfer money from?"
|
|
7
|
+
- user: "56789012"
|
|
8
|
+
- utter: utter_ask_payee_name
|
|
9
|
+
- user: "Susan"
|
|
10
|
+
- utter: utter_ask_amount
|
|
11
|
+
- user: "55.10"
|
|
12
|
+
- utter: utter_ask_timing
|
|
13
|
+
- user: "/SetSlots(timing=now)"
|
|
14
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
15
|
+
- user: "Yes"
|
|
16
|
+
- utter: utter_transfer_successful
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
test_cases:
|
|
2
|
+
- test_case: various_tests_for_account_balance
|
|
3
|
+
steps:
|
|
4
|
+
- user: "I want to view my account balance"
|
|
5
|
+
- bot: "Which account would you like the balance for?"
|
|
6
|
+
- user: "12345678"
|
|
7
|
+
- bot: "The balance is: $10123.45"
|
|
8
|
+
- user: "I want to query the balance of my acccounts"
|
|
9
|
+
- bot: "Which account would you like the balance for?"
|
|
10
|
+
- user: "12345678"
|
|
11
|
+
- bot: "The balance is: $10123.45"
|
|
12
|
+
- user: "I want to know the balance of one of my accounts"
|
|
13
|
+
- bot: "Which account would you like the balance for?"
|
|
14
|
+
- user: "23456789"
|
|
15
|
+
- bot: "The balance is: $4923.67"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
test_cases:
|
|
2
|
+
- test_case: banking_questions - Happy paths no 1
|
|
3
|
+
steps:
|
|
4
|
+
- user: "Are there any fees to transfer money to my friends?"
|
|
5
|
+
- bot: "Yes, there may be fees associated with transferring money, especially for international transfers. To avoid fees, consider using bank-to-bank transfers within the UK whenever possible. You will be notified of any applicable fees before confirming the transfer."
|
|
6
|
+
|
|
7
|
+
- test_case: banking_questions - Happy paths no 2
|
|
8
|
+
steps:
|
|
9
|
+
- user: "I have a question on prepaid card"
|
|
10
|
+
- utter: utter_help
|
|
11
|
+
- user: "are there fees to transfer from or to prepaid cards"
|
|
12
|
+
- bot: "Yes, there may be fees associated with transferring funds to or from prepaid cards. It is advisable to check your account details for specific charges related to these transactions."
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
test_cases:
|
|
2
|
+
- test_case: card_blocking - Happy paths no1
|
|
3
|
+
steps:
|
|
4
|
+
- user: "I want to block my card"
|
|
5
|
+
- utter: utter_block_card_understand
|
|
6
|
+
- bot: "Select the card you require assistance with:"
|
|
7
|
+
- user: "Wait, Wait, what will happen to my pre-authorized payments"
|
|
8
|
+
- bot: "When you block your card, any recurring payments linked to it will be interrupted until you update them with a new card number. You can request the merchants to cancel the hold on your pre-authorized payments if it is no longer necessary."
|
|
9
|
+
- bot: "Select the card you require assistance with:"
|
|
10
|
+
- user: "SetSlots(card_selection=3456789034567890)"
|
|
11
|
+
- utter: utter_ask_reason_for_blocking
|
|
12
|
+
- user: "/SetSlots(reason_for_blocking=lost)"
|
|
13
|
+
- utter: utter_acknowledge_reason_fraud_stolen_lost
|
|
14
|
+
- utter: utter_card_blocked
|
|
15
|
+
- utter: utter_ask_confirm_issue_new_card
|
|
16
|
+
- user: "/SetSlots(confirm_issue_new_card=true)"
|
|
17
|
+
- utter: utter_ask_address_confirmed
|
|
18
|
+
- user: "/SetSlots(address_confirmed=True)"
|
|
19
|
+
- utter: utter_confirm_physical_address
|
|
20
|
+
|
|
21
|
+
- test_case: card_blocking - Happy paths no2
|
|
22
|
+
steps:
|
|
23
|
+
- user: "I think I that I have lost my card"
|
|
24
|
+
- utter: utter_block_card_understand
|
|
25
|
+
- bot: "Select the card you require assistance with:"
|
|
26
|
+
- user: "SetSlots(card_selection=5555666677778888)"
|
|
27
|
+
- utter: utter_acknowledge_reason_fraud_stolen_lost
|
|
28
|
+
- utter: utter_card_blocked
|
|
29
|
+
- utter: utter_ask_confirm_issue_new_card
|
|
30
|
+
- user: "/SetSlots(confirm_issue_new_card=false)"
|
|
31
|
+
|
|
32
|
+
- test_case: card_blocking - Happy paths no3
|
|
33
|
+
steps:
|
|
34
|
+
- user: "I think I have lost my card"
|
|
35
|
+
- utter: utter_block_card_understand
|
|
36
|
+
- bot: "Select the card you require assistance with:"
|
|
37
|
+
- user: "SetSlots(card_selection=1111222233334444)"
|
|
38
|
+
- utter: utter_acknowledge_reason_fraud_stolen_lost
|
|
39
|
+
- utter: utter_card_blocked
|
|
40
|
+
- utter: utter_ask_confirm_issue_new_card
|
|
41
|
+
- user: "sorry, i selected the wrong card"
|
|
42
|
+
- utter: utter_corrected_previous_input
|
|
43
|
+
- bot: "Select the card you require assistance with:"
|
|
44
|
+
- user: "the second debit card"
|
|
45
|
+
- utter: utter_corrected_previous_input
|
|
46
|
+
- utter: utter_acknowledge_reason_fraud_stolen_lost
|
|
47
|
+
- utter: utter_card_blocked
|
|
48
|
+
- utter: utter_ask_confirm_issue_new_card
|
|
49
|
+
- user: "/SetSlots(confirm_issue_new_card=true)"
|
|
50
|
+
- utter: utter_ask_address_confirmed
|
|
51
|
+
- user: "yes"
|
|
52
|
+
- utter: utter_confirm_physical_address
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
test_cases:
|
|
2
|
+
- test_case: Money Transfer - Happy paths no1
|
|
3
|
+
steps:
|
|
4
|
+
- user: "I want to transfer money"
|
|
5
|
+
- utter: utter_transfer_money_understand
|
|
6
|
+
- bot: "Which account would you like to transfer money from?"
|
|
7
|
+
- user: "12345678"
|
|
8
|
+
- utter: utter_ask_payee_name
|
|
9
|
+
- user: "Robert"
|
|
10
|
+
- utter: utter_ask_amount
|
|
11
|
+
- user: "55"
|
|
12
|
+
- utter: utter_ask_timing
|
|
13
|
+
- user: "immediate"
|
|
14
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
15
|
+
- user: "Yes"
|
|
16
|
+
- utter: utter_transfer_successful
|
|
17
|
+
|
|
18
|
+
- test_case: Money Transfer - Happy paths no2
|
|
19
|
+
steps:
|
|
20
|
+
- user: "I want to transfer $55.55 to Amy from checking"
|
|
21
|
+
- utter: utter_transfer_money_understand
|
|
22
|
+
- utter: utter_ask_timing
|
|
23
|
+
- user: "/SetSlots(timing=now)"
|
|
24
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
25
|
+
- user: "yes"
|
|
26
|
+
- utter: utter_transfer_successful
|
|
27
|
+
|
|
28
|
+
- test_case: Money Transfer - Happy paths no3
|
|
29
|
+
steps:
|
|
30
|
+
- user: "I want to transfer $55.55 to Amy"
|
|
31
|
+
- utter: utter_transfer_money_understand
|
|
32
|
+
- bot: "Which account would you like to transfer money from?"
|
|
33
|
+
- user: "78901234"
|
|
34
|
+
- utter: utter_ask_timing
|
|
35
|
+
- user: "/SetSlots(timing=now)"
|
|
36
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
37
|
+
- user: "yes"
|
|
38
|
+
- utter: utter_transfer_successful
|
|
39
|
+
|
|
40
|
+
- test_case: Money Transfer - Happy paths no4
|
|
41
|
+
steps:
|
|
42
|
+
- user: "I would like to transfer $55.55 to Amy"
|
|
43
|
+
- utter: utter_transfer_money_understand
|
|
44
|
+
- bot: "Which account would you like to transfer money from?"
|
|
45
|
+
- user: "78901234"
|
|
46
|
+
- utter: utter_ask_timing
|
|
47
|
+
- user: "/SetSlots(timing=future)"
|
|
48
|
+
- utter: utter_ask_payment_date
|
|
49
|
+
- user: "12-12-2025"
|
|
50
|
+
- utter: utter_ask_confirm_future_payment
|
|
51
|
+
- user: "yes"
|
|
52
|
+
- utter: utter_payment_scheduled
|
|
53
|
+
|
|
54
|
+
- test_case: Money Transfer - Happy paths no5
|
|
55
|
+
steps:
|
|
56
|
+
- user: "I want to transfer $55.55 to Amy from checking"
|
|
57
|
+
- utter: utter_transfer_money_understand
|
|
58
|
+
- utter: utter_ask_timing
|
|
59
|
+
- user: "/SetSlots(timing=now)"
|
|
60
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
61
|
+
- user: "yes"
|
|
62
|
+
- utter: utter_transfer_successful
|
|
63
|
+
|
|
64
|
+
- test_case: Money Transfer - Happy paths no6
|
|
65
|
+
steps:
|
|
66
|
+
- user: "I want to transfer 55.55$ to Amy"
|
|
67
|
+
- utter: utter_transfer_money_understand
|
|
68
|
+
- bot: "Which account would you like to transfer money from?"
|
|
69
|
+
- user: "67890123"
|
|
70
|
+
- utter: utter_ask_timing
|
|
71
|
+
- user: "immediate"
|
|
72
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
73
|
+
- user: "yes"
|
|
74
|
+
- utter: utter_transfer_successful
|
|
75
|
+
|
|
76
|
+
- test_case: Money Transfer - Happy paths no7
|
|
77
|
+
steps:
|
|
78
|
+
- user: "I want to transfer $55.55 to Amy from checking right now"
|
|
79
|
+
- utter: utter_transfer_money_understand
|
|
80
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
81
|
+
- user: "yes"
|
|
82
|
+
- utter: utter_transfer_successful
|
|
83
|
+
|
|
84
|
+
- test_case: Money Transfer - Happy paths no8
|
|
85
|
+
steps:
|
|
86
|
+
- user: "I want to transfer 100.24$ from my savings to Amy right now"
|
|
87
|
+
- utter: utter_transfer_money_understand
|
|
88
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
89
|
+
- user: "yes"
|
|
90
|
+
- utter: utter_transfer_successful
|
|
91
|
+
|
|
92
|
+
- test_case: Money Transfer - Happy paths no9
|
|
93
|
+
steps:
|
|
94
|
+
- user: "I want to transfer money"
|
|
95
|
+
- utter: utter_transfer_money_understand
|
|
96
|
+
- bot: "Which account would you like to transfer money from?"
|
|
97
|
+
- user: "who are my payees"
|
|
98
|
+
- bot: "You are authorised to transfer money to: Robert, James and Food Market"
|
|
99
|
+
- utter: utter_flow_continue_interrupted
|
|
100
|
+
- bot: "Which account would you like to transfer money from?"
|
|
101
|
+
- user: "I would like to add Timmy as a payee"
|
|
102
|
+
- utter: utter_ask_account_number
|
|
103
|
+
- user: "56567"
|
|
104
|
+
- utter: utter_ask_payee_type
|
|
105
|
+
- user: "/SetSlots(payee_type=person)"
|
|
106
|
+
- utter: utter_ask_reference
|
|
107
|
+
- user: "Facebook Marketplace"
|
|
108
|
+
- utter: utter_ask_confirm_payee_details
|
|
109
|
+
- user: "/SetSlots(confirm_payee_details=True)"
|
|
110
|
+
- utter: utter_payee_added_success
|
|
111
|
+
- utter: utter_flow_continue_interrupted
|
|
112
|
+
- bot: "Which account would you like to transfer money from?"
|
|
113
|
+
- user: "12345678"
|
|
114
|
+
- utter: utter_ask_amount
|
|
115
|
+
- user: "$40.67"
|
|
116
|
+
- utter: utter_ask_timing
|
|
117
|
+
- user: "/SetSlots(timing=now)"
|
|
118
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
119
|
+
- user: "yup"
|
|
120
|
+
- utter: utter_transfer_successful
|
|
121
|
+
|
|
122
|
+
- test_case: Money Transfer - Happy paths no10
|
|
123
|
+
steps:
|
|
124
|
+
- user: "I want to transfer 55 to Amy from savings right now"
|
|
125
|
+
- utter: utter_transfer_money_understand
|
|
126
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
127
|
+
- user: "sorry I meant 65"
|
|
128
|
+
- utter: utter_corrected_previous_input
|
|
129
|
+
- utter: utter_ask_confirm_immediate_payment
|
|
130
|
+
- user: "sorry I meant in the future"
|
|
131
|
+
- utter: utter_corrected_previous_input
|
|
132
|
+
- utter: utter_ask_payment_date
|
|
133
|
+
- user: "12/12/2025"
|
|
134
|
+
- utter: utter_ask_confirm_future_payment
|
|
135
|
+
- user: "Yes"
|
|
136
|
+
- utter: utter_payment_scheduled
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
test_cases:
|
|
2
|
+
- test_case: payee_management - Happy paths no1
|
|
3
|
+
steps:
|
|
4
|
+
- user: "who are my payees"
|
|
5
|
+
- bot: "You are authorised to transfer money to: Robert, James and Food Market"
|
|
6
|
+
|
|
7
|
+
- test_case: payee_management - Happy paths no2
|
|
8
|
+
steps:
|
|
9
|
+
- user: "I want to add a payee"
|
|
10
|
+
- utter: utter_ask_payee_name
|
|
11
|
+
- user: "Sonia Smith"
|
|
12
|
+
- utter: utter_ask_account_number
|
|
13
|
+
- user: "123456"
|
|
14
|
+
- utter: utter_ask_payee_type
|
|
15
|
+
- user: "person"
|
|
16
|
+
- utter: utter_ask_reference
|
|
17
|
+
- user: "Facebook Marketplace"
|
|
18
|
+
- utter: utter_ask_confirm_payee_details
|
|
19
|
+
- user: "/SetSlots(confirm_payee_details=True)"
|
|
20
|
+
- utter: utter_payee_added_success
|
|
21
|
+
|
|
22
|
+
- test_case: payee_management - Happy paths no3
|
|
23
|
+
steps:
|
|
24
|
+
- user: "who are my payees"
|
|
25
|
+
- bot: "You are authorised to transfer money to: Robert, James and Food Market"
|
|
26
|
+
- user: "I want to remove a payee"
|
|
27
|
+
- utter: utter_ask_rephrase
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import csv
|
|
1
2
|
import logging
|
|
2
3
|
from datetime import datetime
|
|
3
4
|
|
|
4
|
-
import pandas as pd
|
|
5
5
|
from rasa_sdk import Action
|
|
6
6
|
from rasa_sdk.events import SlotSet
|
|
7
7
|
|
|
@@ -29,17 +29,11 @@ class ActionVerifyBillByDate(Action):
|
|
|
29
29
|
return "Invalid format. Please use a full month name (e.g., 'March')."
|
|
30
30
|
|
|
31
31
|
def run(self, dispatcher, tracker, domain):
|
|
32
|
-
# Load CSV file with billing data
|
|
33
|
-
df = pd.read_csv("csvs/billing.csv")
|
|
34
|
-
|
|
35
32
|
# Get customer ID and date from slots
|
|
36
33
|
customer_id = tracker.get_slot("customer_id")
|
|
37
34
|
bill_month = tracker.get_slot("bill_month")
|
|
38
|
-
# logging.info(f"This is an info message: bill_month : {bill_month}")
|
|
39
35
|
|
|
40
36
|
bill_date = ActionVerifyBillByDate.text_to_date(bill_month)
|
|
41
|
-
# logging.info(f"This is an info message: bill_month after
|
|
42
|
-
# transformation: {bill_date}")
|
|
43
37
|
|
|
44
38
|
if not customer_id:
|
|
45
39
|
dispatcher.utter_message(
|
|
@@ -53,37 +47,69 @@ class ActionVerifyBillByDate(Action):
|
|
|
53
47
|
)
|
|
54
48
|
return []
|
|
55
49
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
50
|
+
try:
|
|
51
|
+
# Load CSV file with billing data
|
|
52
|
+
with open("csvs/billing.csv", "r", newline="") as csvfile:
|
|
53
|
+
reader = csv.DictReader(csvfile)
|
|
54
|
+
|
|
55
|
+
# Convert bill_date to datetime for comparison
|
|
56
|
+
bill_date_obj = datetime.strptime(bill_date, "%d/%m/%Y")
|
|
57
|
+
|
|
58
|
+
# Filter data for the given customer and date
|
|
59
|
+
customer_bills = []
|
|
60
|
+
specific_bill = None
|
|
61
|
+
|
|
62
|
+
for row in reader:
|
|
63
|
+
if row["customer_id"] == str(customer_id):
|
|
64
|
+
# Parse the date from CSV
|
|
65
|
+
row_date = datetime.strptime(row["date"], "%Y-%m-%d")
|
|
66
|
+
row["amount"] = float(row["amount"])
|
|
67
|
+
customer_bills.append(row)
|
|
68
|
+
|
|
69
|
+
# Check if this is the specific bill we're looking for
|
|
70
|
+
if row_date.date() == bill_date_obj.date():
|
|
71
|
+
specific_bill = row
|
|
72
|
+
|
|
73
|
+
if specific_bill is None:
|
|
74
|
+
dispatcher.utter_message(
|
|
75
|
+
f"No bill found for {bill_date_obj.date()}."
|
|
76
|
+
)
|
|
77
|
+
return []
|
|
78
|
+
|
|
79
|
+
bill_amount = specific_bill["amount"]
|
|
80
|
+
|
|
81
|
+
# Calculate average
|
|
82
|
+
if customer_bills:
|
|
83
|
+
average_bill = sum(bill["amount"] for bill in customer_bills) / len(
|
|
84
|
+
customer_bills
|
|
85
|
+
)
|
|
86
|
+
else:
|
|
87
|
+
average_bill = 0
|
|
88
|
+
|
|
89
|
+
difference = bill_amount - average_bill
|
|
90
|
+
|
|
91
|
+
# Generate response
|
|
92
|
+
response = (
|
|
93
|
+
f"Your bill for {bill_month} {bill_date_obj.date().year} is "
|
|
94
|
+
f"${bill_amount:.2f}. \n"
|
|
95
|
+
f"The average of your past bills is ${average_bill:.2f}. \n"
|
|
96
|
+
f"This bill is {'higher' if difference > 0 else 'lower'} than "
|
|
97
|
+
f"your average by ${abs(difference):.2f}."
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
dispatcher.utter_message(response)
|
|
101
|
+
return [
|
|
102
|
+
SlotSet("bill_amount", int(bill_amount)),
|
|
103
|
+
SlotSet("average_bill", int(average_bill)),
|
|
104
|
+
SlotSet("difference", int(difference)),
|
|
105
|
+
]
|
|
106
|
+
|
|
107
|
+
except FileNotFoundError:
|
|
108
|
+
dispatcher.utter_message("Billing data file not found.")
|
|
109
|
+
return []
|
|
110
|
+
except Exception:
|
|
111
|
+
dispatcher.utter_message("Error retrieving billing information.")
|
|
66
112
|
return []
|
|
67
|
-
|
|
68
|
-
bill_amount = specific_bill.iloc[0]["amount"]
|
|
69
|
-
average_bill = customer_bills["amount"].mean()
|
|
70
|
-
difference = bill_amount - average_bill
|
|
71
|
-
|
|
72
|
-
# Generate response
|
|
73
|
-
response = (
|
|
74
|
-
f"Your bill for {bill_month} {bill_date.date().year} is "
|
|
75
|
-
f"${bill_amount:.2f}. \n"
|
|
76
|
-
f"The average of your past bills is ${average_bill:.2f}. \n"
|
|
77
|
-
f"This bill is {'higher' if difference > 0 else 'lower'} than "
|
|
78
|
-
f"your average by ${abs(difference):.2f}."
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
dispatcher.utter_message(response)
|
|
82
|
-
return [
|
|
83
|
-
SlotSet("bill_amount", int(bill_amount)),
|
|
84
|
-
SlotSet("average_bill", int(average_bill)),
|
|
85
|
-
SlotSet("difference", int(difference)),
|
|
86
|
-
]
|
|
87
113
|
|
|
88
114
|
|
|
89
115
|
class ActionRecapBill(Action):
|
|
@@ -91,21 +117,11 @@ class ActionRecapBill(Action):
|
|
|
91
117
|
return "action_recap_bill"
|
|
92
118
|
|
|
93
119
|
def run(self, dispatcher, tracker, domain):
|
|
94
|
-
# Path to the CSV file (Update path if necessary)
|
|
95
|
-
csv_path = "csvs/billing.csv"
|
|
96
|
-
|
|
97
|
-
# Read the CSV
|
|
98
|
-
df = pd.read_csv(csv_path)
|
|
99
|
-
# this can be shown in the logs of your custom action, if you want
|
|
100
|
-
# the message to be displayed to the user use 'dispatcher.utter_message'
|
|
101
|
-
print(df)
|
|
102
120
|
# Get customer_id and bill_date from slots
|
|
103
121
|
customer_id = tracker.get_slot("customer_id")
|
|
104
122
|
bill_month = tracker.get_slot("bill_month")
|
|
105
|
-
|
|
106
|
-
df["date"] = pd.to_datetime(df["date"])
|
|
123
|
+
|
|
107
124
|
bill_date = ActionVerifyBillByDate.text_to_date(bill_month)
|
|
108
|
-
bill_date = pd.to_datetime(bill_date)
|
|
109
125
|
|
|
110
126
|
if not customer_id:
|
|
111
127
|
dispatcher.utter_message(
|
|
@@ -126,26 +142,55 @@ class ActionRecapBill(Action):
|
|
|
126
142
|
dispatcher.utter_message("Invalid customer ID format.")
|
|
127
143
|
return []
|
|
128
144
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
145
|
+
try:
|
|
146
|
+
# Load CSV file
|
|
147
|
+
with open("csvs/billing.csv", "r", newline="") as csvfile:
|
|
148
|
+
reader = csv.DictReader(csvfile)
|
|
149
|
+
|
|
150
|
+
bill_date_obj = datetime.strptime(bill_date, "%d/%m/%Y")
|
|
151
|
+
|
|
152
|
+
# Filter records for the given customer_id
|
|
153
|
+
filtered_records = []
|
|
154
|
+
for row in reader:
|
|
155
|
+
if row["customer_id"] == str(customer_id):
|
|
156
|
+
# Parse date and add to filtered records
|
|
157
|
+
row_date = datetime.strptime(row["date"], "%Y-%m-%d")
|
|
158
|
+
filtered_records.append(
|
|
159
|
+
{
|
|
160
|
+
"date": row_date,
|
|
161
|
+
"amount": float(row["amount"]),
|
|
162
|
+
"source": row["source"],
|
|
163
|
+
}
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
if not filtered_records:
|
|
167
|
+
dispatcher.utter_message(
|
|
168
|
+
f"No transactions found for customer {customer_id} on "
|
|
169
|
+
f"{bill_date_obj.date().strftime('%B %Y')}."
|
|
170
|
+
)
|
|
171
|
+
return []
|
|
172
|
+
|
|
173
|
+
# Format the output
|
|
174
|
+
response1 = "Here is a summary of your costs :"
|
|
175
|
+
dispatcher.utter_message(response1)
|
|
176
|
+
response = "\n".join(
|
|
177
|
+
[
|
|
178
|
+
(
|
|
179
|
+
f"{record['date'].date()} | {record['amount']} $ "
|
|
180
|
+
f"| {record['source']}"
|
|
181
|
+
)
|
|
182
|
+
for record in filtered_records
|
|
183
|
+
]
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
# Send response to user
|
|
187
|
+
dispatcher.utter_message(response)
|
|
188
|
+
print("response heeere", response)
|
|
189
|
+
return []
|
|
190
|
+
|
|
191
|
+
except FileNotFoundError:
|
|
192
|
+
dispatcher.utter_message("Billing data file not found.")
|
|
193
|
+
return []
|
|
194
|
+
except Exception:
|
|
195
|
+
dispatcher.utter_message("Error retrieving billing information.")
|
|
137
196
|
return []
|
|
138
|
-
|
|
139
|
-
# Format the output
|
|
140
|
-
response1 = "Here is a summary of your costs :"
|
|
141
|
-
dispatcher.utter_message(response1)
|
|
142
|
-
response = "\n".join(
|
|
143
|
-
[
|
|
144
|
-
f"{row['date'].date()} | {row['amount']} $ | {row['source']}"
|
|
145
|
-
for _, row in filtered_df.iterrows()
|
|
146
|
-
]
|
|
147
|
-
)
|
|
148
|
-
# Send response to user
|
|
149
|
-
dispatcher.utter_message(response)
|
|
150
|
-
print("response heeere", response)
|
|
151
|
-
return []
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import csv
|
|
2
|
+
|
|
2
3
|
from rasa_sdk import Action
|
|
3
4
|
from rasa_sdk.events import SlotSet
|
|
4
5
|
|
|
@@ -10,18 +11,32 @@ class ActionGetCustomerInfo(Action):
|
|
|
10
11
|
def run(self, dispatcher, tracker, domain):
|
|
11
12
|
# Load CSV file
|
|
12
13
|
file_path = "csvs/customers.csv" # get information from your DBs
|
|
13
|
-
df = pd.read_csv(file_path)
|
|
14
14
|
customer_id = tracker.get_slot("customer_id")
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
try:
|
|
17
|
+
with open(file_path, "r", newline="") as csvfile:
|
|
18
|
+
reader = csv.DictReader(csvfile)
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
# Filter data for the given customer ID
|
|
21
|
+
customer_info = None
|
|
22
|
+
for row in reader:
|
|
23
|
+
if row["customer_id"] == str(customer_id):
|
|
24
|
+
customer_info = row
|
|
25
|
+
break
|
|
26
|
+
|
|
27
|
+
if customer_info is None:
|
|
28
|
+
dispatcher.utter_message("No customer found with this ID.")
|
|
29
|
+
return []
|
|
22
30
|
|
|
23
|
-
|
|
24
|
-
|
|
31
|
+
# Extract customer details
|
|
32
|
+
first_name = customer_info["first_name"]
|
|
25
33
|
|
|
26
|
-
|
|
27
|
-
|
|
34
|
+
# Set the retrieved name in a slot
|
|
35
|
+
return [SlotSet("customer_first_name", first_name)]
|
|
36
|
+
|
|
37
|
+
except FileNotFoundError:
|
|
38
|
+
dispatcher.utter_message("Customer database file not found.")
|
|
39
|
+
return []
|
|
40
|
+
except Exception:
|
|
41
|
+
dispatcher.utter_message("Error retrieving customer information.")
|
|
42
|
+
return []
|
|
@@ -794,7 +794,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
794
794
|
)
|
|
795
795
|
print_error_and_exit(error_message)
|
|
796
796
|
|
|
797
|
-
docs = glob.glob(os.path.join(docs_folder, "
|
|
797
|
+
docs = glob.glob(os.path.join(docs_folder, "**/*.txt"), recursive=True)
|
|
798
798
|
if not docs or len(docs) < 1:
|
|
799
799
|
error_message = (
|
|
800
800
|
f"Document source directory is empty: '{docs_folder}'. "
|
|
@@ -219,11 +219,6 @@ class FlowRetrieval(EmbeddingsHealthCheckMixin):
|
|
|
219
219
|
if self.vector_store is not None:
|
|
220
220
|
with self._model_storage.write_to(self._resource) as model_path:
|
|
221
221
|
self.vector_store.save_local(model_path)
|
|
222
|
-
else:
|
|
223
|
-
structlogger.warning(
|
|
224
|
-
"flow_retrieval.persist_vector_store.not_initialized",
|
|
225
|
-
event_info="Vector store is None, not persisted.",
|
|
226
|
-
)
|
|
227
222
|
|
|
228
223
|
def _persist_config(self) -> None:
|
|
229
224
|
with self._model_storage.write_to(self._resource) as path:
|
|
@@ -249,6 +244,16 @@ class FlowRetrieval(EmbeddingsHealthCheckMixin):
|
|
|
249
244
|
)
|
|
250
245
|
|
|
251
246
|
flows_to_embedd = flows.exclude_link_only_flows()
|
|
247
|
+
|
|
248
|
+
if not flows_to_embedd:
|
|
249
|
+
structlogger.debug(
|
|
250
|
+
"flow_retrieval.populate_vector_store.no_flows_to_embed",
|
|
251
|
+
event_info=(
|
|
252
|
+
"No flows to embed in the vector store, skipping population."
|
|
253
|
+
),
|
|
254
|
+
)
|
|
255
|
+
return
|
|
256
|
+
|
|
252
257
|
embeddings = self._create_embedder(self.config)
|
|
253
258
|
documents = self._generate_flow_documents(flows_to_embedd, domain)
|
|
254
259
|
try:
|
|
@@ -420,10 +425,6 @@ class FlowRetrieval(EmbeddingsHealthCheckMixin):
|
|
|
420
425
|
The top k documents with similarity scores.
|
|
421
426
|
"""
|
|
422
427
|
if self.vector_store is None:
|
|
423
|
-
structlogger.error(
|
|
424
|
-
"flow_retrieval.query_vector_store.vector_store_not_configured",
|
|
425
|
-
event_info="Vector store is not configured",
|
|
426
|
-
)
|
|
427
428
|
return []
|
|
428
429
|
try:
|
|
429
430
|
documents_with_scores = (
|
rasa/version.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: rasa-pro
|
|
3
|
-
Version: 3.13.
|
|
3
|
+
Version: 3.13.1a7
|
|
4
4
|
Summary: State-of-the-art open-core Conversational AI framework for Enterprises that natively leverages generative AI for effortless assistant development.
|
|
5
5
|
Keywords: nlp,machine-learning,machine-learning-library,bot,bots,botkit,rasa conversational-agents,conversational-ai,chatbot,chatbot-framework,bot-framework
|
|
6
6
|
Author: Rasa Technologies GmbH
|
|
@@ -85,7 +85,7 @@ rasa/cli/project_templates/finance/actions/action_schedule_payment.py,sha256=DRX
|
|
|
85
85
|
rasa/cli/project_templates/finance/actions/action_session_start.py,sha256=Pp6AHDNMxiocGGfGRS5g9Ls_tP2GV4KgKkzdvyNRe8Y,2398
|
|
86
86
|
rasa/cli/project_templates/finance/actions/action_update_card_status.py,sha256=5uIWwyjy1LhNA7jP8Qr43t4sPsEBfzAMXWVatEQEVTM,1482
|
|
87
87
|
rasa/cli/project_templates/finance/actions/action_validate_payment_date.py,sha256=7591cJicv4SukK4Xwf-GsHFJ9GyPA0lqIeWVPeyQcaw,1230
|
|
88
|
-
rasa/cli/project_templates/finance/actions/database.py,sha256=
|
|
88
|
+
rasa/cli/project_templates/finance/actions/database.py,sha256=JDLWzYs9BocjxJ345GCXrUwwd-IHe3glfjtwbcfV06I,9955
|
|
89
89
|
rasa/cli/project_templates/finance/config.yml,sha256=6G3gaVEGYszM71a_lShgxV334Awcclw7vOEcyBr1q9c,790
|
|
90
90
|
rasa/cli/project_templates/finance/credentials.yml,sha256=h_hZQaVP_GqG58xAbXtQ0uOD5J63M-my0__nvyBLYF0,1014
|
|
91
91
|
rasa/cli/project_templates/finance/csvs/accounts.csv,sha256=DcFXLw_ji2cO8uXxGTycvCiGY0WEpS8gGXA9dpVE7PI,470
|
|
@@ -210,15 +210,30 @@ rasa/cli/project_templates/finance/domain/transfer_money.yml,sha256=RUyNU3qiJBk5
|
|
|
210
210
|
rasa/cli/project_templates/finance/endpoints.yml,sha256=ltcxb1Cj2S4BFRVtzIfW1eyd4WBgMPoe3DrNphleUcw,2115
|
|
211
211
|
rasa/cli/project_templates/finance/prompts/command-generator.jinja2,sha256=3_vP1QthoteyHZpdGgc2Rz0Nd7PTHvH3lxbBz2WD3HQ,3529
|
|
212
212
|
rasa/cli/project_templates/finance/prompts/rephraser_demo_personality_prompt.jinja2,sha256=ZVlS0Cc-jTfWjbL4_Pi3_7cH6TbbMurdG519ECSE53s,707
|
|
213
|
-
rasa/cli/project_templates/finance/
|
|
213
|
+
rasa/cli/project_templates/finance/tests/conversation_repair/cancellations.yml,sha256=KF6p7c2NfEHYRxbNxf8mac0-L1Cq3qF1QmQGWSltYgM,477
|
|
214
|
+
rasa/cli/project_templates/finance/tests/conversation_repair/cannot_handle.yml,sha256=zwlynIt5ChHza4Kt4dxP4kXT_Kp-atjLYwAb7GAQsnE,197
|
|
215
|
+
rasa/cli/project_templates/finance/tests/conversation_repair/chitchat.yml,sha256=9jRIFd0hO6f4XYLrBSeLH4uTZm9DzxT7KpoCqqY7XdM,441
|
|
216
|
+
rasa/cli/project_templates/finance/tests/conversation_repair/clarification.yml,sha256=Sti3D7vZUsx7PJka2TBOxVu1WU3_GYrZkTnZPICt76Q,296
|
|
217
|
+
rasa/cli/project_templates/finance/tests/conversation_repair/completion.yml,sha256=n5ZfVPuxyOwXyqzuY2a1vck6Dg9qLZnKS0K3skswsz8,636
|
|
218
|
+
rasa/cli/project_templates/finance/tests/conversation_repair/corrections.yml,sha256=g52IPCSmpaKtWNao3tFFLNILmEQYbIVBRmDnsiQFv-0,676
|
|
219
|
+
rasa/cli/project_templates/finance/tests/conversation_repair/digressions.yml,sha256=fhfKuSej2MUoEtOVmhaA3iOwCJDK9ww3wfxz_9V2VyY,1240
|
|
220
|
+
rasa/cli/project_templates/finance/tests/conversation_repair/human_handoff.yml,sha256=7HIA6pVcIMws1AajwPqoYp10GDcTiLQhDe-hanGiAD8,764
|
|
221
|
+
rasa/cli/project_templates/finance/tests/conversation_repair/skipping_collect_steps.yml,sha256=L2Oa-aptctOpGYLtyXzjq4-PYNxptKCg8yAPlX9QPsA,614
|
|
222
|
+
rasa/cli/project_templates/finance/tests/demo_scripts/main.yml,sha256=SZfBe8EdEkJFRpaoE8VALSRi7lmV_xicU-ugG2SkpCc,574
|
|
223
|
+
rasa/cli/project_templates/finance/tests/happy_paths/balance_verification.yml,sha256=19OhXzHIqMRkGC6Oqf9HsolUojGDgO-A4UPhMltTQIU,603
|
|
224
|
+
rasa/cli/project_templates/finance/tests/happy_paths/banking_questions.yml,sha256=8o8q9T8FNj1Llns50RbJL224JFtD8j50i8971JEtqaY,812
|
|
225
|
+
rasa/cli/project_templates/finance/tests/happy_paths/card_blocking.yml,sha256=lnwiqvzVp5im6fsWlINBca3r3z_jF_eZuxCU2DZae4U,2419
|
|
226
|
+
rasa/cli/project_templates/finance/tests/happy_paths/money_transfer.yml,sha256=is5nKqzLs8EU2_SebnHiQ6i-RGfz2oAgnjtPq8Yppxg,4818
|
|
227
|
+
rasa/cli/project_templates/finance/tests/happy_paths/payee_management.yml,sha256=JtAgVO0-qvbuVELpKPDV64HG8TEkIIz8S5we37A1J-g,914
|
|
228
|
+
rasa/cli/project_templates/finance/tests/happy_paths/user_greeted.yml,sha256=op9TrCV_0E1xfMelNvx9bWP1xPtKDQeAbtD-EXSPEq8,126
|
|
214
229
|
rasa/cli/project_templates/plain/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
215
230
|
rasa/cli/project_templates/plain/config.yml,sha256=bmJ5X9nnuD2knwClniM9EFh11wstAbVvMvFR7nv-U2g,390
|
|
216
231
|
rasa/cli/project_templates/plain/credentials.yml,sha256=h_hZQaVP_GqG58xAbXtQ0uOD5J63M-my0__nvyBLYF0,1014
|
|
217
232
|
rasa/cli/project_templates/plain/data/patterns/pattern_session_start.yml,sha256=m7Kyo738_25JeGM_HbvjOrNMQXCdGpaSlSVCicD1S28,175
|
|
218
|
-
rasa/cli/project_templates/plain/domain.yml,sha256=
|
|
233
|
+
rasa/cli/project_templates/plain/domain.yml,sha256=6Jm8AbB3LD2KBWPKfpiW03sSFBCEW9iJfLw3Zx3msAs,171
|
|
219
234
|
rasa/cli/project_templates/plain/endpoints.yml,sha256=YHMIzpxM7xyfhNOQLpZs1V-RgQvRdR8uc2SZsnKZDxg,1999
|
|
220
|
-
rasa/cli/project_templates/telco/actions/actions_billing.py,sha256=
|
|
221
|
-
rasa/cli/project_templates/telco/actions/actions_get_data_from_db.py,sha256=
|
|
235
|
+
rasa/cli/project_templates/telco/actions/actions_billing.py,sha256=ug75b3shRrYXE1j7SDDJpe9xLx3Vo9QQ1Hku_10-NlY,7152
|
|
236
|
+
rasa/cli/project_templates/telco/actions/actions_get_data_from_db.py,sha256=4stTMHLLOMYhzYAqHxoneedg2xOeaiO0Fi5sQZJc5Sw,1401
|
|
222
237
|
rasa/cli/project_templates/telco/actions/actions_run_diagnostics.py,sha256=V1QqtTPZTWlkqExOqmLBqvzm-yIPPx-T9pc950SLvdk,739
|
|
223
238
|
rasa/cli/project_templates/telco/actions/actions_session_start.py,sha256=j14ItwzwQt_qQcEAcDD1Xh_MxKXTCI0v3bP0q2RjyjY,309
|
|
224
239
|
rasa/cli/project_templates/telco/config.yml,sha256=W52rQO0RxWLarRcZXtdT8RdAuWxxkQ0zio1XKiw9HTQ,577
|
|
@@ -522,7 +537,7 @@ rasa/core/nlg/translate.py,sha256=PBMTbIgdkhx8rhzqv6h0u5r9jqdfiVIh7u0qb363sJA,18
|
|
|
522
537
|
rasa/core/persistor.py,sha256=7LCZHAwCM-xrUI38aaJ5dkxJvLdJXWI1TEUKsBo4_EE,21295
|
|
523
538
|
rasa/core/policies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
524
539
|
rasa/core/policies/ensemble.py,sha256=XoHxU0jcb_io_LBOpjJffylzqtGEB7CH9ivhRyO8pDc,12960
|
|
525
|
-
rasa/core/policies/enterprise_search_policy.py,sha256=
|
|
540
|
+
rasa/core/policies/enterprise_search_policy.py,sha256=6o4KiqK_r6nNR5nJEltc0MSXemJcGqV2Dli6bxtCd2U,46872
|
|
526
541
|
rasa/core/policies/enterprise_search_policy_config.py,sha256=rTIGBrfGfe_lvsYQW1cU20tza07p_-oxFfjXhw7-phc,8644
|
|
527
542
|
rasa/core/policies/enterprise_search_prompt_template.jinja2,sha256=dCS_seyBGxMQoMsOjjvPp0dd31OSzZCJSZeev1FJK5Q,1187
|
|
528
543
|
rasa/core/policies/enterprise_search_prompt_with_citation_template.jinja2,sha256=va9rpP97dN3PKoJZOVfyuISt3cPBlb10Pqyz25RwO_Q,3294
|
|
@@ -603,7 +618,7 @@ rasa/dialogue_understanding/generator/command_parser.py,sha256=gI_VGsD4aJOQmIVlU
|
|
|
603
618
|
rasa/dialogue_understanding/generator/command_parser_validator.py,sha256=qUIaKBRhH6Q-BGOELJLRvgv3gwUf75el-kw7p0v7eWI,2293
|
|
604
619
|
rasa/dialogue_understanding/generator/constants.py,sha256=ulqmLIwrBOZLyhsCChI_4CdOnA0I8MfuBxxuKGyFp7U,1130
|
|
605
620
|
rasa/dialogue_understanding/generator/flow_document_template.jinja2,sha256=f4H6vVd-_nX_RtutMh1xD3ZQE_J2OyuPHAtiltfiAPY,253
|
|
606
|
-
rasa/dialogue_understanding/generator/flow_retrieval.py,sha256=
|
|
621
|
+
rasa/dialogue_understanding/generator/flow_retrieval.py,sha256=TF0QEM7q8KpyDYIJDu0Ym6K-ObjCOw4EEUbGXdpgPvY,17732
|
|
607
622
|
rasa/dialogue_understanding/generator/llm_based_command_generator.py,sha256=dori1F756kxOv-VkYetGPnacTsoTYHIUt1mTqt050Qs,23585
|
|
608
623
|
rasa/dialogue_understanding/generator/llm_command_generator.py,sha256=z7jhIJ3W_5GFH-p15kVoWbigMIoY8fIJjc_j_uX7yxw,2581
|
|
609
624
|
rasa/dialogue_understanding/generator/multi_step/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -1049,9 +1064,9 @@ rasa/utils/train_utils.py,sha256=ClJx-6x3-h3Vt6mskacgkcCUJTMXjFPe3zAcy_DfmaU,212
|
|
|
1049
1064
|
rasa/utils/url_tools.py,sha256=dZ1HGkVdWTJB7zYEdwoDIrEuyX9HE5WsxKKFVsXBLE0,1218
|
|
1050
1065
|
rasa/utils/yaml.py,sha256=KjbZq5C94ZP7Jdsw8bYYF7HASI6K4-C_kdHfrnPLpSI,2000
|
|
1051
1066
|
rasa/validator.py,sha256=IRhLfcgCpps0wSpokOvUGNaY8t8GsmeSmPOUVRKeOeE,83087
|
|
1052
|
-
rasa/version.py,sha256=
|
|
1053
|
-
rasa_pro-3.13.
|
|
1054
|
-
rasa_pro-3.13.
|
|
1055
|
-
rasa_pro-3.13.
|
|
1056
|
-
rasa_pro-3.13.
|
|
1057
|
-
rasa_pro-3.13.
|
|
1067
|
+
rasa/version.py,sha256=qitZXgzJBInAXqPOwijzZnTrGa3eqY_mwDrUjpKlN2Y,119
|
|
1068
|
+
rasa_pro-3.13.1a7.dist-info/METADATA,sha256=BAkRjK-q3FhiOCcKpvYqkth6g1cQxxncve2JTVYMW_Y,10555
|
|
1069
|
+
rasa_pro-3.13.1a7.dist-info/NOTICE,sha256=7HlBoMHJY9CL2GlYSfTQ-PZsVmLmVkYmMiPlTjhuCqA,218
|
|
1070
|
+
rasa_pro-3.13.1a7.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
1071
|
+
rasa_pro-3.13.1a7.dist-info/entry_points.txt,sha256=ckJ2SfEyTPgBqj_I6vm_tqY9dZF_LAPJZA335Xp0Q9U,43
|
|
1072
|
+
rasa_pro-3.13.1a7.dist-info/RECORD,,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
pandas>=1.5.0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|