giva-discovery / src /query_parse.py
Gautham98's picture
GIVA Discovery: full app + vectors
73d02ec verified
Raw
History Blame Contribute Delete
2.51 kB
"""
query_parse.py — pull price constraints out of a natural-language prompt.
"bird pendant under 15000" -> clean="bird pendant", max_price=15000
"rose gold ring above 5k" -> clean="rose gold ring", min_price=5000
"anklet between 1000 and 3000" -> min_price=1000, max_price=3000
Deterministic (regex) so the demo behaves predictably — no LLM needed. The
cleaned prompt (price words removed) is what we embed, so the vector focuses on
the product, not the number.
"""
import re
def _to_number(raw: str) -> float:
"""'15,000' -> 15000, '15k' -> 15000, '1.5k' -> 1500."""
s = raw.lower().replace(",", "").replace("₹", "").replace("rs", "").strip()
mult = 1
if s.endswith("k"):
mult = 1000
s = s[:-1]
elif s.endswith("l") or s.endswith("lakh"):
mult = 100000
s = s.rstrip("lakh").strip()
try:
return float(s) * mult
except ValueError:
return None
# A price token like 15000 | 15,000 | 15k | ₹15000 | rs 2.5k
_NUM = r"(?:₹\s*|rs\.?\s*)?(\d[\d,]*\.?\d*\s*(?:k|l|lakh)?)"
_BETWEEN = re.compile(r"between\s+" + _NUM + r"\s+(?:and|to|-)\s+" + _NUM, re.I)
_UNDER = re.compile(
r"(?:under|below|less than|within|upto|up to|max(?:imum)?|no more than|<=?)\s+" + _NUM, re.I)
_OVER = re.compile(
r"(?:over|above|more than|min(?:imum)?|at least|starting (?:from|at)|>=?)\s+" + _NUM, re.I)
def parse_constraints(prompt: str):
"""Return (clean_prompt, min_price, max_price). Bounds are None if absent."""
text = prompt
min_price = max_price = None
m = _BETWEEN.search(text)
if m:
a, b = _to_number(m.group(1)), _to_number(m.group(2))
if a is not None and b is not None:
min_price, max_price = min(a, b), max(a, b)
text = _BETWEEN.sub(" ", text)
m = _UNDER.search(text)
if m:
v = _to_number(m.group(1))
if v is not None:
max_price = v
text = _UNDER.sub(" ", text)
m = _OVER.search(text)
if m:
v = _to_number(m.group(1))
if v is not None:
min_price = v
text = _OVER.sub(" ", text)
clean = re.sub(r"\s{2,}", " ", text).strip(" .,-") or prompt
return clean, min_price, max_price
if __name__ == "__main__":
for q in ["bird pendant under 15000", "rose gold ring above 5k",
"anklet between 1000 and 3000", "gold studs upto ₹20,000",
"silver bracelet less than 2.5k", "diamond necklace"]:
print(q, "->", parse_constraints(q))