Spaces:
Runtime error
Runtime error
File size: 6,627 Bytes
fe6855c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | import requests
import json
from app.models.request_type_model import RequestTypeModel
from config import settings
MODEL_NAME = settings.settings.MODEL_NAME # e.g., "tiiuae/falcon-7b-instruct"
HF_TOKEN = settings.settings.HUGGINGFACE_API_TOKEN # Hugging Face token
if not HF_TOKEN or HF_TOKEN == "YOUR_HUGGINGFACE_API_TOKEN":
print("Error: Hugging Face API token is missing. Please ensure you have a valid config.")
exit()
API_URL = f"https://router.huggingface.co/hf-inference/models/{MODEL_NAME}/v1/chat/completions"
HEADERS = {"Authorization": f"Bearer {HF_TOKEN}"}
PROMPT_OBJECTIVE_CLASSIFICATION_RULES = """
### Task: Email Classification
#### **Objective:**
Analyze the given email and classify it into the most appropriate **Request Type** and **Sub Request Type** based on its primary intent.
#### **Instructions:**
- Identify the key intent of the email.
- Match it with one of the **Request Types** from the predefined categories.
- Select the most relevant **Sub Request Type** for the classification.
- If no exact match is found, choose the closest category.
Only return a JSON object with the classification results.
"""
PROMPT_CATEGORIES = f"""
#### **Classification Categories & Definitions:**
{json.dumps(RequestTypeModel.requests_datasets, indent=2)}
"""
PROMPT_OUTPUT_FORMAT = """
#### **Output Format:**
Return the classification result in **pure JSON format** (without extra text or markdown).
Example Output:
{
"request_type": "Commitment Change",
"sub_request_type": "Increase",
"confidence_score": 0.95,
"email_subject": "Request for Credit Line Increase"
}
"""
PROMPT_TEMPLATE = """
### Task: Email Classification
#### **Objective:**
Analyze the given email and classify it into the most appropriate **Request Type** and **Sub Request Type** based on its primary intent. Ensure the response is strictly in JSON format with the specified fields.
#### **Classification Categories:**
Each email must be categorized under one of the following **Request Types** and corresponding **Sub Request Types**:
| Request Type | Sub Request Type |
|---------------------------|------------------------------------------------------|
| Adjustment | N/A |
| AU Transfer | N/A |
| Closing Notice | Reallocation Fees, Amendment Fees, Reallocation Principal |
| Commitment Change | Cashless Roll, Decrease, Increase |
| Fee Payment | Ongoing Fee, Letter of Credit Fee |
| Money Movement - Inbound | Principal, Interest, Principal + Interest, Principal + Interest + Fee |
| Money Movement - Outbound | Timebound, Foreign Currency |
#### **Output Format:**
Return the classification result strictly in **JSON format** with the following fields:
```json
{
"request_type": "Request Type",
"sub_request_type": "Sub Request Type",
"confidence_score": Confidence Score (between 0 and 1),
"email_subject": "Email Subject"
}
### **🔹 Email for Classification:**
```email
{{
QQA Bank, N.A.
Loan Agency Services
Date: 05-Feb-2025
TO: ABC BANK, NATIONAL ASSOCIATION
ATTN: RAMAKRISHNA KUNCHALA
Fax: 877-606-9426
Re: ABB MID-ATLANTIC LLC $171.3MM 11-4-2022, TERM LOAN A-2
Description: Facility Lender Share Adjustment
BORROWER: ABB MID-ATLANTIC LIC
DEAL NAME: ABB MID-ATLANTIC LIC $171. 3MM 11-4-2022
Effective 04-Feb-2025, the Lender Shares of facility TERM LOAN A-2 have been adjusted.
Your share of the commitment was USD 5,518,249.19. It has been Increased to USD 5,542,963.55.
For: ABC BANK, NA
Reference: ABIB MID-ATLANTIC LIC $171.3MM 11-4-2022,
If you have any questions, please call the undersigned.
********************************************COMMENT***************************************
PLEASE FUND YOUR SHARE OF $24,714.36
Bank Name: QQA Bank NA
ABA # 011500120
Account #: 0026693011
Account Name: LIQ CLO Operating Account
Ref: ABTB Mid-Atlantic LLC
********************************************************************************************
Regards,
SCOTT WALLACE
Telephone #:
Fax #:
QQA Commercial Banking is a brand name of QQA Bank, N.A. Member FDIC
}}
"""
def extract_json_from_response(response_text):
"""Extract JSON response from model output."""
try:
json_start = response_text.find('{')
json_end = response_text.rfind('}') + 1
json_string = response_text[json_start:json_end]
return json.loads(json_string)
except (ValueError, json.JSONDecodeError):
return {"error": "Could not extract JSON from model output"}
def send_to_huggingface_api(prompt):
"""Send the prompt to Hugging Face API and get the response."""
try:
payload = {
"messages": [
{"role": "system", "content": PROMPT_OBJECTIVE_CLASSIFICATION_RULES + PROMPT_CATEGORIES + PROMPT_OUTPUT_FORMAT},
{"role": "user", "content": prompt}
],
"max_tokens": 700,
"temperature": 0.2,
"top_p": 0.8,
"model": MODEL_NAME
}
response = requests.post(API_URL, headers=HEADERS, json=payload)
response.raise_for_status()
result = response.json()
if "choices" in result and result["choices"]:
return result["choices"][0]["message"]["content"]
return {"error": "Unexpected API response format"}
except requests.exceptions.RequestException as e:
return {"error": f"API request failed: {e}"}
def classify_email_with_prompt(email_text):
final_response = send_to_huggingface_api(email_text)
try:
classification = extract_json_from_response(final_response)
request_type = classification.get("request_type", "").strip()
if request_type:
valid_sub_types = RequestTypeModel.get_sub_types(request_type)
sub_request_type = classification.get("sub_request_type", "").strip()
if sub_request_type not in valid_sub_types:
classification["sub_request_type"] = valid_sub_types[0]
return classification
except Exception as e:
return {"error": str(e)}
# Example Usage
if __name__ == "__main__":
email_text = """
QQA Bank, N.A.
Loan Agency Services
Date: 05-Feb-2025
Description: Facility Lender Share Adjustment
"""
classification = classify_email_with_prompt(email_text)
print(classification)
|