Spaces:
Running
Running
Upload src/api.py with huggingface_hub
Browse files- src/api.py +31 -2
src/api.py
CHANGED
|
@@ -94,7 +94,7 @@ CATEGORY_SIGNAL_PATTERNS = {
|
|
| 94 |
r'\b(?:invoice|billing|bill|refund|charge|payment|paid|duplicate payment|credit)\b',
|
| 95 |
],
|
| 96 |
'technical_support': [
|
| 97 |
-
r'\b(?:error|bug|crash|broken|failing|not working|api|http\s*\d{3}|500|timeout|integration|export)\b',
|
| 98 |
],
|
| 99 |
'account_management': [
|
| 100 |
r'\b(?:password|login|log in|locked out|reset|permission|access|account|sso|user role|admin)\b',
|
|
@@ -118,7 +118,7 @@ CATEGORY_SIGNAL_PATTERNS = {
|
|
| 118 |
|
| 119 |
EXPLANATION_KEYWORDS = {
|
| 120 |
'billing': ['invoice', 'billing', 'bill', 'refund', 'charge', 'payment', 'paid', 'credit', 'subscription', 'plan'],
|
| 121 |
-
'technical_support': ['error', 'bug', 'crash', 'broken', 'failing', 'working', 'api', 'http', '500', 'timeout', 'integration', 'export'],
|
| 122 |
'account_management': ['password', 'login', 'locked', 'reset', 'permission', 'access', 'account', 'sso', 'user', 'admin'],
|
| 123 |
'feature_request': ['feature', 'request', 'enhancement', 'add', 'support', 'capability', 'roadmap'],
|
| 124 |
'compliance_legal': ['gdpr', 'compliance', 'legal', 'audit', 'privacy', 'dpa', 'regulatory', 'security'],
|
|
@@ -407,6 +407,16 @@ def _has_explicit_churn_signal(text: str) -> bool:
|
|
| 407 |
))
|
| 408 |
|
| 409 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 410 |
def _apply_probability_guardrails(result: Dict, text: str) -> Dict:
|
| 411 |
probs = dict(result.get('all_probs') or {})
|
| 412 |
churn_prob = float(probs.get('churn_risk', 0.0))
|
|
@@ -452,6 +462,18 @@ def _apply_direct_signal_overrides(result: Dict, text: str, direct_intents: List
|
|
| 452 |
reason='Direct billing signal detected without onboarding evidence.',
|
| 453 |
)
|
| 454 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 455 |
return result
|
| 456 |
|
| 457 |
|
|
@@ -562,6 +584,13 @@ def _can_route_by_direct_signal(result: Dict, text: str) -> bool:
|
|
| 562 |
if category == 'billing' and signal_strength >= 3 and margin >= 0.15:
|
| 563 |
return True
|
| 564 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 565 |
if signal_strength >= 3 and confidence >= 0.58 and margin >= 0.20:
|
| 566 |
return True
|
| 567 |
|
|
|
|
| 94 |
r'\b(?:invoice|billing|bill|refund|charge|payment|paid|duplicate payment|credit)\b',
|
| 95 |
],
|
| 96 |
'technical_support': [
|
| 97 |
+
r'\b(?:error|bug|crash|broken|failing|not working|api|http\s*\d{3}|500|timeout|integration|export|outage|down|unavailable)\b',
|
| 98 |
],
|
| 99 |
'account_management': [
|
| 100 |
r'\b(?:password|login|log in|locked out|reset|permission|access|account|sso|user role|admin)\b',
|
|
|
|
| 118 |
|
| 119 |
EXPLANATION_KEYWORDS = {
|
| 120 |
'billing': ['invoice', 'billing', 'bill', 'refund', 'charge', 'payment', 'paid', 'credit', 'subscription', 'plan'],
|
| 121 |
+
'technical_support': ['error', 'bug', 'crash', 'broken', 'failing', 'working', 'api', 'http', '500', 'timeout', 'integration', 'export', 'outage', 'down', 'unavailable'],
|
| 122 |
'account_management': ['password', 'login', 'locked', 'reset', 'permission', 'access', 'account', 'sso', 'user', 'admin'],
|
| 123 |
'feature_request': ['feature', 'request', 'enhancement', 'add', 'support', 'capability', 'roadmap'],
|
| 124 |
'compliance_legal': ['gdpr', 'compliance', 'legal', 'audit', 'privacy', 'dpa', 'regulatory', 'security'],
|
|
|
|
| 407 |
))
|
| 408 |
|
| 409 |
|
| 410 |
+
def _has_system_failure_signal(text: str) -> bool:
|
| 411 |
+
return bool(re.search(
|
| 412 |
+
r'\b(?:outage|production\s+(?:is\s+)?(?:down|blocked|broken|failing)|'
|
| 413 |
+
r'(?:service|platform|dashboard|api)\s+(?:is\s+)?(?:down|unavailable|not responding)|'
|
| 414 |
+
r'all\s+users\s+(?:are\s+)?(?:affected|blocked|unable))\b',
|
| 415 |
+
text,
|
| 416 |
+
flags=re.I,
|
| 417 |
+
))
|
| 418 |
+
|
| 419 |
+
|
| 420 |
def _apply_probability_guardrails(result: Dict, text: str) -> Dict:
|
| 421 |
probs = dict(result.get('all_probs') or {})
|
| 422 |
churn_prob = float(probs.get('churn_risk', 0.0))
|
|
|
|
| 462 |
reason='Direct billing signal detected without onboarding evidence.',
|
| 463 |
)
|
| 464 |
|
| 465 |
+
if (
|
| 466 |
+
_has_system_failure_signal(text)
|
| 467 |
+
and not _has_explicit_churn_signal(text)
|
| 468 |
+
and result.get('top_category') != 'technical_support'
|
| 469 |
+
):
|
| 470 |
+
return _result_forced_to_category(
|
| 471 |
+
result,
|
| 472 |
+
'technical_support',
|
| 473 |
+
confidence=max(0.78, float(result.get('all_probs', {}).get('technical_support', 0.0))),
|
| 474 |
+
reason='Direct system-failure signal detected: outage/down/unavailable.',
|
| 475 |
+
)
|
| 476 |
+
|
| 477 |
return result
|
| 478 |
|
| 479 |
|
|
|
|
| 584 |
if category == 'billing' and signal_strength >= 3 and margin >= 0.15:
|
| 585 |
return True
|
| 586 |
|
| 587 |
+
if (
|
| 588 |
+
category == 'technical_support'
|
| 589 |
+
and _has_system_failure_signal(text)
|
| 590 |
+
and confidence >= 0.35
|
| 591 |
+
):
|
| 592 |
+
return True
|
| 593 |
+
|
| 594 |
if signal_strength >= 3 and confidence >= 0.58 and margin >= 0.20:
|
| 595 |
return True
|
| 596 |
|