lollms-client 1.6.7__py3-none-any.whl → 1.7.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 (33) hide show
  1. lollms_client/__init__.py +1 -1
  2. lollms_client/lollms_agentic.py +4 -2
  3. lollms_client/lollms_core.py +263 -138
  4. lollms_client/lollms_discussion.py +15 -2
  5. lollms_client/lollms_stt_binding.py +59 -3
  6. lollms_client/lollms_tti_binding.py +3 -1
  7. lollms_client/lollms_ttm_binding.py +3 -1
  8. lollms_client/lollms_tts_binding.py +2 -2
  9. lollms_client/lollms_ttv_binding.py +3 -1
  10. lollms_client/stt_bindings/whisper/__init__.py +20 -12
  11. lollms_client/stt_bindings/whispercpp/__init__.py +7 -1
  12. lollms_client/tti_bindings/diffusers/__init__.py +9 -10
  13. lollms_client/tti_bindings/diffusers/server/main.py +10 -59
  14. lollms_client/tti_bindings/gemini/__init__.py +4 -1
  15. lollms_client/tti_bindings/leonardo_ai/__init__.py +5 -2
  16. lollms_client/tti_bindings/lollms/__init__.py +4 -1
  17. lollms_client/tti_bindings/novita_ai/__init__.py +4 -1
  18. lollms_client/tti_bindings/openai/__init__.py +10 -11
  19. lollms_client/tti_bindings/stability_ai/__init__.py +4 -2
  20. lollms_client/ttm_bindings/audiocraft/__init__.py +7 -12
  21. lollms_client/ttm_bindings/beatoven_ai/__init__.py +7 -3
  22. lollms_client/ttm_bindings/lollms/__init__.py +4 -17
  23. lollms_client/ttm_bindings/replicate/__init__.py +7 -4
  24. lollms_client/ttm_bindings/stability_ai/__init__.py +7 -4
  25. lollms_client/ttm_bindings/topmediai/__init__.py +6 -3
  26. lollms_client/tts_bindings/bark/__init__.py +7 -10
  27. lollms_client/tts_bindings/piper_tts/__init__.py +7 -10
  28. lollms_client/tts_bindings/xtts/__init__.py +8 -8
  29. {lollms_client-1.6.7.dist-info → lollms_client-1.7.0.dist-info}/METADATA +1 -1
  30. {lollms_client-1.6.7.dist-info → lollms_client-1.7.0.dist-info}/RECORD +33 -33
  31. {lollms_client-1.6.7.dist-info → lollms_client-1.7.0.dist-info}/WHEEL +0 -0
  32. {lollms_client-1.6.7.dist-info → lollms_client-1.7.0.dist-info}/licenses/LICENSE +0 -0
  33. {lollms_client-1.6.7.dist-info → lollms_client-1.7.0.dist-info}/top_level.txt +0 -0
@@ -4,12 +4,13 @@ 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
-
7
+ import yaml
8
8
  class LollmsSTTBinding(ABC):
9
9
  """Abstract base class for all LOLLMS Speech-to-Text bindings."""
10
10
 
11
11
  def __init__(self,
12
- binding_name:str="unknown"):
12
+ binding_name:str="unknown",
13
+ config={}):
13
14
  """
14
15
  Initialize the LollmsSTTBinding base class.
15
16
 
@@ -17,6 +18,7 @@ class LollmsSTTBinding(ABC):
17
18
  binding_name (Optional[str]): The binding name
18
19
  """
19
20
  self.binding_name = binding_name
21
+ self.config = config
20
22
 
21
23
  @abstractmethod
22
24
  def transcribe_audio(self, audio_path: Union[str, Path], model: Optional[str] = None, **kwargs) -> str:
@@ -122,4 +124,58 @@ class LollmsSTTBindingManager:
122
124
  list[str]: List of binding names.
123
125
  """
124
126
  return [binding_dir.name for binding_dir in self.stt_bindings_dir.iterdir()
125
- if binding_dir.is_dir() and (binding_dir / "__init__.py").exists()]
127
+ if binding_dir.is_dir() and (binding_dir / "__init__.py").exists()]
128
+
129
+
130
+ @staticmethod
131
+ def _get_fallback_description(binding_name: str) -> Dict:
132
+ return {
133
+ "binding_name": binding_name,
134
+ "title": binding_name.replace("_", " ").title(),
135
+ "author": "Unknown",
136
+ "version": "N/A",
137
+ "description": f"A binding for {binding_name}. No description.yaml file was found.",
138
+ "input_parameters": [
139
+ {
140
+ "name": "model_name",
141
+ "type": "str",
142
+ "description": "The model name or ID to be used.",
143
+ "mandatory": False,
144
+ "default": ""
145
+ }
146
+ ],
147
+ "generate_audio_parameters": []
148
+ }
149
+ @staticmethod
150
+ def get_bindings_list(stt_bindings_dir: Union[str, Path]) -> List[Dict]:
151
+ bindings_dir = Path(stt_bindings_dir)
152
+ if not bindings_dir.is_dir():
153
+ return []
154
+
155
+ bindings_list = []
156
+ for binding_folder in bindings_dir.iterdir():
157
+ if binding_folder.is_dir() and (binding_folder / "__init__.py").exists():
158
+ binding_name = binding_folder.name
159
+ description_file = binding_folder / "description.yaml"
160
+
161
+ binding_info = {}
162
+ if description_file.exists():
163
+ try:
164
+ with open(description_file, 'r', encoding='utf-8') as f:
165
+ binding_info = yaml.safe_load(f)
166
+ binding_info['binding_name'] = binding_name
167
+ except Exception as e:
168
+ print(f"Error loading description.yaml for {binding_name}: {e}")
169
+ binding_info = LollmsSTTBindingManager._get_fallback_description(binding_name)
170
+ else:
171
+ binding_info = LollmsSTTBindingManager._get_fallback_description(binding_name)
172
+
173
+ bindings_list.append(binding_info)
174
+
175
+ return sorted(bindings_list, key=lambda b: b.get('title', b['binding_name']))
176
+
177
+
178
+ def get_available_bindings(stt_bindings_dir: Union[str, Path] = None) -> List[Dict]:
179
+ if stt_bindings_dir is None:
180
+ stt_bindings_dir = Path(__file__).resolve().parent / "stt_bindings"
181
+ return LollmsSTTBindingManager.get_bindings_list(stt_bindings_dir)
@@ -9,7 +9,8 @@ class LollmsTTIBinding(ABC):
9
9
  """Abstract base class for all LOLLMS Text-to-Image bindings."""
10
10
 
11
11
  def __init__(self,
12
- binding_name:str="unknown"):
12
+ binding_name:str="unknown",
13
+ config={}):
13
14
  """
14
15
  Initialize the LollmsTTIBinding base class.
15
16
 
@@ -17,6 +18,7 @@ class LollmsTTIBinding(ABC):
17
18
  binding_name (Optional[str]): The binding name
18
19
  """
19
20
  self.binding_name = binding_name
21
+ self.config = config
20
22
 
21
23
  @abstractmethod
22
24
  def generate_image(self,
@@ -9,7 +9,8 @@ class LollmsTTMBinding(ABC):
9
9
  """Abstract base class for all LOLLMS Text-to-Music bindings."""
10
10
 
11
11
  def __init__(self,
12
- binding_name:str="unknown"):
12
+ binding_name:str="unknown",
13
+ config={}):
13
14
  """
14
15
  Initialize the LollmsTTMBinding base class.
15
16
 
@@ -17,6 +18,7 @@ class LollmsTTMBinding(ABC):
17
18
  binding_name (Optional[str]): The binding name
18
19
  """
19
20
  self.binding_name = binding_name
21
+ self.config = config
20
22
 
21
23
 
22
24
  @abstractmethod
@@ -8,9 +8,9 @@ from ascii_colors import trace_exception
8
8
  class LollmsTTSBinding(ABC):
9
9
  def __init__(self,
10
10
  binding_name: str = "unknown",
11
- **kwargs):
11
+ config={}):
12
12
  self.binding_name = binding_name
13
- self.settings = kwargs
13
+ self.config = config
14
14
 
15
15
  @abstractmethod
16
16
  def generate_audio(self,
@@ -9,7 +9,8 @@ class LollmsTTVBinding(ABC):
9
9
  """Abstract base class for all LOLLMS Text-to-Video bindings."""
10
10
 
11
11
  def __init__(self,
12
- binding_name:str="unknown"):
12
+ binding_name:str="unknown",
13
+ config={}):
13
14
  """
14
15
  Initialize the LollmsTTVBinding base class.
15
16
 
@@ -17,6 +18,7 @@ class LollmsTTVBinding(ABC):
17
18
  binding_name (Optional[str]): The binding name
18
19
  """
19
20
  self.binding_name = binding_name
21
+ self.config = config
20
22
 
21
23
  @abstractmethod
22
24
  def generate_video(self, prompt: str, **kwargs) -> bytes:
@@ -67,7 +67,7 @@ class WhisperSTTBinding(LollmsSTTBinding):
67
67
  """
68
68
 
69
69
  # 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"]
70
+ WHISPER_MODEL_SIZES = ["turbo"]
71
71
 
72
72
  def __init__(self,
73
73
  **kwargs # To catch any other LollmsSTTBinding standard args
@@ -76,12 +76,13 @@ class WhisperSTTBinding(LollmsSTTBinding):
76
76
  Initialize the Whisper STT binding.
77
77
 
78
78
  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".
79
+ model_name (str): The Whisper model size to use (e.g., "turbo").
80
+ Defaults to "turno".
81
81
  device (Optional[str]): The device to run the model on ("cpu", "cuda", "mps").
82
82
  If None, `torch` will attempt to auto-detect. Defaults to None.
83
83
  """
84
84
  super().__init__(binding_name="whisper") # Not applicable
85
+ self.default_model_name = kwargs.get("model_name", "turno")
85
86
 
86
87
  if not _whisper_installed:
87
88
  raise ImportError(f"Whisper STT binding dependencies not met. Please ensure 'openai-whisper' and 'torch' are installed. Error: {_whisper_installation_error}")
@@ -99,12 +100,15 @@ class WhisperSTTBinding(LollmsSTTBinding):
99
100
 
100
101
  self.loaded_model_name = None
101
102
  self.model = None
102
- self._load_whisper_model(kwargs.get("model_name", "base")) # Default to "base" if not specified
103
+ try:
104
+ self._load_whisper_model(kwargs.get("model_name", "turbo")) # Default to "turno" if not specified
105
+ except Exception as e:
106
+ pass
103
107
 
104
108
 
105
109
  def _load_whisper_model(self, model_name_to_load: str):
106
110
  """Loads or reloads the Whisper model."""
107
- if model_name_to_load not in self.WHISPER_MODEL_SIZES:
111
+ if model_name_to_load not in whisper.available_models():
108
112
  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
113
 
110
114
  if self.model is not None and self.loaded_model_name == model_name_to_load:
@@ -149,6 +153,10 @@ class WhisperSTTBinding(LollmsSTTBinding):
149
153
  RuntimeError: If the Whisper model is not loaded or transcription fails.
150
154
  Exception: For other errors during transcription.
151
155
  """
156
+ if not self.model:
157
+ self._load_whisper_model(self.default_model_name)
158
+
159
+
152
160
  audio_file = Path(audio_path)
153
161
  if not audio_file.exists():
154
162
  raise FileNotFoundError(f"Audio file not found at: {audio_path}")
@@ -191,8 +199,8 @@ class WhisperSTTBinding(LollmsSTTBinding):
191
199
  trace_exception(e)
192
200
  raise Exception(f"Whisper transcription error: {e}") from e
193
201
 
194
-
195
- def list_models(self, **kwargs) -> List[str]:
202
+ @staticmethod
203
+ def list_models(**kwargs) -> List[str]:
196
204
  """
197
205
  Lists the available standard Whisper model sizes.
198
206
 
@@ -202,7 +210,7 @@ class WhisperSTTBinding(LollmsSTTBinding):
202
210
  Returns:
203
211
  List[str]: A list of available Whisper model size identifiers.
204
212
  """
205
- return self.WHISPER_MODEL_SIZES.copy() # Return a copy
213
+ return whisper.available_models() # Return a copy
206
214
 
207
215
  def __del__(self):
208
216
  """Clean up: Unload the model to free resources."""
@@ -252,7 +260,7 @@ if __name__ == '__main__':
252
260
  else:
253
261
  try:
254
262
  ASCIIColors.cyan("\n--- Initializing WhisperSTTBinding (model: 'tiny') ---")
255
- # Using 'tiny' model for faster testing. Change to 'base' or 'small' for better quality.
263
+ # Using 'tiny' model for faster testing. Change to 'turno' or 'small' for better quality.
256
264
  stt_binding = WhisperSTTBinding(model_name="tiny")
257
265
 
258
266
  ASCIIColors.cyan("\n--- Listing available Whisper models ---")
@@ -269,9 +277,9 @@ if __name__ == '__main__':
269
277
  # print(f"Transcription (tiny, lang='en'): '{transcription_lang_hint}'")
270
278
 
271
279
  # 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}'")
280
+ # ASCIIColors.cyan(f"\n--- Transcribing '{test_audio_file.name}' by switching to 'turno' model ---")
281
+ # transcription_base = stt_binding.transcribe_audio(test_audio_file, model="turno")
282
+ # print(f"Transcription (turno): '{transcription_base}'")
275
283
 
276
284
 
277
285
  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
+
@@ -36,16 +36,15 @@ class DiffusersBinding(LollmsTTIBinding):
36
36
  """
37
37
  def __init__(self,
38
38
  **kwargs):
39
-
40
- super().__init__(binding_name=BindingName)
41
-
42
39
  # Prioritize 'model_name' but accept 'model' as an alias from config files.
43
40
  if 'model' in kwargs and 'model_name' not in kwargs:
44
41
  kwargs['model_name'] = kwargs.pop('model')
42
+ super().__init__(binding_name=BindingName, config=kwargs)
43
+
44
+
45
45
 
46
- self.config = kwargs
47
46
  self.host = kwargs.get("host", "localhost")
48
- self.port = kwargs.get("port", 9630)
47
+ self.port = kwargs.get("port", 9632)
49
48
  self.auto_start_server = kwargs.get("auto_start_server", True)
50
49
  self.server_process = None
51
50
  self.base_url = f"http://{self.host}:{self.port}"
@@ -61,7 +60,7 @@ class DiffusersBinding(LollmsTTIBinding):
61
60
  def is_server_running(self) -> bool:
62
61
  """Checks if the server is already running and responsive."""
63
62
  try:
64
- response = requests.get(f"{self.base_url}/status", timeout=2)
63
+ response = requests.get(f"{self.base_url}/status", timeout=4)
65
64
  if response.status_code == 200 and response.json().get("status") == "running":
66
65
  return True
67
66
  except requests.exceptions.RequestException:
@@ -90,7 +89,7 @@ class DiffusersBinding(LollmsTTIBinding):
90
89
  try:
91
90
  # Try to acquire the lock with a timeout. If another process is starting
92
91
  # the server, this will wait until it's finished.
93
- with lock.acquire(timeout=60):
92
+ with lock.acquire(timeout=3):
94
93
  # After acquiring the lock, we MUST re-check if the server is running.
95
94
  # Another process might have started it and released the lock while we were waiting.
96
95
  if not self.is_server_running():
@@ -105,7 +104,7 @@ class DiffusersBinding(LollmsTTIBinding):
105
104
  # This happens if the process holding the lock takes more than 60 seconds to start the server.
106
105
  # We don't try to start another one. We just wait for the existing one to be ready.
107
106
  ASCIIColors.yellow("Could not acquire lock, another process is taking a long time to start the server. Waiting...")
108
- self._wait_for_server(timeout=300) # Give it a longer timeout here just in case.
107
+ self._wait_for_server(timeout=60) # Give it a longer timeout here just in case.
109
108
 
110
109
  # A final verification to ensure we are connected.
111
110
  if not self.is_server_running():
@@ -214,7 +213,7 @@ class DiffusersBinding(LollmsTTIBinding):
214
213
  self.server_process = subprocess.Popen(command, creationflags=creationflags)
215
214
  ASCIIColors.info("Diffusers server process launched in the background.")
216
215
 
217
- def _wait_for_server(self, timeout=300):
216
+ def _wait_for_server(self, timeout=30):
218
217
  """Waits for the server to become responsive."""
219
218
  ASCIIColors.info("Waiting for Diffusers server to become available...")
220
219
  start_time = time.time()
@@ -374,4 +373,4 @@ class DiffusersBinding(LollmsTTIBinding):
374
373
  def __del__(self):
375
374
  # The client destructor does not stop the server,
376
375
  # as it is a shared resource for all worker processes.
377
- pass
376
+ pass
@@ -60,66 +60,14 @@ MODELS_PATH = Path("./models")
60
60
 
61
61
  # --- START: Core Logic (Complete and Unabridged) ---
62
62
  CIVITAI_MODELS = {
63
- "realistic-vision-v6": {
64
- "display_name": "Realistic Vision V6.0", "url": "https://civitai.com/api/download/models/501240?type=Model&format=SafeTensor&size=pruned&fp=fp16",
65
- "filename": "realisticVisionV60_v60B1.safetensors", "description": "Photorealistic SD1.5 checkpoint.", "owned_by": "civitai"
66
- },
67
- "absolute-reality": {
68
- "display_name": "Absolute Reality", "url": "https://civitai.com/api/download/models/132760?type=Model&format=SafeTensor&size=pruned&fp=fp16",
69
- "filename": "absolutereality_v181.safetensors", "description": "General realistic SD1.5.", "owned_by": "civitai"
70
- },
71
- "dreamshaper-8": {
63
+ "DreamShaper-8": {
72
64
  "display_name": "DreamShaper 8", "url": "https://civitai.com/api/download/models/128713",
73
65
  "filename": "dreamshaper_8.safetensors", "description": "Versatile SD1.5 style model.", "owned_by": "civitai"
74
66
  },
75
- "juggernaut-xl": {
67
+ "Juggernaut-xl": {
76
68
  "display_name": "Juggernaut XL", "url": "https://civitai.com/api/download/models/133005",
77
69
  "filename": "juggernautXL_version6Rundiffusion.safetensors", "description": "Artistic SDXL.", "owned_by": "civitai"
78
70
  },
79
- "lyriel-v1.6": {
80
- "display_name": "Lyriel v1.6", "url": "https://civitai.com/api/download/models/72396?type=Model&format=SafeTensor&size=full&fp=fp16",
81
- "filename": "lyriel_v16.safetensors", "description": "Fantasy/stylized SD1.5.", "owned_by": "civitai"
82
- },
83
- "ui_icons": {
84
- "display_name": "UI Icons", "url": "https://civitai.com/api/download/models/367044?type=Model&format=SafeTensor&size=full&fp=fp16",
85
- "filename": "uiIcons_v10.safetensors", "description": "A model for generating UI icons.", "owned_by": "civitai"
86
- },
87
- "meinamix": {
88
- "display_name": "MeinaMix", "url": "https://civitai.com/api/download/models/948574?type=Model&format=SafeTensor&size=pruned&fp=fp16",
89
- "filename": "meinamix_meinaV11.safetensors", "description": "Anime/illustration SD1.5.", "owned_by": "civitai"
90
- },
91
- "rpg-v5": {
92
- "display_name": "RPG v5", "url": "https://civitai.com/api/download/models/124626?type=Model&format=SafeTensor&size=pruned&fp=fp16",
93
- "filename": "rpg_v5.safetensors", "description": "RPG assets SD1.5.", "owned_by": "civitai"
94
- },
95
- "pixel-art-xl": {
96
- "display_name": "Pixel Art XL", "url": "https://civitai.com/api/download/models/135931?type=Model&format=SafeTensor",
97
- "filename": "pixelartxl_v11.safetensors", "description": "Pixel art SDXL.", "owned_by": "civitai"
98
- },
99
- "lowpoly-world": {
100
- "display_name": "Lowpoly World", "url": "https://civitai.com/api/download/models/146502?type=Model&format=SafeTensor",
101
- "filename": "LowpolySDXL.safetensors", "description": "Lowpoly style SD1.5.", "owned_by": "civitai"
102
- },
103
- "toonyou": {
104
- "display_name": "ToonYou", "url": "https://civitai.com/api/download/models/125771?type=Model&format=SafeTensor&size=pruned&fp=fp16",
105
- "filename": "toonyou_beta6.safetensors", "description": "Cartoon/Disney SD1.5.", "owned_by": "civitai"
106
- },
107
- "papercut": {
108
- "display_name": "Papercut", "url": "https://civitai.com/api/download/models/133503?type=Model&format=SafeTensor",
109
- "filename": "papercut.safetensors", "description": "Paper cutout SD1.5.", "owned_by": "civitai"
110
- },
111
- "fantassifiedIcons": {
112
- "display_name": "Fantassified Icons", "url": "https://civitai.com/api/download/models/67584?type=Model&format=SafeTensor&size=pruned&fp=fp16",
113
- "filename": "fantassifiedIcons_fantassifiedIconsV20.safetensors", "description": "Flat, modern Icons.", "owned_by": "civitai"
114
- },
115
- "game_icon_institute": {
116
- "display_name": "Game icon institute", "url": "https://civitai.com/api/download/models/158776?type=Model&format=SafeTensor&size=full&fp=fp16",
117
- "filename": "gameIconInstituteV10_v10.safetensors", "description": "Flat, modern game Icons.", "owned_by": "civitai"
118
- },
119
- "M4RV3LS_DUNGEONS": {
120
- "display_name": "M4RV3LS & DUNGEONS", "url": "https://civitai.com/api/download/models/139417?type=Model&format=SafeTensor&size=pruned&fp=fp16",
121
- "filename": "M4RV3LSDUNGEONSNEWV40COMICS_mD40.safetensors", "description": "comics.", "owned_by": "civitai"
122
- },
123
71
  }
124
72
 
125
73
  HF_PUBLIC_MODELS = {
@@ -183,6 +131,7 @@ SCHEDULER_MAPPING = {
183
131
  "dpm2_karras": "KDPM2DiscreteScheduler", "dpm2_a": "KDPM2AncestralDiscreteScheduler", "dpm2_a_karras": "KDPM2AncestralDiscreteScheduler",
184
132
  "euler": "EulerDiscreteScheduler", "euler_a": "EulerAncestralDiscreteScheduler", "heun": "HeunDiscreteScheduler", "lms": "LMSDiscreteScheduler"
185
133
  }
134
+
186
135
  SCHEDULER_USES_KARRAS_SIGMAS = [
187
136
  "dpm_multistep_karras","dpm++_2m_karras","dpm++_2s_ancestral_karras", "dpm++_sde_karras","heun_karras","lms_karras",
188
137
  "dpm++_2m_sde_karras","dpm2_karras","dpm2_a_karras"
@@ -604,7 +553,7 @@ class ServerState:
604
553
  return {
605
554
  "model_name": "", "device": "auto", "torch_dtype_str": "auto", "use_safetensors": True,
606
555
  "scheduler_name": "default", "safety_checker_on": True, "num_inference_steps": 25,
607
- "guidance_scale": 7.0, "width": 512, "height": 512, "seed": -1,
556
+ "guidance_scale": 7.0, "width": 1024, "height": 1024, "seed": -1,
608
557
  "enable_cpu_offload": False, "enable_sequential_cpu_offload": False, "enable_xformers": False,
609
558
  "hf_variant": None, "hf_token": None, "hf_cache_path": None, "local_files_only": False,
610
559
  "unload_inactive_model_after": 0
@@ -749,8 +698,8 @@ async def generate_image(request: T2IRequest):
749
698
  # Add prompts and ensure types for specific args
750
699
  pipeline_args["prompt"] = request.prompt
751
700
  pipeline_args["negative_prompt"] = request.negative_prompt
752
- pipeline_args["width"] = int(pipeline_args.get("width", 512))
753
- pipeline_args["height"] = int(pipeline_args.get("height", 512))
701
+ pipeline_args["width"] = int(pipeline_args.get("width", 1024))
702
+ pipeline_args["height"] = int(pipeline_args.get("height", 1024))
754
703
  pipeline_args["num_inference_steps"] = int(pipeline_args.get("num_inference_steps", 25))
755
704
  pipeline_args["guidance_scale"] = float(pipeline_args.get("guidance_scale", 7.0))
756
705
 
@@ -800,6 +749,8 @@ async def generate_image(request: T2IRequest):
800
749
  async def edit_image(request: EditRequestJSON):
801
750
  manager = None
802
751
  temp_config = None
752
+ ASCIIColors.info(f"Received /edit_image request with {len(request.images_b64)} image(s).")
753
+ ASCIIColors.info(request.params)
803
754
  try:
804
755
  if "model_name" in request.params and request.params["model_name"]:
805
756
  temp_config = state.config.copy()
@@ -843,7 +794,7 @@ async def edit_image(request: EditRequestJSON):
843
794
  edit_mode = pipeline_args.get("edit_mode", "fusion")
844
795
  if edit_mode == "fusion": pipeline_args["image"] = pil_images
845
796
  else:
846
- pipeline_args.update({"image": pil_images[0], "strength": 0.8, "guidance_scale": 7.5, "num_inference_steps": 25})
797
+ pipeline_args.update({"image": pil_images[0]})
847
798
 
848
799
  log_args = {k: v for k, v in pipeline_args.items() if k not in ['generator', 'image', 'mask_image']}
849
800
  if pipeline_args.get("generator"): log_args['generator'] = f"<torch.Generator(seed={seed})>"
@@ -989,4 +940,4 @@ if __name__ == "__main__":
989
940
  else:
990
941
  ASCIIColors.info(f"Detected device: {state.config['device']}")
991
942
 
992
- uvicorn.run(app, host=args.host, port=args.port, reload=False)
943
+ uvicorn.run(app, host=args.host, port=args.port, reload=False)
@@ -69,7 +69,10 @@ def _load_image_from_str(image_str: str) -> bytes:
69
69
 
70
70
  class GeminiTTIBinding_Impl(LollmsTTIBinding):
71
71
  def __init__(self, **kwargs):
72
- super().__init__(binding_name="gemini")
72
+ # Prioritize 'model_name' but accept 'model' as an alias from config files.
73
+ if 'model' in kwargs and 'model_name' not in kwargs:
74
+ kwargs['model_name'] = kwargs.pop('model')
75
+ super().__init__(binding_name=BindingName, config=kwargs)
73
76
  self.auth_method = kwargs.get("auth_method", "vertex_ai")
74
77
  self.client: Optional[Any] = None
75
78
  self.available_models = []
@@ -29,8 +29,11 @@ class LeonardoAITTIBinding(LollmsTTIBinding):
29
29
  """Leonardo.ai TTI binding for LoLLMS"""
30
30
 
31
31
  def __init__(self, **kwargs):
32
- super().__init__(binding_name=BindingName)
33
- self.config = kwargs
32
+ # Prioritize 'model_name' but accept 'model' as an alias from config files.
33
+ if 'model' in kwargs and 'model_name' not in kwargs:
34
+ kwargs['model_name'] = kwargs.pop('model')
35
+ super().__init__(binding_name=BindingName, config=kwargs)
36
+
34
37
  self.api_key = self.config.get("api_key") or os.environ.get("LEONARDO_API_KEY")
35
38
  if not self.api_key:
36
39
  raise ValueError("Leonardo.ai API key is required.")
@@ -23,7 +23,10 @@ class LollmsWebuiTTIBinding_Impl(LollmsTTIBinding):
23
23
  service_key (Optional[str]): Authentication key (used for client_id verification).
24
24
  verify_ssl_certificate (bool): Whether to verify SSL certificates.
25
25
  """
26
- super().__init__(binding_name="lollms")
26
+ # Prioritize 'model_name' but accept 'model' as an alias from config files.
27
+ if 'model' in kwargs and 'model_name' not in kwargs:
28
+ kwargs['model_name'] = kwargs.pop('model')
29
+ super().__init__(binding_name=BindingName, config=kwargs)
27
30
 
28
31
  # Extract parameters from kwargs, providing defaults
29
32
  self.host_address = kwargs.get("host_address", "http://localhost:9600") # Default LOLLMS host
@@ -27,7 +27,10 @@ class NovitaAITTIBinding(LollmsTTIBinding):
27
27
  """Novita.ai TTI binding for LoLLMS"""
28
28
 
29
29
  def __init__(self, **kwargs):
30
- super().__init__(binding_name=BindingName)
30
+ # Prioritize 'model_name' but accept 'model' as an alias from config files.
31
+ if 'model' in kwargs and 'model_name' not in kwargs:
32
+ kwargs['model_name'] = kwargs.pop('model')
33
+ super().__init__(binding_name=BindingName, config=kwargs)
31
34
  self.config = kwargs
32
35
  self.api_key = self.config.get("api_key") or os.environ.get("NOVITA_API_KEY")
33
36
  if not self.api_key:
@@ -6,7 +6,7 @@ from io import BytesIO
6
6
  from ascii_colors import trace_exception
7
7
  from openai import OpenAI
8
8
  from lollms_client.lollms_tti_binding import LollmsTTIBinding
9
-
9
+ import os
10
10
  BindingName = "OpenAITTIBinding"
11
11
 
12
12
 
@@ -50,19 +50,18 @@ class OpenAITTIBinding(LollmsTTIBinding):
50
50
 
51
51
  def __init__(
52
52
  self,
53
- model: str = "gpt-image-1",
54
- api_key: Optional[str] = None,
55
- size: str = "1024x1024",
56
- n: int = 1,
57
- quality: str = "standard",
58
53
  **kwargs,
59
54
  ):
60
- self.client = OpenAI(api_key=api_key)
55
+ # Prioritize 'model_name' but accept 'model' as an alias from config files.
56
+ if 'model' in kwargs and 'model_name' not in kwargs:
57
+ kwargs['model_name'] = kwargs.pop('model')
58
+ super().__init__(binding_name=BindingName, config=kwargs)
59
+ self.client = OpenAI(api_key=kwargs.get("api_key" or os.environ.get("OPENAI_API_KEY")))
61
60
  self.global_params = {
62
- "model": model,
63
- "size": size,
64
- "n": n,
65
- "quality": quality,
61
+ "model": kwargs.get("model_name") or "gpt-image-1",
62
+ "size": kwargs.get("size", "1024x1024"),
63
+ "n": kwargs.get("n", 1),
64
+ "quality": kwargs.get("quality", "standard"),
66
65
  }
67
66
 
68
67
  def _resolve_param(self, name: str, kwargs: Dict[str, Any], default: Any) -> Any:
@@ -33,8 +33,10 @@ class StabilityAITTIBinding(LollmsTTIBinding):
33
33
  """Stability AI TTI binding for LoLLMS"""
34
34
 
35
35
  def __init__(self, **kwargs):
36
- super().__init__(binding_name=BindingName)
37
- self.config = kwargs
36
+ # Prioritize 'model_name' but accept 'model' as an alias from config files.
37
+ if 'model' in kwargs and 'model_name' not in kwargs:
38
+ kwargs['model_name'] = kwargs.pop('model')
39
+ super().__init__(binding_name=BindingName, config=kwargs)
38
40
  self.api_key = self.config.get("api_key") or os.environ.get("STABILITY_API_KEY")
39
41
  if not self.api_key:
40
42
  raise ValueError("Stability AI API key is required. Please set it in the configuration or as STABILITY_API_KEY environment variable.")
@@ -75,21 +75,16 @@ DEFAULT_AUDIOCRAFT_MODELS = [
75
75
 
76
76
  class AudioCraftTTMBinding(LollmsTTMBinding):
77
77
  def __init__(self,
78
- model_name: str = "facebook/musicgen-small", # HF ID or local path
79
- device: Optional[str] = None, # "cpu", "cuda", "mps", or None for auto
80
- output_format: str = "wav", # 'wav', 'mp3' (mp3 needs ffmpeg via audiocraft)
81
- # Catch LollmsTTMBinding standard args
82
- host_address: Optional[str] = None, # Not used by local binding
83
- service_key: Optional[str] = None, # Not used by local binding
84
- verify_ssl_certificate: bool = True,# Not used by local binding
85
- **kwargs): # Catch-all for future compatibility or specific audiocraft params
86
-
87
- super().__init__(binding_name="audiocraft")
78
+ **kwargs):
79
+ # Prioritize 'model_name' but accept 'model' as an alias from config files.
80
+ if 'model' in kwargs and 'model_name' not in kwargs:
81
+ kwargs['model_name'] = kwargs.pop('model')
82
+ super().__init__(binding_name=BindingName, config=kwargs)
88
83
 
89
84
  if not _audiocraft_installed_with_correct_torch:
90
85
  raise ImportError(f"AudioCraft TTM binding dependencies not met. Please ensure 'audiocraft', 'torch', 'torchaudio', 'scipy', 'numpy' are installed. Error: {_audiocraft_installation_error}")
91
86
 
92
- self.device = device
87
+ self.device = kwargs.get("device") # "cuda", "mps", "cpu", or None for auto-detect
93
88
  if self.device is None: # Auto-detect if not specified by user
94
89
  if torch.cuda.is_available():
95
90
  self.device = "cuda"
@@ -117,7 +112,7 @@ class AudioCraftTTMBinding(LollmsTTMBinding):
117
112
  ASCIIColors.warning(f"Unsupported output_format '{self.output_format}'. Defaulting to 'wav'.")
118
113
  self.output_format = "wav"
119
114
 
120
- self._load_audiocraft_model(model_name)
115
+ self._load_audiocraft_model(kwargs.get("model_name") or "facebook/musicgen-small")
121
116
 
122
117
  def _load_audiocraft_model(self, model_name_to_load: str):
123
118
  if self.model is not None and self.loaded_model_name == model_name_to_load:
@@ -16,9 +16,13 @@ BindingName = "BeatovenAITTMBinding"
16
16
  class BeatovenAITTMBinding(LollmsTTMBinding):
17
17
  """A Text-to-Music binding for the Beatoven.ai API."""
18
18
 
19
- def __init__(self, **kwargs):
20
- super().__init__(binding_name=BindingName, **kwargs)
21
- self.api_key = self.settings.get("api_key") or os.environ.get("BEATOVEN_API_KEY")
19
+ def __init__(self,
20
+ **kwargs):
21
+ # Prioritize 'model_name' but accept 'model' as an alias from config files.
22
+ if 'model' in kwargs and 'model_name' not in kwargs:
23
+ kwargs['model_name'] = kwargs.pop('model')
24
+ super().__init__(binding_name=BindingName, config=kwargs)
25
+ self.api_key = self.config.get("api_key") or os.environ.get("BEATOVEN_API_KEY")
22
26
  if not self.api_key:
23
27
  raise ValueError("Beatoven.ai API key is required. Please set it in config or as BEATOVEN_API_KEY env var.")
24
28
  self.base_url = "https://api.beatoven.ai/api/v1"