3morixd commited on
Commit
1c5f271
·
verified ·
1 Parent(s): b33b7ce

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +125 -0
app.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import json
3
+ import re
4
+
5
+ def summarize_text(text: str, max_sentences: int = 2) -> str:
6
+ """Summarize text using extractive summarization (works on-device, no model needed).
7
+
8
+ Use this tool when a user needs to summarize text, messages, emails, or articles.
9
+ Optimized for mobile use cases: short inputs, concise outputs.
10
+
11
+ Args:
12
+ text: The text to summarize
13
+ max_sentences: Maximum number of sentences in the summary (default 2)
14
+
15
+ Returns:
16
+ JSON string with the summary and stats
17
+ """
18
+ if not text or len(text.strip()) < 10:
19
+ return json.dumps({"error": "Text too short to summarize"})
20
+
21
+ # Split into sentences
22
+ sentences = re.split(r'[.!?]+\s+', text.strip())
23
+ sentences = [s.strip() for s in sentences if len(s.strip()) > 5]
24
+
25
+ if len(sentences) <= max_sentences:
26
+ summary = ". ".join(sentences) + "."
27
+ else:
28
+ # Score sentences by word frequency (extractive summarization)
29
+ words = re.findall(r'\w+', text.lower())
30
+ word_freq = {}
31
+ for w in words:
32
+ if len(w) > 2:
33
+ word_freq[w] = word_freq.get(w, 0) + 1
34
+
35
+ # Score each sentence
36
+ scored = []
37
+ for i, sent in enumerate(sentences):
38
+ sent_words = re.findall(r'\w+', sent.lower())
39
+ score = sum(word_freq.get(w, 0) for w in sent_words) / (len(sent_words) + 1)
40
+ # Boost first sentences (position bias)
41
+ score *= (1.0 - i * 0.1)
42
+ scored.append((score, i, sent))
43
+
44
+ # Take top sentences, maintain order
45
+ scored.sort(key=lambda x: x[0], reverse=True)
46
+ top = sorted(scored[:max_sentences], key=lambda x: x[1])
47
+ summary = ". ".join([s[2] for s in top]) + "."
48
+
49
+ original_words = len(text.split())
50
+ summary_words = len(summary.split())
51
+ reduction = (1 - summary_words / original_words) * 100 if original_words > 0 else 0
52
+
53
+ return json.dumps({
54
+ "original_length_chars": len(text),
55
+ "original_length_words": original_words,
56
+ "summary": summary,
57
+ "summary_length_chars": len(summary),
58
+ "summary_length_words": summary_words,
59
+ "compression_ratio": round(reduction, 1),
60
+ "sentences_in_summary": max_sentences,
61
+ }, indent=2)
62
+
63
+ def classify_text(text: str) -> str:
64
+ """Classify text as spam/not-spam and detect sentiment.
65
+
66
+ Use this tool when a user needs to classify a message, email, or notification.
67
+ Uses keyword-based heuristics that work on-device without a model.
68
+
69
+ Args:
70
+ text: The text to classify
71
+
72
+ Returns:
73
+ JSON string with classification results
74
+ """
75
+ lower = text.lower()
76
+
77
+ # Spam detection
78
+ spam_keywords = ["winner", "congratulations", "click here", "claim now", "free",
79
+ "urgent", "limited time", "act now", "cash prize", "gift card",
80
+ "verify your account", "suspended", "lottery", "inheritance"]
81
+ spam_score = sum(1 for kw in spam_keywords if kw in lower)
82
+ is_spam = spam_score >= 2
83
+
84
+ # Sentiment
85
+ positive_words = ["good", "great", "excellent", "amazing", "love", "happy",
86
+ "best", "awesome", "fantastic", "wonderful", "perfect"]
87
+ negative_words = ["bad", "terrible", "awful", "hate", "angry", "worst",
88
+ "horrible", "disappointing", "frustrated", "broken"]
89
+
90
+ pos_count = sum(1 for w in positive_words if w in lower)
91
+ neg_count = sum(1 for w in negative_words if w in lower)
92
+
93
+ if pos_count > neg_count:
94
+ sentiment = "positive"
95
+ elif neg_count > pos_count:
96
+ sentiment = "negative"
97
+ else:
98
+ sentiment = "neutral"
99
+
100
+ return json.dumps({
101
+ "text": text[:100] + "..." if len(text) > 100 else text,
102
+ "is_spam": is_spam,
103
+ "spam_confidence": min(spam_score / 3, 1.0),
104
+ "sentiment": sentiment,
105
+ "positive_signals": pos_count,
106
+ "negative_signals": neg_count,
107
+ }, indent=2)
108
+
109
+ with gr.Blocks(title="dispatchAI Summarize MCP") as demo:
110
+ gr.Markdown("## 📝 dispatchAI Summarize (MCP Tool)")
111
+
112
+ with gr.Tab("Summarize"):
113
+ s_input = gr.Textbox(label="Text to Summarize", lines=8, placeholder="Paste text here...")
114
+ s_max = gr.Slider(1, 5, value=2, step=1, label="Max Sentences")
115
+ s_btn = gr.Button("Summarize", variant="primary")
116
+ s_out = gr.Textbox(label="Summary (JSON)", lines=10)
117
+ s_btn.click(fn=summarize_text, inputs=[s_input, s_max], outputs=s_out)
118
+
119
+ with gr.Tab("Classify"):
120
+ c_input = gr.Textbox(label="Text to Classify", lines=5, placeholder="Paste message here...")
121
+ c_btn = gr.Button("Classify", variant="primary")
122
+ c_out = gr.Textbox(label="Classification (JSON)", lines=10)
123
+ c_btn.click(fn=classify_text, inputs=c_input, outputs=c_out)
124
+
125
+ demo.launch(mcp_server=True)