Initial commit: SpongeBob vocabulary transformer plugin
- 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
This commit is contained in:
parent
8c6775bffb
commit
d97e28467d
3 changed files with 251 additions and 1 deletions
79
README.md
79
README.md
|
|
@ -1,3 +1,80 @@
|
||||||
# spongebob-vocab
|
# spongebob-vocab
|
||||||
|
|
||||||
SpongeBob vocabulary transformer plugin for Hermes Agent - zero-token personality injection via transform_llm_output hook
|
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
|
||||||
167
__init__.py
Normal file
167
__init__.py
Normal file
|
|
@ -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"]
|
||||||
6
plugin.yaml
Normal file
6
plugin.yaml
Normal file
|
|
@ -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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue