File size: 3,966 Bytes
d53b325
e53cc7e
 
33a37e4
d53b325
 
 
 
 
aae0d96
d53b325
 
d33239b
d53b325
 
c0a5ec1
d53b325
 
c0a5ec1
d53b325
 
 
aae0d96
 
 
 
 
 
 
 
c0a5ec1
d53b325
 
 
 
 
 
 
 
33a37e4
 
d53b325
c0a5ec1
 
d53b325
 
33a37e4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d53b325
33a37e4
d53b325
 
 
 
 
33a37e4
 
d53b325
 
 
 
 
 
 
 
33a37e4
d53b325
 
 
 
 
c0a5ec1
 
 
 
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
from smolagents.tools import Tool
import json
import pronouncing
import string

class ParodyWordSuggestionTool(Tool):
    name = "parody_word_suggester"
    description = """Suggests phonetically similar funny words using CMU dictionary pronunciations.

    Returns similar words from a curated list of funny words, along with their similarity scores."""
    inputs = {'target': {'type': 'string', 'description': 'The word you want to find funny alternatives for'}, 'word_list_str': {'type': 'string', 'description': 'JSON string of word list (e.g. \'["word1", "word2"]\')'}, 'min_similarity': {'type': 'string', 'description': 'Minimum similarity threshold (0.0-1.0)', 'nullable': True}}
    output_type = "string"

    def forward(self, target: str, word_list_str: str, min_similarity: str = "0.7") -> str:
        """Get phonetically similar funny word suggestions."""
        import pronouncing
        import string
        import json
    
        target = target.lower().strip(string.punctuation)
        min_similarity = float(min_similarity)
        suggestions = []
    
        # Parse JSON string to list
        try:
            words = json.loads(word_list_str)
        except json.JSONDecodeError:
            return json.dumps({
                "error": "Invalid JSON string for word_list_str",
                "suggestions": []
            }, indent=2)
        
        # Get target pronunciation
        target_phones = pronouncing.phones_for_word(target)
        if not target_phones:
            return json.dumps({
                "error": f"'{target}' not found in CMU dictionary",
                "suggestions": []
            }, indent=2)
        
        target_phones = target_phones[0]
        target_phone_list = target_phones.split()
    
        # Check each word
        for word in words:
            phones = pronouncing.phones_for_word(word)
            if phones:  # Only process if word is in dictionary
                word_phones = phones[0]
                word_phone_list = word_phones.split()
            
                # Calculate position-aware similarity
                matches = 0
                length = max(len(word_phone_list), len(target_phone_list))
            
                # Compare phones at each position
                for i in range(length):
                    if i < len(word_phone_list) and i < len(target_phone_list):
                        # Get current phones
                        current_word_phone = word_phone_list[i]
                        current_target_phone = target_phone_list[i]
                    
                        # Exact match at same position
                        if current_word_phone == current_target_phone:
                            matches += 1
                        # Partial match (just the consonant or vowel part)
                        elif current_word_phone.rstrip('012') == current_target_phone.rstrip('012'):
                            matches += 0.5
            
                similarity = matches / length if length > 0 else 0.0
            
                if similarity >= min_similarity:
                    suggestions.append({
                        "word": word,
                        "similarity": round(similarity, 3),
                        "syllables": pronouncing.syllable_count(word_phones),
                        "phones": word_phones,
                    })
    
        # Sort by similarity score descending
        suggestions.sort(key=lambda x: x["similarity"], reverse=True)
    
        result = {
            "target": target,
            "target_syllables": pronouncing.syllable_count(target_phones),
            "target_phones": target_phones,
            "suggestions": suggestions
        }
    
        return json.dumps(result, indent=2)


    def __init__(self, *args, **kwargs):
        self.is_initialized = False