Update app.py
Browse files
app.py
CHANGED
|
@@ -221,7 +221,11 @@ def get_card_details(card_id: str, mcc: str = None) -> dict:
|
|
| 221 |
}
|
| 222 |
|
| 223 |
def get_recommendation_with_agent(user_id, merchant, category, amount):
|
| 224 |
-
yield "
|
|
|
|
|
|
|
|
|
|
|
|
|
| 225 |
|
| 226 |
try:
|
| 227 |
transaction = {
|
|
@@ -235,12 +239,24 @@ def get_recommendation_with_agent(user_id, merchant, category, amount):
|
|
| 235 |
print("=" * 80)
|
| 236 |
print(f"π REQUEST: {config.ORCHESTRATOR_URL}/recommend")
|
| 237 |
print(f"PAYLOAD: {json.dumps(transaction, indent=2)}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 238 |
|
| 239 |
response = httpx.post(
|
| 240 |
f"{config.ORCHESTRATOR_URL}/recommend",
|
| 241 |
json=transaction,
|
| 242 |
timeout=60.0
|
| 243 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 244 |
|
| 245 |
print(f"π₯ STATUS: {response.status_code}")
|
| 246 |
print(f"π¦ RESPONSE: {response.text[:2000]}")
|
|
@@ -1272,7 +1288,88 @@ with gr.Blocks(
|
|
| 1272 |
margin: 5px 0;
|
| 1273 |
font-size: 14px;
|
| 1274 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1275 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1276 |
/* ===== FORECAST TAB - PREDICTION BOX ===== */
|
| 1277 |
.forecast-prediction {
|
| 1278 |
background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);
|
|
@@ -1700,7 +1797,6 @@ Get AI-powered credit card recommendations that maximize your rewards based on:
|
|
| 1700 |
]
|
| 1701 |
)
|
| 1702 |
|
| 1703 |
-
# ==================== TAB 4: FORECAST ====================
|
| 1704 |
# ==================== TAB 4: FORECAST ====================
|
| 1705 |
with gr.Tab("π Forecast"):
|
| 1706 |
# Add clear header with explanation
|
|
|
|
| 221 |
}
|
| 222 |
|
| 223 |
def get_recommendation_with_agent(user_id, merchant, category, amount):
|
| 224 |
+
yield """
|
| 225 |
+
<div class="thinking-dots">
|
| 226 |
+
π€ AI Agent is thinking
|
| 227 |
+
</div>
|
| 228 |
+
""", None
|
| 229 |
|
| 230 |
try:
|
| 231 |
transaction = {
|
|
|
|
| 239 |
print("=" * 80)
|
| 240 |
print(f"π REQUEST: {config.ORCHESTRATOR_URL}/recommend")
|
| 241 |
print(f"PAYLOAD: {json.dumps(transaction, indent=2)}")
|
| 242 |
+
|
| 243 |
+
yield """
|
| 244 |
+
<div class="thinking-dots">
|
| 245 |
+
π Analyzing your wallet
|
| 246 |
+
</div>
|
| 247 |
+
""", None
|
| 248 |
|
| 249 |
response = httpx.post(
|
| 250 |
f"{config.ORCHESTRATOR_URL}/recommend",
|
| 251 |
json=transaction,
|
| 252 |
timeout=60.0
|
| 253 |
)
|
| 254 |
+
|
| 255 |
+
yield """
|
| 256 |
+
<div class="thinking-dots">
|
| 257 |
+
π³ Comparing cards
|
| 258 |
+
</div>
|
| 259 |
+
""", None
|
| 260 |
|
| 261 |
print(f"π₯ STATUS: {response.status_code}")
|
| 262 |
print(f"π¦ RESPONSE: {response.text[:2000]}")
|
|
|
|
| 1288 |
margin: 5px 0;
|
| 1289 |
font-size: 14px;
|
| 1290 |
}
|
| 1291 |
+
.thinking-dots {
|
| 1292 |
+
display: inline-flex;
|
| 1293 |
+
align-items: center;
|
| 1294 |
+
gap: 8px;
|
| 1295 |
+
padding: 20px;
|
| 1296 |
+
font-size: 18px;
|
| 1297 |
+
color: #667eea;
|
| 1298 |
+
font-weight: 500;
|
| 1299 |
+
}
|
| 1300 |
+
|
| 1301 |
+
.thinking-dots::after {
|
| 1302 |
+
content: 'βββ';
|
| 1303 |
+
display: inline-block;
|
| 1304 |
+
letter-spacing: 4px;
|
| 1305 |
+
animation: thinking 1.4s infinite;
|
| 1306 |
+
color: #667eea;
|
| 1307 |
+
}
|
| 1308 |
+
|
| 1309 |
+
@keyframes thinking {
|
| 1310 |
+
0%, 20% {
|
| 1311 |
+
content: 'βββ';
|
| 1312 |
+
}
|
| 1313 |
+
40% {
|
| 1314 |
+
content: 'βββ';
|
| 1315 |
+
}
|
| 1316 |
+
60%, 100% {
|
| 1317 |
+
content: 'βββ';
|
| 1318 |
+
}
|
| 1319 |
+
}
|
| 1320 |
+
|
| 1321 |
+
/* Alternative bouncing dots animation */
|
| 1322 |
+
.thinking-bounce {
|
| 1323 |
+
display: inline-flex;
|
| 1324 |
+
align-items: center;
|
| 1325 |
+
gap: 5px;
|
| 1326 |
+
}
|
| 1327 |
+
|
| 1328 |
+
.thinking-bounce span {
|
| 1329 |
+
width: 10px;
|
| 1330 |
+
height: 10px;
|
| 1331 |
+
background: #667eea;
|
| 1332 |
+
border-radius: 50%;
|
| 1333 |
+
animation: bounce 1.4s infinite ease-in-out;
|
| 1334 |
+
}
|
| 1335 |
|
| 1336 |
+
.thinking-bounce span:nth-child(1) {
|
| 1337 |
+
animation-delay: 0s;
|
| 1338 |
+
}
|
| 1339 |
+
|
| 1340 |
+
.thinking-bounce span:nth-child(2) {
|
| 1341 |
+
animation-delay: 0.2s;
|
| 1342 |
+
}
|
| 1343 |
+
|
| 1344 |
+
.thinking-bounce span:nth-child(3) {
|
| 1345 |
+
animation-delay: 0.4s;
|
| 1346 |
+
}
|
| 1347 |
+
|
| 1348 |
+
@keyframes bounce {
|
| 1349 |
+
0%, 80%, 100% {
|
| 1350 |
+
transform: translateY(0);
|
| 1351 |
+
opacity: 0.5;
|
| 1352 |
+
}
|
| 1353 |
+
40% {
|
| 1354 |
+
transform: translateY(-10px);
|
| 1355 |
+
opacity: 1;
|
| 1356 |
+
}
|
| 1357 |
+
}
|
| 1358 |
+
|
| 1359 |
+
/* Pulsing effect */
|
| 1360 |
+
.thinking-pulse {
|
| 1361 |
+
display: inline-block;
|
| 1362 |
+
animation: pulse 1.5s ease-in-out infinite;
|
| 1363 |
+
}
|
| 1364 |
+
|
| 1365 |
+
@keyframes pulse {
|
| 1366 |
+
0%, 100% {
|
| 1367 |
+
opacity: 1;
|
| 1368 |
+
}
|
| 1369 |
+
50% {
|
| 1370 |
+
opacity: 0.3;
|
| 1371 |
+
}
|
| 1372 |
+
}
|
| 1373 |
/* ===== FORECAST TAB - PREDICTION BOX ===== */
|
| 1374 |
.forecast-prediction {
|
| 1375 |
background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);
|
|
|
|
| 1797 |
]
|
| 1798 |
)
|
| 1799 |
|
|
|
|
| 1800 |
# ==================== TAB 4: FORECAST ====================
|
| 1801 |
with gr.Tab("π Forecast"):
|
| 1802 |
# Add clear header with explanation
|