lollms-client 1.4.1__py3-none-any.whl → 1.7.10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. lollms_client/__init__.py +1 -1
  2. lollms_client/llm_bindings/azure_openai/__init__.py +2 -2
  3. lollms_client/llm_bindings/claude/__init__.py +125 -34
  4. lollms_client/llm_bindings/gemini/__init__.py +261 -159
  5. lollms_client/llm_bindings/grok/__init__.py +52 -14
  6. lollms_client/llm_bindings/groq/__init__.py +2 -2
  7. lollms_client/llm_bindings/hugging_face_inference_api/__init__.py +2 -2
  8. lollms_client/llm_bindings/litellm/__init__.py +1 -1
  9. lollms_client/llm_bindings/llamacpp/__init__.py +18 -11
  10. lollms_client/llm_bindings/lollms/__init__.py +151 -32
  11. lollms_client/llm_bindings/lollms_webui/__init__.py +1 -1
  12. lollms_client/llm_bindings/mistral/__init__.py +2 -2
  13. lollms_client/llm_bindings/novita_ai/__init__.py +439 -0
  14. lollms_client/llm_bindings/ollama/__init__.py +309 -93
  15. lollms_client/llm_bindings/open_router/__init__.py +2 -2
  16. lollms_client/llm_bindings/openai/__init__.py +148 -29
  17. lollms_client/llm_bindings/openllm/__init__.py +362 -506
  18. lollms_client/llm_bindings/openwebui/__init__.py +465 -0
  19. lollms_client/llm_bindings/perplexity/__init__.py +326 -0
  20. lollms_client/llm_bindings/pythonllamacpp/__init__.py +3 -3
  21. lollms_client/llm_bindings/tensor_rt/__init__.py +1 -1
  22. lollms_client/llm_bindings/transformers/__init__.py +428 -632
  23. lollms_client/llm_bindings/vllm/__init__.py +1 -1
  24. lollms_client/lollms_agentic.py +4 -2
  25. lollms_client/lollms_base_binding.py +61 -0
  26. lollms_client/lollms_core.py +516 -1890
  27. lollms_client/lollms_discussion.py +55 -18
  28. lollms_client/lollms_llm_binding.py +112 -261
  29. lollms_client/lollms_mcp_binding.py +34 -75
  30. lollms_client/lollms_personality.py +5 -2
  31. lollms_client/lollms_stt_binding.py +85 -52
  32. lollms_client/lollms_tti_binding.py +23 -37
  33. lollms_client/lollms_ttm_binding.py +24 -42
  34. lollms_client/lollms_tts_binding.py +28 -17
  35. lollms_client/lollms_ttv_binding.py +24 -42
  36. lollms_client/lollms_types.py +4 -2
  37. lollms_client/stt_bindings/whisper/__init__.py +108 -23
  38. lollms_client/stt_bindings/whispercpp/__init__.py +7 -1
  39. lollms_client/tti_bindings/diffusers/__init__.py +418 -810
  40. lollms_client/tti_bindings/diffusers/server/main.py +1051 -0
  41. lollms_client/tti_bindings/gemini/__init__.py +182 -239
  42. lollms_client/tti_bindings/leonardo_ai/__init__.py +127 -0
  43. lollms_client/tti_bindings/lollms/__init__.py +4 -1
  44. lollms_client/tti_bindings/novita_ai/__init__.py +105 -0
  45. lollms_client/tti_bindings/openai/__init__.py +10 -11
  46. lollms_client/tti_bindings/stability_ai/__init__.py +178 -0
  47. lollms_client/ttm_bindings/audiocraft/__init__.py +7 -12
  48. lollms_client/ttm_bindings/beatoven_ai/__init__.py +129 -0
  49. lollms_client/ttm_bindings/lollms/__init__.py +4 -17
  50. lollms_client/ttm_bindings/replicate/__init__.py +115 -0
  51. lollms_client/ttm_bindings/stability_ai/__init__.py +117 -0
  52. lollms_client/ttm_bindings/topmediai/__init__.py +96 -0
  53. lollms_client/tts_bindings/bark/__init__.py +7 -10
  54. lollms_client/tts_bindings/lollms/__init__.py +6 -1
  55. lollms_client/tts_bindings/piper_tts/__init__.py +8 -11
  56. lollms_client/tts_bindings/xtts/__init__.py +157 -74
  57. lollms_client/tts_bindings/xtts/server/main.py +241 -280
  58. {lollms_client-1.4.1.dist-info → lollms_client-1.7.10.dist-info}/METADATA +316 -6
  59. lollms_client-1.7.10.dist-info/RECORD +89 -0
  60. lollms_client/ttm_bindings/bark/__init__.py +0 -339
  61. lollms_client-1.4.1.dist-info/RECORD +0 -78
  62. {lollms_client-1.4.1.dist-info → lollms_client-1.7.10.dist-info}/WHEEL +0 -0
  63. {lollms_client-1.4.1.dist-info → lollms_client-1.7.10.dist-info}/licenses/LICENSE +0 -0
  64. {lollms_client-1.4.1.dist-info → lollms_client-1.7.10.dist-info}/top_level.txt +0 -0
@@ -1,15 +1,16 @@
1
- from abc import ABC, abstractmethod
1
+ from abc import abstractmethod
2
2
  import importlib
3
3
  from pathlib import Path
4
4
  from typing import Optional, List, Dict, Any, Union
5
5
  import yaml
6
6
  from ascii_colors import trace_exception
7
+ from lollms_client.lollms_base_binding import LollmsBaseBinding
7
8
 
8
- class LollmsTTSBinding(ABC):
9
+ class LollmsTTSBinding(LollmsBaseBinding):
9
10
  def __init__(self,
10
11
  binding_name: str = "unknown",
11
12
  **kwargs):
12
- self.binding_name = binding_name
13
+ super().__init__(binding_name=binding_name, **kwargs)
13
14
  self.settings = kwargs
14
15
 
15
16
  @abstractmethod
@@ -49,26 +50,21 @@ class LollmsTTSBindingManager:
49
50
  except Exception as e:
50
51
  trace_exception(e)
51
52
  print(f"Failed to load TTS binding {binding_name}: {str(e)}")
52
-
53
- def create_binding(self,
53
+ def create_binding(self,
54
54
  binding_name: str,
55
- config: Dict[str, Any] = None) -> Optional[LollmsTTSBinding]:
56
- if config is None:
57
- config = {}
58
-
55
+ **kwargs) -> Optional[LollmsTTSBinding]:
56
+ """
57
+ Create an instance of a specific binding.
58
+ """
59
59
  if binding_name not in self.available_bindings:
60
60
  self._load_binding(binding_name)
61
-
61
+
62
62
  binding_class = self.available_bindings.get(binding_name)
63
63
  if binding_class:
64
- try:
65
- return binding_class(**config)
66
- except Exception as e:
67
- trace_exception(e)
68
- print(f"Failed to instantiate TTS binding {binding_name}: {str(e)}")
69
- return None
64
+ return binding_class(binding_name=binding_name, **kwargs)
70
65
  return None
71
66
 
67
+
72
68
  @staticmethod
73
69
  def _get_fallback_description(binding_name: str) -> Dict:
74
70
  return {
@@ -124,4 +120,19 @@ class LollmsTTSBindingManager:
124
120
  def get_available_bindings(tts_bindings_dir: Union[str, Path] = None) -> List[Dict]:
125
121
  if tts_bindings_dir is None:
126
122
  tts_bindings_dir = Path(__file__).resolve().parent / "tts_bindings"
127
- return LollmsTTSBindingManager.get_bindings_list(tts_bindings_dir)
123
+ return LollmsTTSBindingManager.get_bindings_list(tts_bindings_dir)
124
+
125
+ def list_binding_models(stt_binding_name: str, stt_binding_config: Optional[Dict[str, any]]|None = None, stt_bindings_dir: str|Path = Path(__file__).parent / "stt_bindings") -> List[Dict]:
126
+ """
127
+ Lists all available models for a specific binding.
128
+ """
129
+ binding = LollmsTTSBindingManager(stt_bindings_dir).create_binding(
130
+ binding_name=stt_binding_name,
131
+ **{
132
+ k: v
133
+ for k, v in (stt_binding_config or {}).items()
134
+ if k != "binding_name"
135
+ }
136
+ )
137
+
138
+ return binding.list_models() if binding else []
@@ -1,37 +1,26 @@
1
1
  # lollms_client/lollms_ttv_binding.py
2
- from abc import ABC, abstractmethod
2
+ from abc import abstractmethod
3
3
  import importlib
4
4
  from pathlib import Path
5
5
  from typing import Optional, List, Dict, Any, Union
6
6
  from ascii_colors import trace_exception
7
+ from lollms_client.lollms_base_binding import LollmsBaseBinding
7
8
 
8
- class LollmsTTVBinding(ABC):
9
+ class LollmsTTVBinding(LollmsBaseBinding):
9
10
  """Abstract base class for all LOLLMS Text-to-Video bindings."""
10
11
 
11
12
  def __init__(self,
12
- binding_name:str="unknown"):
13
+ binding_name:str="unknown",
14
+ **kwargs):
13
15
  """
14
16
  Initialize the LollmsTTVBinding base class.
15
-
16
- Args:
17
- binding_name (Optional[str]): The binding name
18
17
  """
19
- self.binding_name = binding_name
18
+ super().__init__(binding_name=binding_name, **kwargs)
20
19
 
21
20
  @abstractmethod
22
21
  def generate_video(self, prompt: str, **kwargs) -> bytes:
23
22
  """
24
23
  Generates video data from the provided text prompt.
25
-
26
- Args:
27
- prompt (str): The text prompt describing the desired video content.
28
- **kwargs: Additional binding-specific parameters (e.g., duration, fps, style, seed).
29
-
30
- Returns:
31
- bytes: The generated video data (e.g., in MP4 format).
32
-
33
- Raises:
34
- Exception: If video generation fails.
35
24
  """
36
25
  pass
37
26
 
@@ -39,12 +28,6 @@ class LollmsTTVBinding(ABC):
39
28
  def list_models(self, **kwargs) -> List[str]:
40
29
  """
41
30
  Lists the available TTV models or services supported by the binding.
42
-
43
- Args:
44
- **kwargs: Additional binding-specific parameters.
45
-
46
- Returns:
47
- List[str]: A list of available model/service identifiers.
48
31
  """
49
32
  pass
50
33
 
@@ -52,13 +35,6 @@ class LollmsTTVBindingManager:
52
35
  """Manages TTV binding discovery and instantiation."""
53
36
 
54
37
  def __init__(self, ttv_bindings_dir: Union[str, Path] = Path(__file__).parent.parent / "ttv_bindings"):
55
- """
56
- Initialize the LollmsTTVBindingManager.
57
-
58
- Args:
59
- ttv_bindings_dir (Union[str, Path]): Directory containing TTV binding implementations.
60
- Defaults to the "ttv_bindings" subdirectory.
61
- """
62
38
  self.ttv_bindings_dir = Path(ttv_bindings_dir)
63
39
  self.available_bindings = {}
64
40
 
@@ -79,13 +55,6 @@ class LollmsTTVBindingManager:
79
55
  **kwargs) -> Optional[LollmsTTVBinding]:
80
56
  """
81
57
  Create an instance of a specific TTV binding.
82
-
83
- Args:
84
- binding_name (str): Name of the TTV binding to create.
85
- **kwargs: Additional parameters specific to the binding's __init__.
86
-
87
- Returns:
88
- Optional[LollmsTTVBinding]: Binding instance or None if creation failed.
89
58
  """
90
59
  if binding_name not in self.available_bindings:
91
60
  self._load_binding(binding_name)
@@ -93,7 +62,7 @@ class LollmsTTVBindingManager:
93
62
  binding_class = self.available_bindings.get(binding_name)
94
63
  if binding_class:
95
64
  try:
96
- return binding_class(**kwargs)
65
+ return binding_class(binding_name=binding_name, **kwargs)
97
66
  except Exception as e:
98
67
  trace_exception(e)
99
68
  print(f"Failed to instantiate TTV binding {binding_name}: {str(e)}")
@@ -103,9 +72,22 @@ class LollmsTTVBindingManager:
103
72
  def get_available_bindings(self) -> list[str]:
104
73
  """
105
74
  Return list of available TTV binding names based on subdirectories.
106
-
107
- Returns:
108
- list[str]: List of binding names.
109
75
  """
110
76
  return [binding_dir.name for binding_dir in self.ttv_bindings_dir.iterdir()
111
- if binding_dir.is_dir() and (binding_dir / "__init__.py").exists()]
77
+ if binding_dir.is_dir() and (binding_dir / "__init__.py").exists()]
78
+
79
+
80
+ def list_binding_models(ttv_binding_name: str, ttv_binding_config: Optional[Dict[str, any]]|None = None, ttv_bindings_dir: str|Path = Path(__file__).parent / "ttv_bindings") -> List[Dict]:
81
+ """
82
+ Lists all available models for a specific binding.
83
+ """
84
+ binding = LollmsTTVBindingManager(ttv_bindings_dir).create_binding(
85
+ binding_name=ttv_binding_name,
86
+ **{
87
+ k: v
88
+ for k, v in (ttv_binding_config or {}).items()
89
+ if k != "binding_name"
90
+ }
91
+ )
92
+
93
+ return binding.list_models() if binding else []
@@ -41,8 +41,10 @@ class MSG_TYPE(Enum):
41
41
  MSG_TYPE_OBSERVATION = 23# the ai shows its reasoning
42
42
 
43
43
  MSG_TYPE_ERROR = 24#a severe error hapened
44
- MSG_TYPE_GENERATING_TITLE_START = 25#a severe error hapened
45
- MSG_TYPE_GENERATING_TITLE_END = 26#a severe error hapened
44
+ MSG_TYPE_GENERATING_TITLE_START = 25#title generation started
45
+ MSG_TYPE_GENERATING_TITLE_END = 26#title generation done
46
+
47
+ MSG_TYPE_SOURCES_LIST = 27# List of sources provided
46
48
 
47
49
 
48
50
  class SENDER_TYPES(Enum):
@@ -3,6 +3,8 @@ import os
3
3
  from pathlib import Path
4
4
  from typing import Optional, List, Union, Dict, Any
5
5
  from ascii_colors import trace_exception, ASCIIColors
6
+ import time
7
+ import filelock
6
8
 
7
9
  # --- Package Management and Conditional Imports ---
8
10
  _whisper_installed = False
@@ -25,7 +27,7 @@ try:
25
27
  preferred_torch_device_for_install = "mps" # or keep cpu if mps detection is later
26
28
 
27
29
  torch_pkgs = ["torch", "torchaudio","xformers"]
28
- audiocraft_core_pkgs = ["openai-whisper"]
30
+ audiocraft_core_pkgs = ["openai-whisper", "filelock"]
29
31
 
30
32
  torch_index_url = None
31
33
  if preferred_torch_device_for_install == "cuda":
@@ -67,7 +69,7 @@ class WhisperSTTBinding(LollmsSTTBinding):
67
69
  """
68
70
 
69
71
  # Standard Whisper model sizes
70
- WHISPER_MODEL_SIZES = ["tiny", "tiny.en", "base", "base.en", "small", "small.en", "medium", "medium.en", "large", "large-v1", "large-v2", "large-v3"]
72
+ WHISPER_MODEL_SIZES = ["turbo"]
71
73
 
72
74
  def __init__(self,
73
75
  **kwargs # To catch any other LollmsSTTBinding standard args
@@ -76,18 +78,19 @@ class WhisperSTTBinding(LollmsSTTBinding):
76
78
  Initialize the Whisper STT binding.
77
79
 
78
80
  Args:
79
- model_name (str): The Whisper model size to use (e.g., "tiny", "base", "small", "medium", "large", "large-v2", "large-v3").
80
- Defaults to "base".
81
+ model_name (str): The Whisper model size to use (e.g., "turbo").
82
+ Defaults to "turno".
81
83
  device (Optional[str]): The device to run the model on ("cpu", "cuda", "mps").
82
84
  If None, `torch` will attempt to auto-detect. Defaults to None.
83
85
  """
84
86
  super().__init__(binding_name="whisper") # Not applicable
87
+ self.default_model_name = kwargs.get("model_name", "turbo")
85
88
 
86
89
  if not _whisper_installed:
87
90
  raise ImportError(f"Whisper STT binding dependencies not met. Please ensure 'openai-whisper' and 'torch' are installed. Error: {_whisper_installation_error}")
88
91
 
89
- self.device = kwargs.get("device",None)
90
- if self.device is None: # Auto-detect if not specified
92
+ self.device = kwargs.get("device", None)
93
+ if self.device is None or self.device == "": # Auto-detect if not specified or empty
91
94
  if torch.cuda.is_available():
92
95
  self.device = "cuda"
93
96
  elif hasattr(torch.backends, 'mps') and torch.backends.mps.is_available(): # For Apple Silicon
@@ -95,37 +98,115 @@ class WhisperSTTBinding(LollmsSTTBinding):
95
98
  else:
96
99
  self.device = "cpu"
97
100
 
101
+ # Validate device string
102
+ if not self.device or self.device.strip() == "":
103
+ ASCIIColors.warning("Device was empty or invalid, defaulting to 'cpu'")
104
+ self.device = "cpu"
105
+
98
106
  ASCIIColors.info(f"WhisperSTTBinding: Using device '{self.device}'.")
99
107
 
100
108
  self.loaded_model_name = None
101
109
  self.model = None
102
- self._load_whisper_model(kwargs.get("model_name", "base")) # Default to "base" if not specified
110
+ try:
111
+ self._load_whisper_model(kwargs.get("model_name", "turbo")) # Default to "turbo" if not specified
112
+ except Exception as e:
113
+ pass
114
+
115
+
116
+ def _get_whisper_cache_dir(self) -> Path:
117
+ """Get the Whisper cache directory."""
118
+ # Whisper uses the same cache location as specified in its code
119
+ cache_dir = os.getenv("XDG_CACHE_HOME", os.path.expanduser("~/.cache"))
120
+ return Path(cache_dir) / "whisper"
103
121
 
122
+ def _is_model_downloaded(self, model_name: str) -> bool:
123
+ """Check if a Whisper model is already downloaded and valid."""
124
+ cache_dir = self._get_whisper_cache_dir()
125
+ # Whisper models are stored as {model_name}.pt
126
+ model_file = cache_dir / f"{model_name}.pt"
127
+
128
+ if not model_file.exists():
129
+ return False
130
+
131
+ # Check if file size is reasonable (at least 1MB to catch partial downloads)
132
+ try:
133
+ file_size = model_file.stat().st_size
134
+ if file_size < 1_000_000: # Less than 1MB is likely corrupted
135
+ ASCIIColors.warning(f"Model file {model_file} appears corrupted (size: {file_size} bytes). Will re-download.")
136
+ return False
137
+ except Exception as e:
138
+ ASCIIColors.warning(f"Could not check model file size: {e}")
139
+ return False
140
+
141
+ return True
104
142
 
105
143
  def _load_whisper_model(self, model_name_to_load: str):
106
- """Loads or reloads the Whisper model."""
107
- if model_name_to_load not in self.WHISPER_MODEL_SIZES:
144
+ """Loads or reloads the Whisper model with file locking to prevent concurrent downloads."""
145
+ if model_name_to_load not in whisper.available_models():
108
146
  ASCIIColors.warning(f"'{model_name_to_load}' is not a standard Whisper model size. Attempting to load anyway. Known sizes: {self.WHISPER_MODEL_SIZES}")
109
147
 
110
148
  if self.model is not None and self.loaded_model_name == model_name_to_load:
111
149
  ASCIIColors.info(f"Whisper model '{model_name_to_load}' already loaded.")
112
150
  return
113
151
 
152
+ # Get the cache directory and create lock file path
153
+ cache_dir = self._get_whisper_cache_dir()
154
+ cache_dir.mkdir(parents=True, exist_ok=True)
155
+ lock_file = cache_dir / f"{model_name_to_load}.lock"
156
+ model_file = cache_dir / f"{model_name_to_load}.pt"
157
+
114
158
  ASCIIColors.info(f"Loading Whisper model: '{model_name_to_load}' on device '{self.device}'...")
159
+
160
+ # Use file lock to prevent concurrent downloads
161
+ lock = filelock.FileLock(lock_file, timeout=300) # 5 minute timeout
162
+
115
163
  try:
116
- # Whisper's load_model might download the model if not already cached.
117
- # Cache is typically in ~/.cache/whisper
118
- self.model = whisper.load_model(model_name_to_load, device=self.device)
119
- self.loaded_model_name = model_name_to_load
120
- self.model_name = model_name_to_load # Update the binding's current model_name
121
- ASCIIColors.green(f"Whisper model '{model_name_to_load}' loaded successfully.")
164
+ with lock:
165
+ # Check if model is already downloaded and valid
166
+ if self._is_model_downloaded(model_name_to_load):
167
+ ASCIIColors.info(f"Model '{model_name_to_load}' already downloaded, loading from cache...")
168
+ else:
169
+ ASCIIColors.info(f"Downloading model '{model_name_to_load}' (this process has the lock)...")
170
+ # If model file exists but is corrupted, delete it first
171
+ if model_file.exists():
172
+ try:
173
+ ASCIIColors.warning(f"Removing corrupted model file: {model_file}")
174
+ model_file.unlink()
175
+ except Exception as e:
176
+ ASCIIColors.error(f"Could not remove corrupted model file: {e}")
177
+
178
+ # Load the model (will download if not cached)
179
+ self.model = whisper.load_model(model_name_to_load, device=self.device)
180
+ self.loaded_model_name = model_name_to_load
181
+ self.model_name = model_name_to_load
182
+ ASCIIColors.green(f"Whisper model '{model_name_to_load}' loaded successfully.")
183
+
184
+ except filelock.Timeout:
185
+ error_msg = f"Timeout waiting for model '{model_name_to_load}' download lock. Another process may be downloading."
186
+ ASCIIColors.error(error_msg)
187
+ self.model = None
188
+ self.loaded_model_name = None
189
+ raise RuntimeError(error_msg)
122
190
  except Exception as e:
123
191
  self.model = None
124
192
  self.loaded_model_name = None
125
193
  ASCIIColors.error(f"Failed to load Whisper model '{model_name_to_load}': {e}")
126
194
  trace_exception(e)
127
- # Re-raise critical error for initialization or model switching
195
+ # If loading failed, try to clean up potentially corrupted file
196
+ if model_file.exists():
197
+ try:
198
+ ASCIIColors.warning(f"Cleaning up potentially corrupted model file after error...")
199
+ model_file.unlink()
200
+ except Exception as cleanup_error:
201
+ ASCIIColors.error(f"Could not clean up model file: {cleanup_error}")
128
202
  raise RuntimeError(f"Failed to load Whisper model '{model_name_to_load}'") from e
203
+ finally:
204
+ # Clean up lock file if it exists and is not locked
205
+ try:
206
+ if lock_file.exists() and not lock.is_locked:
207
+ lock_file.unlink()
208
+ except Exception:
209
+ pass # Ignore cleanup errors
129
210
 
130
211
 
131
212
  def transcribe_audio(self, audio_path: Union[str, Path], model: Optional[str] = None, **kwargs) -> str:
@@ -149,6 +230,10 @@ class WhisperSTTBinding(LollmsSTTBinding):
149
230
  RuntimeError: If the Whisper model is not loaded or transcription fails.
150
231
  Exception: For other errors during transcription.
151
232
  """
233
+ if not self.model:
234
+ self._load_whisper_model(self.default_model_name)
235
+
236
+
152
237
  audio_file = Path(audio_path)
153
238
  if not audio_file.exists():
154
239
  raise FileNotFoundError(f"Audio file not found at: {audio_path}")
@@ -191,8 +276,8 @@ class WhisperSTTBinding(LollmsSTTBinding):
191
276
  trace_exception(e)
192
277
  raise Exception(f"Whisper transcription error: {e}") from e
193
278
 
194
-
195
- def list_models(self, **kwargs) -> List[str]:
279
+ @staticmethod
280
+ def list_models(**kwargs) -> List[str]:
196
281
  """
197
282
  Lists the available standard Whisper model sizes.
198
283
 
@@ -202,7 +287,7 @@ class WhisperSTTBinding(LollmsSTTBinding):
202
287
  Returns:
203
288
  List[str]: A list of available Whisper model size identifiers.
204
289
  """
205
- return self.WHISPER_MODEL_SIZES.copy() # Return a copy
290
+ return whisper.available_models() # Return a copy
206
291
 
207
292
  def __del__(self):
208
293
  """Clean up: Unload the model to free resources."""
@@ -252,7 +337,7 @@ if __name__ == '__main__':
252
337
  else:
253
338
  try:
254
339
  ASCIIColors.cyan("\n--- Initializing WhisperSTTBinding (model: 'tiny') ---")
255
- # Using 'tiny' model for faster testing. Change to 'base' or 'small' for better quality.
340
+ # Using 'tiny' model for faster testing. Change to 'turbo' or 'small' for better quality.
256
341
  stt_binding = WhisperSTTBinding(model_name="tiny")
257
342
 
258
343
  ASCIIColors.cyan("\n--- Listing available Whisper models ---")
@@ -269,9 +354,9 @@ if __name__ == '__main__':
269
354
  # print(f"Transcription (tiny, lang='en'): '{transcription_lang_hint}'")
270
355
 
271
356
  # Test switching model dynamically (optional, will re-download/load if different)
272
- # ASCIIColors.cyan(f"\n--- Transcribing '{test_audio_file.name}' by switching to 'base' model ---")
273
- # transcription_base = stt_binding.transcribe_audio(test_audio_file, model="base")
274
- # print(f"Transcription (base): '{transcription_base}'")
357
+ # ASCIIColors.cyan(f"\n--- Transcribing '{test_audio_file.name}' by switching to 'turbo' model ---")
358
+ # transcription_base = stt_binding.transcribe_audio(test_audio_file, model="turbo")
359
+ # print(f"Transcription (turbo): '{transcription_base}'")
275
360
 
276
361
 
277
362
  except ImportError as e_imp:
@@ -31,6 +31,8 @@ class WhisperCppSTTBinding(LollmsSTTBinding):
31
31
  n_threads = kwargs.get("n_threads", 4)
32
32
  extra_whisper_args = kwargs.get("extra_whisper_args", []) # e.g. ["--no-timestamps"]
33
33
 
34
+ self.default_model_name = "base"
35
+
34
36
  # --- Validate FFMPEG ---
35
37
  self.ffmpeg_exe = None
36
38
  if ffmpeg_path:
@@ -376,4 +378,8 @@ if __name__ == '__main__':
376
378
  TEST_MODELS_SEARCH_DIR.rmdir()
377
379
  except OSError: pass # Ignore if not empty or other issues
378
380
 
379
- ASCIIColors.yellow("\n--- WhisperCppSTTBinding Test Finished ---")
381
+ ASCIIColors.yellow("\n--- WhisperCppSTTBinding Test Finished ---")
382
+
383
+ def list_models(self) -> List[Dict[str, Any]]:
384
+ return ["base" , "small", "medium", "large"]
385
+