From d97e28467d4f4ecfb70e2881180ff88a7a74be6c Mon Sep 17 00:00:00 2001 From: BarnacleBoy Date: Sat, 9 May 2026 20:52:57 +0000 Subject: [PATCH] Initial commit: SpongeBob vocabulary transformer plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Random opening interjections (25% chance, configurable)- Pattern-based vocabulary replacement (Wow! → Tartar sauce!) - Preserves code blocks, URLs, file paths - Zero-token post-processing via transform_llm_output hook --- README.md | 79 ++++++++++++++++++++++++- __init__.py | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++ plugin.yaml | 6 ++ 3 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 __init__.py create mode 100644 plugin.yaml diff --git a/README.md b/README.md index 9b15e65..cbf625b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,80 @@ # spongebob-vocab -SpongeBob vocabulary transformer plugin for Hermes Agent - zero-token personality injection via transform_llm_output hook \ No newline at end of file +SpongeBob vocabulary transformer plugin for Hermes Agent. AddsBarnacleBoy personality through zero-token `transform_llm_output` hooks. + +## What it does + +1. **Random opening interjections** - 25% chance to prepend phrases like "Jumping jellyfish!" or "Tartar sauce!" at the start of responses +2. **Pattern-based vocabulary replacement** - Transforms words like "Wow!" → "Tartar sauce!", "Amazing!" → "Holy Krabby Patties!" +3. **Preserves technical content** - Code blocks, URLs, file paths, and shell commands are never modified + +## Installation + +Copy to your Hermes plugins directory: + +```bash +cp -r spongebob-vocab ~/.hermes/plugins/ +``` + +## Activation + +Set the environment variable: + +```bash +export SPONGEBOB_MODE=on +``` + +Or add to your shell config: + +```bash +echo 'export SPONGEBOB_MODE=on' >> ~/.bashrc +``` + +## Configuration + +| Variable | Default | Description | +|----------|---------|-------------| +| `SPONGEBOB_MODE` | `off` | Set to `on`, `1`, `true`, or `yes` to enable | +| `SPONGEBOB_INTERJECTION_CHANCE` | `0.25` | Probability (0.0-1.0) of adding opening interjection | + +## Opening Interjections + +Randomly selected from: + +- Jumping jellyfish! +- Tartar sauce! +- Barnacles! +- Holy Krabby Patties! +- Great Neptune's nostrils! +- Mother of Pearl! +- Flappin' flounders! +- Holy fish paste! +- Holy shrimp! +- Great Barrier Reef! +- Aw, fish paste! +- Holy cephalopod! +- What the barnacle! + +## Vocabulary Patterns + +| Original | SpongeBob | +|----------|-----------| +| Wow! | Tartar sauce! | +| Amazing! | Holy Krabby Patties! | +| Excellent! | Holy fish paste! | +| Perfect! | Holy cephalopod! | +| Fantastic! | Holy shrimp! | +| Brilliant! | Great Barrier Reef! | +| Damn! | Barnacles! | +| Ugh! | Fish paste! | + +## Technical Details + +- Uses `transform_llm_output` hook - runs after LLM generation +- Zero additional inference tokens (post-processing only) +- Preserves code blocks, inline code, URLs, file paths, shell commands +- Anti-double-interjection: won't add if response already starts with an interjection + +## License + +MIT \ No newline at end of file diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..9dabe82 --- /dev/null +++ b/__init__.py @@ -0,0 +1,167 @@ +""" +SpongeBob vocabulary transformer for BarnacleBoy. + +Two modes: +1. Pattern-based vocabulary replacement (Wow! → Tartar sauce!) +2. Random opening interjections (Jumping jellyfish! Let's...) + +Hook: transform_llm_output +""" + +import os +import re +import logging +import random + +logger = logging.getLogger(__name__) + +# Opening interjections - randomly prepended to responses +# These are BarnacleBoy's signature exclamations +OPENING_INTERJECTIONS = [ + "Jumping jellyfish!", + "Tartar sauce!", + "Barnacles!", + "Holy Krabby Patties!", + "Great Neptune's nostrils!", + "Mother of Pearl!", + "Flappin' flounders!", + "Holy fish paste!", + "Holy shrimp!", + "Great Barrier Reef!", + "Aw, fishpaste!", + "Holy cephalopod!", + "What the barnacle!", +] + +# Vocabulary replacements - case-insensitive regex patterns +# Format: (pattern, replacement) +VOCABULARY_PATTERNS = [ + # Exclamations (surprise, excitement) - standalone or at start + (r'\bWow!\s', 'Tartar sauce! '), + (r'\bWow!\Z', 'Tartar sauce!'), + (r'\bWow,', 'Tartar sauce,'), + + # Amazing variations + (r'\b[Aa]mazing!\s', 'Holy Krabby Patties! '), + (r'\b[Aa]mazing!\Z', 'Holy Krabby Patties!'), + + # Excellent + (r'\b[Ee]xcellent!\s', 'Holy fish paste! '), + (r'\b[Ee]xcellent!\Z', 'Holy fish paste!'), + + # Great + (r'\bGreat!\s', 'Barnacles! '), + (r'\bGreat!\Z', 'Barnacles!'), + + # Perfect + (r'\b[Pp]erfect!\s', 'Holy cephalopod! '), + (r'\b[Pp]erfect!\Z', 'Holy cephalopod!'), + + # Fantastic + (r'\b[Ff]antastic!\s', 'Holy shrimp! '), + (r'\b[Ff]antastic!\Z', 'Holy shrimp!'), + + # Brilliant + (r'\bBrilliant!', 'Great Barrier Reef!'), + + # Damn frustration + (r'\b[Dd]amn!', 'Barnacles!'), + (r'\b[Dd]amn,', 'Aw, barnacles,'), + + # Ugh frustration + (r'\bUgh!', 'Fish paste!'), + (r'\bUgh,', 'Aw, fish paste!'), + + # Fantastic praise + (r'\b[Ff]antastic!', 'Mother of Pearl!'), + + # Common openers + (r'\bWell,', "Flappin' flounders,"), + (r'\bOh,', 'Oh, barnacles,'), +] + +# Patterns to preserve (never transform) +PRESERVE_PATTERNS = [ + r'```[\s\S]*?```', # Code blocks + r'`[^`]+`', # Inline code + r'https?://[^\s]+', # URLs + r'~/[^\s]+', # File paths starting with ~ + r'/[a-zA-Z][^\s]*', # Absolute paths (start with /) + r'\$[^\n]+', # Shell commands +] + + +def transform_vocabulary(response_text: str, session_id: str = "", model: str = "", platform: str = "") -> str: + """ + Transform response text with SpongeBob vocabulary. + + Args: + response_text: The LLM's output text + session_id: Session identifier (for context-aware decisions) + model: Model name (unused but required by hook signature) + platform: Platform name (e.g., "discord", "telegram") + + Returns: + Transformed text with SpongeBob vocabulary, or None if disabled. + Non-None non-empty string takes precedence over other hooks. + """ + # Check if SpongeBob mode is enabled + mode = os.environ.get("SPONGEBOB_MODE", "").lower() + if mode not in ("on", "1", "true", "yes"): + return None # Not enabled, let other hooks or default pass through + + if not response_text or not response_text.strip(): + return None # Empty response, nothing to transform + + logger.info("[spongebob-vocab] Hook fired, transforming output") + + # Find all regions to preserve + preserved = [] + preserved_text = response_text + + for pattern in PRESERVE_PATTERNS: + for match in re.finditer(pattern, response_text, re.MULTILINE): + placeholder = f"\x00PRESERVE{len(preserved)}\x00" + preserved_text = preserved_text.replace(match.group(0), placeholder) + preserved.append(match.group(0)) + + # Apply vocabulary transformations + transformed = preserved_text + for pattern, replacement in VOCABULARY_PATTERNS: + transformed = re.sub(pattern, replacement, transformed) + + # Restore preserved regions + for i, original in enumerate(preserved): + transformed = transformed.replace(f"\x00PRESERVE{i}\x00", original) + + # Add random opening interjection (25% chance) + # Configurable via SPONGEBOB_INTERJECTION_CHANCE env var(0.0-1.0) + interjection_chance = float(os.environ.get("SPONGEBOB_INTERJECTION_CHANCE", "0.25")) + + if random.random() < interjection_chance: + # Pick a random interjection + interjection = random.choice(OPENING_INTERJECTIONS) + + # Check if response already starts with an interjection-like pattern + # (avoid double-interjecting if the LLM already started with one) + first_line = transformed.split('\n')[0].strip() + already_interjected = any( + first_line.startswith(exc.rstrip('!')) or first_line.startswith(exc) + for exc in OPENING_INTERJECTIONS[:6] # Check common ones + ) + + if not already_interjected: + # Prepend interjection with newline separator + transformed = f"{interjection} {transformed}" + logger.info(f"[spongebob-vocab] Prepended interjection: {interjection}") + + return transformed + + +def register(ctx): + """Register the transform hook with Hermes.""" + ctx.register_hook("transform_llm_output", transform_vocabulary) + logger.info("[spongebob-vocab] Registered transform_llm_output hook") + + +__all__ = ["transform_vocabulary", "register"] \ No newline at end of file diff --git a/plugin.yaml b/plugin.yaml new file mode 100644 index 0000000..0b415cb --- /dev/null +++ b/plugin.yaml @@ -0,0 +1,6 @@ +name: spongebob-vocab +version: 1.0.0 +description: SpongeBob vocabulary transformation via transform_llm_output hook (zero-token personality injection) +author: BarnacleBoy +hooks: + transform_llm_output: transform_vocabulary \ No newline at end of file