mcp-summarize / app.py
3morixd's picture
Upload app.py with huggingface_hub
1c5f271 verified
Raw
History Blame Contribute Delete
4.9 kB
import gradio as gr
import json
import re
def summarize_text(text: str, max_sentences: int = 2) -> str:
"""Summarize text using extractive summarization (works on-device, no model needed).
Use this tool when a user needs to summarize text, messages, emails, or articles.
Optimized for mobile use cases: short inputs, concise outputs.
Args:
text: The text to summarize
max_sentences: Maximum number of sentences in the summary (default 2)
Returns:
JSON string with the summary and stats
"""
if not text or len(text.strip()) < 10:
return json.dumps({"error": "Text too short to summarize"})
# Split into sentences
sentences = re.split(r'[.!?]+\s+', text.strip())
sentences = [s.strip() for s in sentences if len(s.strip()) > 5]
if len(sentences) <= max_sentences:
summary = ". ".join(sentences) + "."
else:
# Score sentences by word frequency (extractive summarization)
words = re.findall(r'\w+', text.lower())
word_freq = {}
for w in words:
if len(w) > 2:
word_freq[w] = word_freq.get(w, 0) + 1
# Score each sentence
scored = []
for i, sent in enumerate(sentences):
sent_words = re.findall(r'\w+', sent.lower())
score = sum(word_freq.get(w, 0) for w in sent_words) / (len(sent_words) + 1)
# Boost first sentences (position bias)
score *= (1.0 - i * 0.1)
scored.append((score, i, sent))
# Take top sentences, maintain order
scored.sort(key=lambda x: x[0], reverse=True)
top = sorted(scored[:max_sentences], key=lambda x: x[1])
summary = ". ".join([s[2] for s in top]) + "."
original_words = len(text.split())
summary_words = len(summary.split())
reduction = (1 - summary_words / original_words) * 100 if original_words > 0 else 0
return json.dumps({
"original_length_chars": len(text),
"original_length_words": original_words,
"summary": summary,
"summary_length_chars": len(summary),
"summary_length_words": summary_words,
"compression_ratio": round(reduction, 1),
"sentences_in_summary": max_sentences,
}, indent=2)
def classify_text(text: str) -> str:
"""Classify text as spam/not-spam and detect sentiment.
Use this tool when a user needs to classify a message, email, or notification.
Uses keyword-based heuristics that work on-device without a model.
Args:
text: The text to classify
Returns:
JSON string with classification results
"""
lower = text.lower()
# Spam detection
spam_keywords = ["winner", "congratulations", "click here", "claim now", "free",
"urgent", "limited time", "act now", "cash prize", "gift card",
"verify your account", "suspended", "lottery", "inheritance"]
spam_score = sum(1 for kw in spam_keywords if kw in lower)
is_spam = spam_score >= 2
# Sentiment
positive_words = ["good", "great", "excellent", "amazing", "love", "happy",
"best", "awesome", "fantastic", "wonderful", "perfect"]
negative_words = ["bad", "terrible", "awful", "hate", "angry", "worst",
"horrible", "disappointing", "frustrated", "broken"]
pos_count = sum(1 for w in positive_words if w in lower)
neg_count = sum(1 for w in negative_words if w in lower)
if pos_count > neg_count:
sentiment = "positive"
elif neg_count > pos_count:
sentiment = "negative"
else:
sentiment = "neutral"
return json.dumps({
"text": text[:100] + "..." if len(text) > 100 else text,
"is_spam": is_spam,
"spam_confidence": min(spam_score / 3, 1.0),
"sentiment": sentiment,
"positive_signals": pos_count,
"negative_signals": neg_count,
}, indent=2)
with gr.Blocks(title="dispatchAI Summarize MCP") as demo:
gr.Markdown("## ๐Ÿ“ dispatchAI Summarize (MCP Tool)")
with gr.Tab("Summarize"):
s_input = gr.Textbox(label="Text to Summarize", lines=8, placeholder="Paste text here...")
s_max = gr.Slider(1, 5, value=2, step=1, label="Max Sentences")
s_btn = gr.Button("Summarize", variant="primary")
s_out = gr.Textbox(label="Summary (JSON)", lines=10)
s_btn.click(fn=summarize_text, inputs=[s_input, s_max], outputs=s_out)
with gr.Tab("Classify"):
c_input = gr.Textbox(label="Text to Classify", lines=5, placeholder="Paste message here...")
c_btn = gr.Button("Classify", variant="primary")
c_out = gr.Textbox(label="Classification (JSON)", lines=10)
c_btn.click(fn=classify_text, inputs=c_input, outputs=c_out)
demo.launch(mcp_server=True)