File size: 5,606 Bytes
18e58fa | 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 | import re
import os
import urllib.parse
# βββ Jurisdiction Detection βββββββββββββββββββββββββββββββββββββββββββββββββββ
INDIA_KEYWORDS = [
"gst", "cgst", "sgst", "igst", "tds", "tcs", "itc", "sebi", "rbi", "india", "indian",
"rupee", "inr", "crore", "lakh", "section 194", "companies act", "ipc", "ibc",
"income tax", "delhi", "mumbai", "bombay", "chennai", "bangalore", "hyderabad",
"goods and services tax", "finance act", "cbdt", "gstr", "pan", "tan",
"fema", "rera", "msme", "nri", "oci", "itat", "nclt", "nclat"
]
UAE_KEYWORDS = [
"vat", "uae vat", "fta", "uae", "dubai", "abu dhabi", "sharjah", "ajman",
"dirham", "aed", "free zone", "difc", "adgm", "excise tax",
"federal tax authority", "corporate tax", "uae corporate", "ministry of finance",
"cabinet decision", "federal decree", "mainland uae", "freezone"
]
def detect_jurisdiction(query: str) -> str:
q = query.lower()
india = sum(1 for kw in INDIA_KEYWORDS if kw in q)
uae = sum(1 for kw in UAE_KEYWORDS if kw in q)
if india > 0 and uae == 0: return "India"
if uae > 0 and india == 0: return "UAE"
return "Both"
# βββ Auto Context Depth βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
COMPLEX_TERMS = [
"section", "act", "regulation", "notification", "circular", "judgment",
"case", "versus", "liability", "exemption", "penalty", "compliance",
"provision", "clause", "amendment", "appeal", "tribunal", "writ",
"holding", "ratio", "precedent", "article", "schedule"
]
def auto_context_depth(query: str) -> int:
wc = len(query.split())
hits = sum(1 for t in COMPLEX_TERMS if t in query.lower())
if wc < 12 and hits < 2: return 5
if wc < 30 and hits < 4: return 8
if wc < 60 or hits < 6: return 12
return 15
# βββ Source Confidence Tiering ββββββββββββββββββββββββββββββββββββββββββββββββ
def tier_sources(docs: list) -> str:
if not docs: return "SYNTHESIZED"
max_score = max(d.get("rerank_score", d.get("score", 0)) for d in docs)
if max_score > 0.4: return "GROUNDED"
if max_score > 0.12: return "PARTIAL"
return "SYNTHESIZED"
# βββ Think-Tag State Machine ββββββββββββββββββββββββββββββββββββββββββββββββββ
def strip_think_tags(token: str, in_think: bool) -> tuple[str, bool]:
output = ""
remaining = token
while remaining:
if in_think:
end_idx = remaining.find("</think>")
if end_idx == -1:
remaining = ""
else:
in_think = False
remaining = remaining[end_idx + len("</think>"):]
else:
start_idx = remaining.find("<think>")
if start_idx == -1:
output += remaining
remaining = ""
else:
output += remaining[:start_idx]
in_think = True
remaining = remaining[start_idx + len("<think>"):]
return output, in_think
# βββ Citation patterns for UAE and India βββββββββββββββββββββββββββββββββββββ
UAE_LAW_PATTERN = r"((?:Federal\s+)?(?:Decree-)?Law\s+No\.\s*(?:\(?\d+\)?)\s+of\s+\d{4})"
INDIA_LAW_PATTERN = r"((?:Income[\s-]?Tax\s+Act|Companies\s+Act|GST\s+Act|Income[\s-]?Tax\s+Rules?|Indian\s+Penal\s+Code|Insolvency\s+and\s+Bankruptcy\s+Code),?\s+\d{4})"
INDIA_SECTION_PATTERN = r"(Section\s+\d+[A-Z]?(?:-\s*[A-Z]+)?)"
def parse_citations(text: str) -> str:
"""
Scans text for legal citations and wraps them in professional tagging or markdown links.
Avoids double wrapping already-linked text.
"""
# UAE Law linking (Search on UAE Legislation Portal - ignores existing markdown links)
uae_combined = r"(\[[^\]]+\]\([^\)]+\))|" + UAE_LAW_PATTERN
def uae_repl(match):
if match.group(1):
return match.group(1)
val = match.group(2)
encoded = urllib.parse.quote(val)
return f"[{val}](https://elaws.moj.gov.ae/UAE-Legislations-Search-en.aspx?query={encoded})"
text = re.sub(uae_combined, uae_repl, text)
# India Law linking (Search on Indian Kanoon)
india_combined = r"(\[[^\]]+\]\([^\)]+\))|" + INDIA_LAW_PATTERN
def india_repl(match):
if match.group(1):
return match.group(1)
val = match.group(2)
encoded = urllib.parse.quote(val)
return f"[{val}](https://indiankanoon.org/search/?formInput={encoded})"
text = re.sub(india_combined, india_repl, text)
# Section linking (Contextual search on Indian Kanoon)
section_combined = r"(\[[^\]]+\]\([^\)]+\))|" + INDIA_SECTION_PATTERN
def section_repl(match):
if match.group(1):
return match.group(1)
val = match.group(2)
encoded = urllib.parse.quote(val)
return f"[{val}](https://indiankanoon.org/search/?formInput={encoded})"
text = re.sub(section_combined, section_repl, text)
return text
def format_score(score: float) -> str:
"""Formats a search score into a user-friendly percentage or indicator."""
if score > 0.8: return "High"
if score > 0.5: return "Medium"
return "Low"
|