piper-assistant / po_normalizer.py
indirapravianti's picture
Deploy Piper sticker restock manager Gradio app
1a65785
Raw
History Blame Contribute Delete
2.05 kB
"""Stage 1 of the Piper pipeline — normalize Indonesian/English code-mixed PO text."""
import re
# Informal Indonesian + code-mixed phrases seen in real partner-store orders
SLANG_PATTERNS: list[tuple[str, str, str]] = [
(r"\bmohon segera\b", "urgent ship request", "mohon segera"),
(r"\btolong kirim\b", "please ship", "tolong kirim"),
(r"\bkirim ya\b", "please ship", "kirim ya"),
(r"\brestock asap\b", "restock segera", "restock asap"),
(r"\bstok habis\b", "out of stock", "stok habis"),
(r"\blg diskon\b", "on sale", "lg diskon"),
(r"\blagi diskon\b", "on sale", "lagi diskon"),
(r"\bpesenan\b", "order", "pesanan"),
(r"\bpesan\b", "order", "pesan"),
(r"\bstiker\b", "sticker", "stiker"),
(r"\bstik(er)?\b", "sticker", "stiker"),
(r"\blembar\b", "pcs", "lembar"),
(r"\bbuah\b", "pcs", "buah"),
(r"\bunit\b", "pcs", "unit"),
(r"\bpcs\b", "pcs", "pcs"),
(r"\bpesanan bulan\b", "monthly order", "pesanan bulan"),
(r"\bmau order lagi\b", "reorder", "mau order lagi"),
(r"\bhai kak\b", "", "hai kak"),
(r"\bmakasih\b", "", "makasih"),
(r"\bthx\b", "", "thx"),
(r"\bthanks\b", "", "thanks"),
]
# Quantity patterns: "20 pcs", "x25", "20,"
QTY_HINT = re.compile(
r"(\d+)\s*(?:pcs|pc|lembar|buah|unit)?",
re.I,
)
def normalize_po_text(raw: str) -> tuple[str, list[str]]:
"""
Clean code-mixed PO text before the LLM sees it.
Returns (normalized_text, list of human-readable fixes applied).
"""
text = raw.strip()
fixes: list[str] = []
for pattern, replacement, label in SLANG_PATTERNS:
if re.search(pattern, text, re.I):
text = re.sub(pattern, replacement, text, flags=re.I)
if label and label not in fixes:
fixes.append(label)
# Collapse repeated whitespace but keep line breaks
text = re.sub(r"[ \t]+", " ", text)
text = re.sub(r"\n{3,}", "\n\n", text)
text = re.sub(r"^[,;\s]+", "", text)
text = re.sub(r"[,;\s]{2,}", ", ", text)
return text, fixes