# ============================================================ # ⚡ Semantic Intent Router (MiniLM) # Zero-shot • No training • Sub-second • HF Free CPU # ============================================================ import json import time import math from typing import Dict, List, Any import torch import gradio as gr from sentence_transformers import SentenceTransformer, util # ============================================================ # CONFIG # ============================================================ MODEL_NAME = "sentence-transformers/all-MiniLM-L6-v2" MIN_SCORE = 0.05 MAX_EXAMPLES = 20 # ============================================================ # LOAD MODEL # ============================================================ print("Loading MiniLM model...") model = SentenceTransformer(MODEL_NAME, device="cpu") print("Model loaded") # ============================================================ # HELPERS # ============================================================ def softmax(scores: Dict[str, float]) -> Dict[str, float]: if not scores: return {} max_val = max(scores.values()) exp_scores = {k: math.exp(v - max_val) for k, v in scores.items()} total = sum(exp_scores.values()) return {k: v / total for k, v in exp_scores.items()} def parse_labels(raw: Any) -> Dict[str, List[str]]: """ Accepts dict (Gradio JSON) or JSON string. Returns clean label -> examples mapping. """ if isinstance(raw, str): try: raw = json.loads(raw) except Exception as e: return {"__error__": f"Invalid JSON: {e}"} if not isinstance(raw, dict): return {"__error__": "Labels must be a JSON object"} cleaned = {} for label, examples in raw.items(): if not isinstance(label, str): continue if not isinstance(examples, list): continue ex = [ str(x).strip() for x in examples if isinstance(x, (str, int, float)) and str(x).strip() ][:MAX_EXAMPLES] if ex: cleaned[label] = ex if not cleaned: return {"__error__": "No valid labels found"} return cleaned # ============================================================ # CLASSIFIER CORE # ============================================================ def classify(text: str, raw_labels: Any) -> Dict[str, Any]: start = time.time() if not text or not text.strip(): return {"error": "Empty input"} labels = parse_labels(raw_labels) if "__error__" in labels: return {"error": labels["__error__"]} text_emb = model.encode(text, convert_to_tensor=True) scores = {} for label, examples in labels.items(): example_embs = model.encode(examples, convert_to_tensor=True) sims = util.cos_sim(text_emb, example_embs)[0] score = float(torch.max(sims).item()) if score >= MIN_SCORE: scores[label] = score if not scores: return { "text": text, "top_intent": None, "scores": {}, "latency_ms": round((time.time() - start) * 1000, 2), } scores = softmax(scores) top_intent = max(scores, key=scores.get) return { "text": text, "top_intent": top_intent, "scores": dict(sorted(scores.items(), key=lambda x: -x[1])), "latency_ms": round((time.time() - start) * 1000, 2), } # ============================================================ # DEFAULT LABELS # ============================================================ DEFAULT_LABELS = { "chat": [ "say hello", "casual talk", "how are you" ], "image_generation": [ "generate an image", "draw a picture", "create artwork" ], "action": [ "set a timer", "create a reminder" ], "code": [ "write code", "debug program" ], "search": [ "search online", "find information" ] } # ============================================================ # GRADIO UI # ============================================================ with gr.Blocks(title="⚡ Semantic Intent Router") as demo: gr.Markdown( "# ⚡ Semantic Intent Router\n" "MiniLM semantic classifier · No training · Sub-second\n\n" "• Edit labels freely\n" "• Add examples per label\n" "• Used for MPC / system-prompt routing\n" ) user_input = gr.Textbox( label="User Input", placeholder="Type anything…", lines=2 ) labels_input = gr.JSON( label="Labels & Examples (editable)", value=DEFAULT_LABELS ) output = gr.JSON(label="Routing Result") classify_btn = gr.Button("Classify", variant="primary") classify_btn.click( fn=classify, inputs=[user_input, labels_input], outputs=output ) gr.Markdown( "### API Usage\n" "POST to this Space endpoint with:\n\n" "`{\"data\": [\"your text\", {\"label\": [\"example\"]}]}`\n" ) # ============================================================ # LAUNCH # ============================================================ if __name__ == "__main__": demo.launch( share=True )