File size: 4,900 Bytes
1c5f271
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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)