lollms-client 0.32.1__py3-none-any.whl → 1.0.0__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.

Potentially problematic release.


This version of lollms-client might be problematic. Click here for more details.

Files changed (73) hide show
  1. lollms_client/__init__.py +1 -1
  2. lollms_client/llm_bindings/azure_openai/__init__.py +6 -10
  3. lollms_client/llm_bindings/claude/__init__.py +4 -7
  4. lollms_client/llm_bindings/gemini/__init__.py +3 -7
  5. lollms_client/llm_bindings/grok/__init__.py +3 -7
  6. lollms_client/llm_bindings/groq/__init__.py +4 -7
  7. lollms_client/llm_bindings/hugging_face_inference_api/__init__.py +4 -6
  8. lollms_client/llm_bindings/litellm/__init__.py +15 -6
  9. lollms_client/llm_bindings/llamacpp/__init__.py +214 -388
  10. lollms_client/llm_bindings/lollms/__init__.py +24 -14
  11. lollms_client/llm_bindings/lollms_webui/__init__.py +6 -12
  12. lollms_client/llm_bindings/mistral/__init__.py +58 -29
  13. lollms_client/llm_bindings/ollama/__init__.py +6 -11
  14. lollms_client/llm_bindings/open_router/__init__.py +45 -14
  15. lollms_client/llm_bindings/openai/__init__.py +7 -14
  16. lollms_client/llm_bindings/openllm/__init__.py +12 -12
  17. lollms_client/llm_bindings/pythonllamacpp/__init__.py +1 -1
  18. lollms_client/llm_bindings/tensor_rt/__init__.py +8 -13
  19. lollms_client/llm_bindings/transformers/__init__.py +14 -6
  20. lollms_client/llm_bindings/vllm/__init__.py +16 -12
  21. lollms_client/lollms_core.py +296 -487
  22. lollms_client/lollms_discussion.py +436 -78
  23. lollms_client/lollms_llm_binding.py +223 -11
  24. lollms_client/lollms_mcp_binding.py +33 -2
  25. lollms_client/mcp_bindings/local_mcp/__init__.py +3 -2
  26. lollms_client/mcp_bindings/remote_mcp/__init__.py +6 -5
  27. lollms_client/mcp_bindings/standard_mcp/__init__.py +3 -5
  28. lollms_client/stt_bindings/lollms/__init__.py +6 -8
  29. lollms_client/stt_bindings/whisper/__init__.py +2 -4
  30. lollms_client/stt_bindings/whispercpp/__init__.py +15 -16
  31. lollms_client/tti_bindings/dalle/__init__.py +29 -28
  32. lollms_client/tti_bindings/diffusers/__init__.py +25 -21
  33. lollms_client/tti_bindings/gemini/__init__.py +215 -0
  34. lollms_client/tti_bindings/lollms/__init__.py +8 -9
  35. lollms_client-1.0.0.dist-info/METADATA +1214 -0
  36. lollms_client-1.0.0.dist-info/RECORD +69 -0
  37. {lollms_client-0.32.1.dist-info → lollms_client-1.0.0.dist-info}/top_level.txt +0 -2
  38. examples/article_summary/article_summary.py +0 -58
  39. examples/console_discussion/console_app.py +0 -266
  40. examples/console_discussion.py +0 -448
  41. examples/deep_analyze/deep_analyse.py +0 -30
  42. examples/deep_analyze/deep_analyze_multiple_files.py +0 -32
  43. examples/function_calling_with_local_custom_mcp.py +0 -250
  44. examples/generate_a_benchmark_for_safe_store.py +0 -89
  45. examples/generate_and_speak/generate_and_speak.py +0 -251
  46. examples/generate_game_sfx/generate_game_fx.py +0 -240
  47. examples/generate_text_with_multihop_rag_example.py +0 -210
  48. examples/gradio_chat_app.py +0 -228
  49. examples/gradio_lollms_chat.py +0 -259
  50. examples/internet_search_with_rag.py +0 -226
  51. examples/lollms_chat/calculator.py +0 -59
  52. examples/lollms_chat/derivative.py +0 -48
  53. examples/lollms_chat/test_openai_compatible_with_lollms_chat.py +0 -12
  54. examples/lollms_discussions_test.py +0 -155
  55. examples/mcp_examples/external_mcp.py +0 -267
  56. examples/mcp_examples/local_mcp.py +0 -171
  57. examples/mcp_examples/openai_mcp.py +0 -203
  58. examples/mcp_examples/run_remote_mcp_example_v2.py +0 -290
  59. examples/mcp_examples/run_standard_mcp_example.py +0 -204
  60. examples/simple_text_gen_test.py +0 -173
  61. examples/simple_text_gen_with_image_test.py +0 -178
  62. examples/test_local_models/local_chat.py +0 -9
  63. examples/text_2_audio.py +0 -77
  64. examples/text_2_image.py +0 -144
  65. examples/text_2_image_diffusers.py +0 -274
  66. examples/text_and_image_2_audio.py +0 -59
  67. examples/text_gen.py +0 -30
  68. examples/text_gen_system_prompt.py +0 -29
  69. lollms_client-0.32.1.dist-info/METADATA +0 -854
  70. lollms_client-0.32.1.dist-info/RECORD +0 -101
  71. test/test_lollms_discussion.py +0 -368
  72. {lollms_client-0.32.1.dist-info → lollms_client-1.0.0.dist-info}/WHEEL +0 -0
  73. {lollms_client-0.32.1.dist-info → lollms_client-1.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -12,11 +12,42 @@ from lollms_client.lollms_types import MSG_TYPE
12
12
  from lollms_client.lollms_discussion import LollmsDiscussion
13
13
  from lollms_client.lollms_utilities import ImageTokenizer
14
14
  import re
15
+ import yaml
16
+
17
+ from pathlib import Path
18
+ import json
19
+
20
+ def load_known_contexts():
21
+ """
22
+ Loads the known_contexts data from a JSON file.
23
+
24
+ Args:
25
+ file_path (str): The path to the JSON file.
26
+
27
+ Returns:
28
+ dict: A dictionary containing the known_contexts data, or None if an error occurs.
29
+ """
30
+ try:
31
+ file_path = Path(__file__).parent / "assets" / "models_ctx_sizes.json"
32
+ with open(file_path, "r") as f:
33
+ known_contexts = json.load(f)
34
+ return known_contexts
35
+ except FileNotFoundError:
36
+ print(f"Error: File not found at {file_path}")
37
+ return None
38
+ except json.JSONDecodeError:
39
+ print(f"Error: Could not decode JSON from {file_path}")
40
+ return None
41
+ except Exception as e:
42
+ print(f"An unexpected error occurred: {e}")
43
+ return None
44
+
15
45
  class LollmsLLMBinding(ABC):
16
46
  """Abstract base class for all LOLLMS LLM bindings"""
17
47
 
18
48
  def __init__(self,
19
- binding_name: Optional[str] ="unknown"
49
+ binding_name: Optional[str] ="unknown",
50
+ **kwargs
20
51
  ):
21
52
  """
22
53
  Initialize the LollmsLLMBinding base class.
@@ -26,6 +57,18 @@ class LollmsLLMBinding(ABC):
26
57
  """
27
58
  self.binding_name=binding_name
28
59
  self.model_name = None #Must be set by the instance
60
+ self.default_ctx_size = kwargs.get("ctx_size")
61
+ self.default_n_predict = kwargs.get("n_predict")
62
+ self.default_stream = kwargs.get("stream")
63
+ self.default_temperature = kwargs.get("temperature")
64
+ self.default_top_k = kwargs.get("top_k")
65
+ self.default_top_p = kwargs.get("top_p")
66
+ self.default_repeat_penalty = kwargs.get("repeat_penalty")
67
+ self.default_repeat_last_n = kwargs.get("repeat_last_n")
68
+ self.default_seed = kwargs.get("seed")
69
+ self.default_n_threads = kwargs.get("n_threads")
70
+ self.default_streaming_callback = kwargs.get("streaming_callback")
71
+
29
72
 
30
73
  @abstractmethod
31
74
  def generate_text(self,
@@ -154,8 +197,38 @@ class LollmsLLMBinding(ABC):
154
197
  """
155
198
  pass
156
199
 
157
- def get_ctx_size(self, model_name:str|None=None):
158
- # if model_name is none use current model name
200
+ def get_ctx_size(self, model_name: Optional[str] = None) -> Optional[int]:
201
+ """
202
+ Retrieves context size for a model from a hardcoded list.
203
+
204
+ This method checks if the model name contains a known base model identifier
205
+ (e.g., 'llama3.1', 'gemma2') to determine its context length. It's intended
206
+ as a failsafe when the context size cannot be retrieved directly from the
207
+ Ollama API.
208
+ """
209
+ if model_name is None:
210
+ model_name = self.model_name
211
+
212
+ # Hardcoded context sizes for popular models. More specific names (e.g., 'llama3.1')
213
+ # should appear, as they will be checked first due to the sorting logic below.
214
+ known_contexts = load_known_contexts()
215
+
216
+ normalized_model_name = model_name.lower().strip()
217
+
218
+ # Sort keys by length in descending order. This ensures that a more specific
219
+ # name like 'llama3.1' is checked before a less specific name like 'llama3'.
220
+ sorted_base_models = sorted(known_contexts.keys(), key=len, reverse=True)
221
+
222
+ for base_name in sorted_base_models:
223
+ if base_name in normalized_model_name:
224
+ context_size = known_contexts[base_name]
225
+ ASCIIColors.warning(
226
+ f"Using hardcoded context size for model '{model_name}' "
227
+ f"based on base name '{base_name}': {context_size}"
228
+ )
229
+ return context_size
230
+
231
+ ASCIIColors.warning(f"Context size not found for model '{model_name}' in the hardcoded list.")
159
232
  return None
160
233
 
161
234
 
@@ -349,16 +422,155 @@ class LollmsLLMBindingManager:
349
422
  if binding_class:
350
423
  return binding_class(**kwargs)
351
424
  return None
352
-
353
- def get_available_bindings(self) -> list[str]:
425
+ @staticmethod
426
+ def _get_fallback_description(binding_name: str) -> Dict:
427
+ """
428
+ Generates a default description dictionary for a binding without a description.yaml file.
429
+ """
430
+ return {
431
+ "binding_name": binding_name,
432
+ "title": binding_name.replace("_", " ").title(),
433
+ "author": "Unknown",
434
+ "creation_date": "N/A",
435
+ "last_update_date": "N/A",
436
+ "description": f"A binding for {binding_name}. No description.yaml file was found, so common parameters are shown as a fallback.",
437
+ "input_parameters": [
438
+ {
439
+ "name": "model_name",
440
+ "type": "str",
441
+ "description": "The model name, ID, or filename to be used.",
442
+ "mandatory": False,
443
+ "default": ""
444
+ },
445
+ {
446
+ "name": "host_address",
447
+ "type": "str",
448
+ "description": "The host address of the service (for API-based bindings).",
449
+ "mandatory": False,
450
+ "default": ""
451
+ },
452
+ {
453
+ "name": "models_path",
454
+ "type": "str",
455
+ "description": "The path to the models directory (for local bindings).",
456
+ "mandatory": False,
457
+ "default": ""
458
+ },
459
+ {
460
+ "name": "service_key",
461
+ "type": "str",
462
+ "description": "The API key or service key for authentication (if applicable).",
463
+ "mandatory": False,
464
+ "default": ""
465
+ }
466
+ ]
467
+ }
468
+
469
+ @staticmethod
470
+ def get_bindings_list(llm_bindings_dir: Union[str, Path]) -> List[Dict]:
354
471
  """
355
- Return list of available binding names.
472
+ Lists all available LLM bindings by scanning a directory, loading their
473
+ description.yaml file if present, or providing a default description.
474
+
475
+ Args:
476
+ llm_bindings_dir (Union[str, Path]): The path to the directory containing LLM binding folders.
356
477
 
357
478
  Returns:
358
- list[str]: List of binding names.
479
+ List[Dict]: A list of dictionaries, each describing a binding.
359
480
  """
360
- return [binding_dir.name for binding_dir in self.llm_bindings_dir.iterdir() if binding_dir.is_dir() and (binding_dir / "__init__.py").exists()]
481
+ bindings_dir = Path(llm_bindings_dir)
482
+ if not bindings_dir.is_dir():
483
+ return []
484
+
485
+ bindings_list = []
486
+ for binding_folder in bindings_dir.iterdir():
487
+ if binding_folder.is_dir() and (binding_folder / "__init__.py").exists():
488
+ binding_name = binding_folder.name
489
+ description_file = binding_folder / "description.yaml"
490
+
491
+ binding_info = {}
492
+ if description_file.exists():
493
+ try:
494
+ with open(description_file, 'r', encoding='utf-8') as f:
495
+ binding_info = yaml.safe_load(f)
496
+ binding_info['binding_name'] = binding_name
497
+ except Exception as e:
498
+ print(f"Error loading description.yaml for {binding_name}: {e}")
499
+ binding_info = LollmsLLMBindingManager._get_fallback_description(binding_name)
500
+ else:
501
+ binding_info = LollmsLLMBindingManager._get_fallback_description(binding_name)
502
+
503
+ bindings_list.append(binding_info)
361
504
 
362
- def get_available_bindings():
363
- bindings_dir = Path(__file__).parent/"llm_bindings"
364
- return [binding_dir.name for binding_dir in bindings_dir.iterdir() if binding_dir.is_dir() and (binding_dir / "__init__.py").exists()]
505
+ return sorted(bindings_list, key=lambda b: b.get('title', b['binding_name']))
506
+
507
+ def get_available_bindings(self) -> List[Dict]:
508
+ """
509
+ Retrieves a list of all available LLM bindings with their full descriptions.
510
+
511
+ This method scans the configured `llm_bindings_dir`, parsing the `description.yaml`
512
+ file for each valid binding. If a `description.yaml` is missing, a fallback
513
+ description with common parameters is generated. This is the primary method
514
+ for discovering available bindings and their configuration requirements.
515
+
516
+ Returns:
517
+ List[Dict]:
518
+ A list of dictionaries, where each dictionary represents the
519
+ full description of an available binding.
520
+
521
+ Each dictionary contains the following keys:
522
+ - ``binding_name`` (str): The programmatic name of the binding (its folder name).
523
+ - ``title`` (str): A user-friendly title for the binding.
524
+ - ``author`` (str): The creator of the binding.
525
+ - ``creation_date`` (str): The date the binding was created.
526
+ - ``last_update_date`` (str): The date of the last major update.
527
+ - ``description`` (str): A detailed explanation of the binding's purpose.
528
+ - ``input_parameters`` (List[Dict]): A list of parameters required to
529
+ configure the binding. Each parameter is a dictionary with:
530
+ - ``name`` (str): The parameter's name (e.g., 'model_name').
531
+ - ``type`` (str): The expected data type ('str', 'int', 'float', 'bool').
532
+ - ``description`` (str): A user-friendly description of the parameter.
533
+ - ``mandatory`` (bool): True if the parameter must be provided.
534
+ - ``default``: The default value for the parameter.
535
+
536
+ Example of a returned dictionary in the list:
537
+ .. code-block:: python
538
+
539
+ {
540
+ "binding_name": "ollama",
541
+ "title": "Ollama",
542
+ "author": "ParisNeo",
543
+ ...
544
+ "input_parameters": [
545
+ {
546
+ "name": "host_address",
547
+ "type": "str",
548
+ "description": "The URL of the Ollama server.",
549
+ "mandatory": True,
550
+ "default": "http://localhost:11434"
551
+ },
552
+ ...
553
+ ]
554
+ }
555
+ """
556
+ return LollmsLLMBindingManager.get_bindings_list(self.llm_bindings_dir)
557
+
558
+ def get_available_bindings(llm_bindings_dir: Union[str, Path] = None) -> List[Dict]:
559
+ """
560
+ Lists all available LLM bindings with their detailed descriptions.
561
+
562
+ This function serves as a primary entry point for discovering what bindings
563
+ are available and how to configure them.
564
+
565
+ Args:
566
+ llm_bindings_dir (Union[str, Path], optional):
567
+ The path to the LLM bindings directory. If None, it defaults to the
568
+ 'llm_bindings' subdirectory relative to this file.
569
+ Defaults to None.
570
+
571
+ Returns:
572
+ List[Dict]: A list of dictionaries, each describing a binding.
573
+ """
574
+ if llm_bindings_dir is None:
575
+ llm_bindings_dir = Path(__file__).parent / "llm_bindings"
576
+ return LollmsLLMBindingManager.get_bindings_list(llm_bindings_dir)
@@ -4,7 +4,7 @@ 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, ASCIIColors
7
-
7
+ import yaml
8
8
  class LollmsMCPBinding(ABC):
9
9
  """
10
10
  Abstract Base Class for LOLLMS Model Context Protocol (MCP) Bindings.
@@ -185,6 +185,7 @@ class LollmsMCPBindingManager:
185
185
  return None
186
186
  return None
187
187
 
188
+
188
189
  def get_available_bindings(self) -> List[str]:
189
190
  """
190
191
  Return list of available MCP binding names based on subdirectories.
@@ -195,4 +196,34 @@ class LollmsMCPBindingManager:
195
196
  for item in self.mcp_bindings_dir.iterdir():
196
197
  if item.is_dir() and (item / "__init__.py").exists():
197
198
  available.append(item.name)
198
- return available
199
+ return available
200
+
201
+ def get_binding_description(self, binding_name: str) -> Optional[Dict[str, Any]]:
202
+ """
203
+ Loads and returns the content of the description.yaml file for a given binding.
204
+
205
+ Args:
206
+ binding_name (str): The name of the binding.
207
+
208
+ Returns:
209
+ Optional[Dict[str, Any]]: A dictionary with the parsed YAML content, or None if the file doesn't exist or is invalid.
210
+ """
211
+ binding_dir = self.mcp_bindings_dir / binding_name
212
+ description_file = binding_dir / "description.yaml"
213
+
214
+ if not description_file.exists():
215
+ ASCIIColors.warning(f"No description.yaml found for MCP binding '{binding_name}'.")
216
+ return None
217
+
218
+ try:
219
+ with open(description_file, 'r', encoding='utf-8') as f:
220
+ description = yaml.safe_load(f)
221
+ return description
222
+ except yaml.YAMLError as e:
223
+ ASCIIColors.error(f"Error parsing description.yaml for MCP binding '{binding_name}': {e}")
224
+ trace_exception(e)
225
+ return None
226
+ except Exception as e:
227
+ ASCIIColors.error(f"Error reading description.yaml for MCP binding '{binding_name}': {e}")
228
+ trace_exception(e)
229
+ return None
@@ -21,15 +21,16 @@ class LocalMCPBinding(LollmsMCPBinding):
21
21
  """
22
22
 
23
23
  def __init__(self,
24
- tools_folder_path: str|Path|None = None):
24
+ **kwargs: Any
25
+ ):
25
26
  """
26
27
  Initialize the LocalMCPBinding.
27
28
 
28
29
  Args:
29
- binding_name (str): The name of this binding.
30
30
  tools_folder_path (str|Path) a folder where to find tools
31
31
  """
32
32
  super().__init__(binding_name="LocalMCP")
33
+ tools_folder_path = kwargs.get("tools_folder_path")
33
34
  if tools_folder_path:
34
35
  try:
35
36
  self.tools_folder_path: Optional[Path] = Path(tools_folder_path)
@@ -27,8 +27,8 @@ class RemoteMCPBinding(LollmsMCPBinding):
27
27
  Tools from all connected servers are aggregated and prefixed with the server's alias.
28
28
  """
29
29
  def __init__(self,
30
- servers_infos: Dict[str, Dict[str, Any]],
31
- **other_config_params: Any):
30
+ **kwargs: Any
31
+ ):
32
32
  """
33
33
  Initializes the binding to connect to multiple MCP servers.
34
34
 
@@ -41,10 +41,11 @@ class RemoteMCPBinding(LollmsMCPBinding):
41
41
  "main_server": {"server_url": "http://localhost:8787", "auth_config": {}},
42
42
  "experimental_server": {"server_url": "http://test.server:9000"}
43
43
  }
44
- **other_config_params (Any): Additional configuration parameters.
44
+ **kwargs (Any): Additional configuration parameters.
45
45
  """
46
46
  super().__init__(binding_name="remote_mcp")
47
47
  # initialization in case no servers are present
48
+ servers_infos: Dict[str, Dict[str, Any]] = kwargs.get("servers_infos", {})
48
49
  self.servers = None
49
50
  if not MCP_LIBRARY_AVAILABLE:
50
51
  ASCIIColors.error(f"{self.binding_name}: MCP library not available. This binding will be disabled.")
@@ -56,8 +57,8 @@ class RemoteMCPBinding(LollmsMCPBinding):
56
57
 
57
58
  ### NEW: Store the overall configuration
58
59
  self.config = {
59
- "servers_infos": servers_infos,
60
- **other_config_params
60
+ "servers_infos": kwargs.get("servers_infos"),
61
+ **kwargs
61
62
  }
62
63
 
63
64
  ### NEW: State management for multiple servers.
@@ -48,12 +48,10 @@ class StandardMCPBinding(LollmsMCPBinding):
48
48
  """
49
49
 
50
50
  def __init__(self,
51
- initial_servers: Optional[Dict[str, Dict[str, Any]]] = None,
52
- **other_config_params: Any):
51
+ **kwargs: Any):
53
52
  super().__init__(binding_name="standard_mcp")
54
-
55
- self.config = {"initial_servers": initial_servers if initial_servers else {}}
56
- self.config.update(other_config_params)
53
+ self.config = kwargs
54
+ initial_servers = kwargs.get("initial_servers", {})
57
55
 
58
56
  self._server_configs: Dict[str, Dict[str, Any]] = {}
59
57
  # Type hint with ClientSession, actual obj if MCP_LIBRARY_AVAILABLE
@@ -14,10 +14,8 @@ class LollmsSTTBinding_Impl(LollmsSTTBinding):
14
14
  """Concrete implementation of the LollmsSTTBinding for the standard LOLLMS server."""
15
15
 
16
16
  def __init__(self,
17
- host_address: Optional[str] = "http://localhost:9600", # Default LOLLMS host
18
- model_name: Optional[str] = None, # Default model (server decides if None)
19
- service_key: Optional[str] = None,
20
- verify_ssl_certificate: bool = True):
17
+ **kwargs
18
+ ):
21
19
  """
22
20
  Initialize the LOLLMS STT binding.
23
21
 
@@ -28,10 +26,10 @@ class LollmsSTTBinding_Impl(LollmsSTTBinding):
28
26
  verify_ssl_certificate (bool): Whether to verify SSL certificates.
29
27
  """
30
28
  super().__init__("lollms")
31
- self.host_address=host_address
32
- self.model_name=model_name
33
- self.service_key=service_key
34
- self.verify_ssl_certificate=verify_ssl_certificate
29
+ self.host_address=kwargs.get("host_address")
30
+ self.model_name=kwargs.get("model_name")
31
+ self.service_key=kwargs.get("service_key")
32
+ self.verify_ssl_certificate=kwargs.get("verify_ssl_certificate")
35
33
 
36
34
  def transcribe_audio(self, audio_path: Union[str, Path], model: Optional[str] = None, **kwargs) -> str:
37
35
  """
@@ -70,8 +70,6 @@ class WhisperSTTBinding(LollmsSTTBinding):
70
70
  WHISPER_MODEL_SIZES = ["tiny", "tiny.en", "base", "base.en", "small", "small.en", "medium", "medium.en", "large", "large-v1", "large-v2", "large-v3"]
71
71
 
72
72
  def __init__(self,
73
- model_name: str = "base", # Default Whisper model size
74
- device: Optional[str] = None, # "cpu", "cuda", "mps", or None for auto
75
73
  **kwargs # To catch any other LollmsSTTBinding standard args
76
74
  ):
77
75
  """
@@ -88,7 +86,7 @@ class WhisperSTTBinding(LollmsSTTBinding):
88
86
  if not _whisper_installed:
89
87
  raise ImportError(f"Whisper STT binding dependencies not met. Please ensure 'openai-whisper' and 'torch' are installed. Error: {_whisper_installation_error}")
90
88
 
91
- self.device = device
89
+ self.device = kwargs.get("device",None)
92
90
  if self.device is None: # Auto-detect if not specified
93
91
  if torch.cuda.is_available():
94
92
  self.device = "cuda"
@@ -101,7 +99,7 @@ class WhisperSTTBinding(LollmsSTTBinding):
101
99
 
102
100
  self.loaded_model_name = None
103
101
  self.model = None
104
- self._load_whisper_model(model_name)
102
+ self._load_whisper_model(kwargs.get("model_name", "base")) # Default to "base" if not specified
105
103
 
106
104
 
107
105
  def _load_whisper_model(self, model_name_to_load: str):
@@ -18,20 +18,19 @@ DEFAULT_WHISPERCPP_EXE_NAMES = ["main", "whisper-cli", "whisper"] # Common names
18
18
 
19
19
  class WhisperCppSTTBinding(LollmsSTTBinding):
20
20
  def __init__(self,
21
- model_path: Union[str, Path], # Path to the GGUF Whisper model
22
- whispercpp_exe_path: Optional[Union[str, Path]] = None, # Path to whisper.cpp executable
23
- ffmpeg_path: Optional[Union[str, Path]] = None, # Path to ffmpeg executable (if not in PATH)
24
- models_search_path: Optional[Union[str, Path]] = None, # Optional dir to scan for more models
25
- default_language: str = "auto",
26
- n_threads: int = 4,
27
- # Catch LollmsSTTBinding standard args even if not directly used by this local binding
28
- host_address: Optional[str] = None, # Not used for local binding
29
- service_key: Optional[str] = None, # Not used for local binding
30
- verify_ssl_certificate: bool = True, # Not used for local binding
31
21
  **kwargs): # Catch-all for future compatibility or specific whisper.cpp params
32
22
 
33
- super().__init__(binding_name="whispercpp")
34
-
23
+ super().__init__(binding_name="whispercpp")
24
+
25
+ # --- Extract values from kwargs with defaults ---
26
+ model_path = kwargs.get("model_path")
27
+ whispercpp_exe_path = kwargs.get("whispercpp_exe_path")
28
+ ffmpeg_path = kwargs.get("ffmpeg_path")
29
+ models_search_path = kwargs.get("models_search_path")
30
+ default_language = kwargs.get("default_language", "auto")
31
+ n_threads = kwargs.get("n_threads", 4)
32
+ extra_whisper_args = kwargs.get("extra_whisper_args", []) # e.g. ["--no-timestamps"]
33
+
35
34
  # --- Validate FFMPEG ---
36
35
  self.ffmpeg_exe = None
37
36
  if ffmpeg_path:
@@ -42,7 +41,7 @@ class WhisperCppSTTBinding(LollmsSTTBinding):
42
41
  raise FileNotFoundError(f"Provided ffmpeg_path '{ffmpeg_path}' not found or not executable.")
43
42
  else:
44
43
  self.ffmpeg_exe = shutil.which("ffmpeg")
45
-
44
+
46
45
  if not self.ffmpeg_exe:
47
46
  ASCIIColors.warning("ffmpeg not found in PATH or explicitly provided. Audio conversion will not be possible for non-WAV files or incompatible WAV files.")
48
47
  ASCIIColors.warning("Please install ffmpeg and ensure it's in your system's PATH, or provide ffmpeg_path argument.")
@@ -63,7 +62,7 @@ class WhisperCppSTTBinding(LollmsSTTBinding):
63
62
  self.whispercpp_exe = found_path
64
63
  ASCIIColors.info(f"Found whisper.cpp executable via PATH: {self.whispercpp_exe}")
65
64
  break
66
-
65
+
67
66
  if not self.whispercpp_exe:
68
67
  raise FileNotFoundError(
69
68
  f"Whisper.cpp executable (tried: {', '.join(DEFAULT_WHISPERCPP_EXE_NAMES)}) not found in PATH or explicitly provided. "
@@ -79,11 +78,11 @@ class WhisperCppSTTBinding(LollmsSTTBinding):
79
78
  self.model_path = Path(models_search_path, self.model_path).resolve()
80
79
  else:
81
80
  raise FileNotFoundError(f"Whisper GGUF model file not found at '{self.model_path}'. Also checked in models_search_path if applicable.")
82
-
81
+
83
82
  self.models_search_path = Path(models_search_path).resolve() if models_search_path else None
84
83
  self.default_language = default_language
85
84
  self.n_threads = n_threads
86
- self.extra_whisper_args = kwargs.get("extra_whisper_args", []) # e.g. ["--no-timestamps"]
85
+ self.extra_whisper_args = extra_whisper_args
87
86
 
88
87
  ASCIIColors.green(f"WhisperCppSTTBinding initialized with model: {self.model_path}")
89
88
 
@@ -35,22 +35,11 @@ DALLE_MODELS = {
35
35
  "max_prompt_length": 4000 # Characters
36
36
  }
37
37
  }
38
-
39
38
  class DalleTTIBinding_Impl(LollmsTTIBinding):
40
39
  """
41
40
  Concrete implementation of LollmsTTIBinding for OpenAI's DALL-E API.
42
41
  """
43
-
44
- def __init__(self,
45
- api_key: Optional[str] = None, # Can be None to check env var
46
- model_name: str = "dall-e-3", # Default to DALL-E 3
47
- default_size: Optional[str] = None, # e.g. "1024x1024"
48
- default_quality: Optional[str] = None, # "standard" or "hd" (DALL-E 3)
49
- default_style: Optional[str] = None, # "vivid" or "natural" (DALL-E 3)
50
- host_address: str = DALLE_API_HOST, # OpenAI API host
51
- verify_ssl_certificate: bool = True,
52
- **kwargs # To catch any other lollms_client specific params like service_key/client_id
53
- ):
42
+ def __init__(self, **kwargs):
54
43
  """
55
44
  Initialize the DALL-E TTI binding.
56
45
 
@@ -70,44 +59,56 @@ class DalleTTIBinding_Impl(LollmsTTIBinding):
70
59
  """
71
60
  super().__init__(binding_name="dalle")
72
61
 
73
- resolved_api_key = api_key
62
+ # Extract parameters from kwargs, providing defaults
63
+ self.api_key = kwargs.get("api_key")
64
+ self.model_name = kwargs.get("model_name")
65
+ self.default_size = kwargs.get("default_size")
66
+ self.default_quality = kwargs.get("default_quality")
67
+ self.default_style = kwargs.get("default_style")
68
+ self.host_address = kwargs.get("host_address", DALLE_API_HOST) # Provide default
69
+ self.verify_ssl_certificate = kwargs.get("verify_ssl_certificate", True) # Provide default
70
+
71
+ # Resolve API key from kwargs or environment variable
72
+ resolved_api_key = self.api_key
74
73
  if not resolved_api_key:
75
74
  ASCIIColors.info(f"API key not provided directly, checking environment variable '{OPENAI_API_KEY_ENV_VAR}'...")
76
75
  resolved_api_key = os.environ.get(OPENAI_API_KEY_ENV_VAR)
77
76
 
78
77
  if not resolved_api_key:
79
78
  raise ValueError(f"OpenAI API key is required. Provide it directly or set the '{OPENAI_API_KEY_ENV_VAR}' environment variable.")
80
-
79
+
81
80
  self.api_key = resolved_api_key
82
- self.host_address = host_address
83
- self.verify_ssl_certificate = verify_ssl_certificate
84
81
 
85
- if model_name not in DALLE_MODELS:
86
- raise ValueError(f"Unsupported DALL-E model: {model_name}. Supported models: {list(DALLE_MODELS.keys())}")
87
- self.model_name = model_name
88
-
82
+ # Model name validation
83
+ if not self.model_name:
84
+ raise ValueError("Model name is required.")
85
+ if self.model_name not in DALLE_MODELS:
86
+ raise ValueError(f"Unsupported DALL-E model: {self.model_name}. Supported models: {list(DALLE_MODELS.keys())}")
87
+
89
88
  model_props = DALLE_MODELS[self.model_name]
90
89
 
91
- # Set defaults from model_props, overridden by user-provided defaults
92
- self.current_size = default_size or model_props["default_size"]
90
+ # Size
91
+ self.current_size = self.default_size or model_props["default_size"]
93
92
  if self.current_size not in model_props["sizes"]:
94
93
  raise ValueError(f"Unsupported size '{self.current_size}' for model '{self.model_name}'. Supported sizes: {model_props['sizes']}")
95
94
 
95
+ # Quality
96
96
  if model_props["supports_quality"]:
97
- self.current_quality = default_quality or model_props["default_quality"]
97
+ self.current_quality = self.default_quality or model_props["default_quality"]
98
98
  if self.current_quality not in model_props["qualities"]:
99
99
  raise ValueError(f"Unsupported quality '{self.current_quality}' for model '{self.model_name}'. Supported qualities: {model_props['qualities']}")
100
100
  else:
101
- self.current_quality = None # Explicitly None if not supported
101
+ self.current_quality = None # Explicitly None if not supported
102
102
 
103
+ # Style
103
104
  if model_props["supports_style"]:
104
- self.current_style = default_style or model_props["default_style"]
105
+ self.current_style = self.default_style or model_props["default_style"]
105
106
  if self.current_style not in model_props["styles"]:
106
107
  raise ValueError(f"Unsupported style '{self.current_style}' for model '{self.model_name}'. Supported styles: {model_props['styles']}")
107
108
  else:
108
- self.current_style = None # Explicitly None if not supported
109
-
110
- # For potential lollms client specific features, if `service_key` is passed as `client_id`
109
+ self.current_style = None # Explicitly None if not supported
110
+
111
+ # Client ID
111
112
  self.client_id = kwargs.get("service_key", kwargs.get("client_id", "dalle_client_user"))
112
113
 
113
114