Whisper Plugin

Plugin implementation for OpenAI Whisper transcription

WhisperPluginConfig


def WhisperPluginConfig(
    model:str='base', device:str='auto', language:Optional=None, task:str='transcribe', temperature:float=0.0,
    temperature_increment_on_fallback:Optional=0.2, beam_size:int=5, best_of:int=5, patience:float=1.0,
    length_penalty:Optional=None, suppress_tokens:str='-1', initial_prompt:Optional=None,
    condition_on_previous_text:bool=False, fp16:bool=True, compression_ratio_threshold:float=2.4,
    logprob_threshold:float=-1.0, no_speech_threshold:float=0.6, word_timestamps:bool=False,
    prepend_punctuations:str='"\'“¿([{-', append_punctuations:str='"\'.。,,!!??::”)]}、', threads:int=0,
    model_dir:Optional=None, compile_model:bool=False
)->None:

Configuration for Whisper transcription plugin.


WhisperLocalPlugin


def WhisperLocalPlugin(
    
):

OpenAI Whisper transcription plugin.

Testing the Plugin

# Test basic functionality
plugin = WhisperLocalPlugin()

# Check availability
print(f"Whisper available: {plugin.is_available()}")
print(f"Plugin name: {plugin.name}")
print(f"Plugin version: {plugin.version}")
print(f"Supported formats: {plugin.supported_formats}")
print(f"Config class: {plugin.config_class.__name__}")
Whisper available: True
Plugin name: whisper_local
Plugin version: 1.0.0
Supported formats: ['wav', 'mp3', 'flac', 'm4a', 'ogg', 'webm', 'mp4', 'avi', 'mov']
Config class: WhisperPluginConfig
# Test configuration dataclass
from dataclasses import fields

print("Available models:")
model_field = next(f for f in fields(WhisperPluginConfig) if f.name == "model")
for model in model_field.metadata.get(SCHEMA_ENUM, []):
    print(f"  - {model}")
Available models:
  - tiny
  - tiny.en
  - base
  - base.en
  - small
  - small.en
  - medium
  - medium.en
  - large
  - large-v1
  - large-v2
  - large-v3
# Test configuration validation
test_configs = [
    ({"model": "tiny"}, "Valid config"),
    ({"model": "invalid"}, "Invalid model"),
    ({"model": "tiny", "temperature": 1.5}, "Temperature out of range"),
]

for config, description in test_configs:
    try:
        test_cfg = dict_to_config(WhisperPluginConfig, config, validate=True)
        print(f"{description}: Valid=True")
    except ValueError as e:
        print(f"{description}: Valid=False")
        print(f"  Error: {str(e)[:100]}")
Valid config: Valid=True
Invalid model: Valid=False
  Error: model: 'invalid' is not one of ['tiny', 'tiny.en', 'base', 'base.en', 'small', 'small.en', 'medium',
Temperature out of range: Valid=False
  Error: temperature: 1.5 is greater than maximum 1.0
# Test initialization and get_current_config (returns dict now)
plugin.initialize({"model": "tiny", "device": "cpu"})
current_config = plugin.get_current_config()
print(f"Current config (dict): {current_config}")
print(f"Current model: {current_config['model']}")
Current config (dict): {'model': 'tiny', 'device': 'cpu', 'language': None, 'task': 'transcribe', 'temperature': 0.0, 'temperature_increment_on_fallback': 0.2, 'beam_size': 5, 'best_of': 5, 'patience': 1.0, 'length_penalty': None, 'suppress_tokens': '-1', 'initial_prompt': None, 'condition_on_previous_text': False, 'fp16': True, 'compression_ratio_threshold': 2.4, 'logprob_threshold': -1.0, 'no_speech_threshold': 0.6, 'word_timestamps': False, 'prepend_punctuations': '"\'“¿([{-', 'append_punctuations': '"\'.。,,!!??::”)]}、', 'threads': 0, 'model_dir': None, 'compile_model': False}
Current model: tiny
# Test get_config_schema for UI generation
import json

schema = plugin.get_config_schema()
print("JSON Schema for WhisperPluginConfig:")
print(f"  Name: {schema['name']}")
print(f"  Properties count: {len(schema['properties'])}")
print(f"  Model field enum: {schema['properties']['model'].get('enum', [])[:3]}...")
print(f"\nFull schema (truncated):")
print(json.dumps({k: v for k, v in list(schema['properties'].items())[:3]}, indent=2))
JSON Schema for WhisperPluginConfig:
  Name: WhisperPluginConfig
  Properties count: 23
  Model field enum: ['tiny', 'tiny.en', 'base']...

Full schema (truncated):
{
  "model": {
    "type": "string",
    "title": "Model",
    "description": "Whisper model size. Larger models are more accurate but slower.",
    "enum": [
      "tiny",
      "tiny.en",
      "base",
      "base.en",
      "small",
      "small.en",
      "medium",
      "medium.en",
      "large",
      "large-v1",
      "large-v2",
      "large-v3"
    ],
    "default": "base"
  },
  "device": {
    "type": "string",
    "title": "Device",
    "description": "Device for inference (auto will use CUDA if available)",
    "enum": [
      "auto",
      "cpu",
      "cuda"
    ],
    "default": "auto"
  },
  "language": {
    "type": [
      "string",
      "null"
    ],
    "title": "Language",
    "description": "Language code (e.g., 'en', 'es', 'fr') or None for auto-detection",
    "default": null
  }
}
# Test idempotent initialize - model unload on config change
import logging

# Enable logging to see model unload messages
logging.basicConfig(level=logging.INFO)

# Initialize with one model
plugin.initialize({"model": "tiny", "device": "cpu"})
print(f"Initial config: model={plugin.config.model}")

# Re-initialize with same model (no unload should happen)
print("\nRe-initializing with same model...")
plugin.initialize({"model": "tiny", "device": "cpu"})

# Re-initialize with different model (unload should trigger)
print("\nRe-initializing with different model...")
plugin.initialize({"model": "base", "device": "cpu"})
print(f"New config: model={plugin.config.model}")
INFO:__main__.WhisperLocalPlugin:Initialized Whisper plugin with model 'tiny' on device 'cpu'
INFO:__main__.WhisperLocalPlugin:Initialized Whisper plugin with model 'tiny' on device 'cpu'
INFO:__main__.WhisperLocalPlugin:Config change: Model tiny -> base
INFO:__main__.WhisperLocalPlugin:Initialized Whisper plugin with model 'base' on device 'cpu'
Initial config: model=tiny

Re-initializing with same model...

Re-initializing with different model...
New config: model=base