lollms-client 1.4.0__py3-none-any.whl → 1.4.5__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.
- lollms_client/__init__.py +1 -1
- lollms_client/llm_bindings/novita_ai/__init__.py +303 -0
- lollms_client/llm_bindings/perplexity/__init__.py +326 -0
- lollms_client/lollms_core.py +678 -78
- lollms_client/lollms_discussion.py +13 -151
- lollms_client/tti_bindings/diffusers/__init__.py +34 -12
- lollms_client/tti_bindings/leonardo_ai/__init__.py +124 -0
- lollms_client/tti_bindings/novita_ai/__init__.py +102 -0
- lollms_client/tti_bindings/stability_ai/__init__.py +176 -0
- {lollms_client-1.4.0.dist-info → lollms_client-1.4.5.dist-info}/METADATA +1 -1
- {lollms_client-1.4.0.dist-info → lollms_client-1.4.5.dist-info}/RECORD +14 -9
- {lollms_client-1.4.0.dist-info → lollms_client-1.4.5.dist-info}/WHEEL +0 -0
- {lollms_client-1.4.0.dist-info → lollms_client-1.4.5.dist-info}/licenses/LICENSE +0 -0
- {lollms_client-1.4.0.dist-info → lollms_client-1.4.5.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import requests
|
|
3
|
+
import base64
|
|
4
|
+
from io import BytesIO
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Optional, List, Dict, Any, Union
|
|
7
|
+
|
|
8
|
+
from lollms_client.lollms_tti_binding import LollmsTTIBinding
|
|
9
|
+
from ascii_colors import trace_exception, ASCIIColors
|
|
10
|
+
import pipmaster as pm
|
|
11
|
+
|
|
12
|
+
pm.ensure_packages(["requests", "Pillow"])
|
|
13
|
+
|
|
14
|
+
from PIL import Image
|
|
15
|
+
|
|
16
|
+
BindingName = "StabilityAITTIBinding"
|
|
17
|
+
|
|
18
|
+
# Sourced from https://platform.stability.ai/docs/getting-started/models
|
|
19
|
+
STABILITY_AI_MODELS = [
|
|
20
|
+
# SD3
|
|
21
|
+
{"model_name": "stable-diffusion-3-medium", "display_name": "Stable Diffusion 3 Medium", "description": "Most advanced text-to-image model.", "owned_by": "Stability AI"},
|
|
22
|
+
{"model_name": "stable-diffusion-3-large", "display_name": "Stable Diffusion 3 Large", "description": "Most advanced model with higher quality.", "owned_by": "Stability AI"},
|
|
23
|
+
{"model_name": "stable-diffusion-3-large-turbo", "display_name": "Stable Diffusion 3 Large Turbo", "description": "Fast, high-quality generation.", "owned_by": "Stability AI"},
|
|
24
|
+
# SDXL
|
|
25
|
+
{"model_name": "stable-diffusion-xl-1024-v1-0", "display_name": "Stable Diffusion XL 1.0", "description": "High-quality 1024x1024 generation.", "owned_by": "Stability AI"},
|
|
26
|
+
{"model_name": "stable-diffusion-xl-beta-v2-2-2", "display_name": "SDXL Beta", "description": "Legacy anime-focused SDXL model.", "owned_by": "Stability AI"},
|
|
27
|
+
# SD 1.x & 2.x
|
|
28
|
+
{"model_name": "stable-diffusion-v1-6", "display_name": "Stable Diffusion 1.6", "description": "Improved version of SD 1.5.", "owned_by": "Stability AI"},
|
|
29
|
+
{"model_name": "stable-diffusion-2-1", "display_name": "Stable Diffusion 2.1", "description": "768x768 native resolution model.", "owned_by": "Stability AI"},
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
class StabilityAITTIBinding(LollmsTTIBinding):
|
|
33
|
+
"""Stability AI TTI binding for LoLLMS"""
|
|
34
|
+
|
|
35
|
+
def __init__(self, **kwargs):
|
|
36
|
+
super().__init__(binding_name=BindingName)
|
|
37
|
+
self.config = kwargs
|
|
38
|
+
self.api_key = self.config.get("api_key") or os.environ.get("STABILITY_API_KEY")
|
|
39
|
+
if not self.api_key:
|
|
40
|
+
raise ValueError("Stability AI API key is required. Please set it in the configuration or as STABILITY_API_KEY environment variable.")
|
|
41
|
+
self.model_name = self.config.get("model_name", "stable-diffusion-3-medium")
|
|
42
|
+
|
|
43
|
+
def listModels(self) -> list:
|
|
44
|
+
return STABILITY_AI_MODELS
|
|
45
|
+
|
|
46
|
+
def _get_api_url(self, task: str) -> str:
|
|
47
|
+
base_url = "https://api.stability.ai/v2beta/stable-image"
|
|
48
|
+
# SD3 models use a different endpoint structure
|
|
49
|
+
if "stable-diffusion-3" in self.model_name:
|
|
50
|
+
return f"{base_url}/generate/sd3"
|
|
51
|
+
|
|
52
|
+
task_map = {
|
|
53
|
+
"text2image": "generate/core",
|
|
54
|
+
"image2image": "edit/image-to-image",
|
|
55
|
+
"inpainting": "edit/in-painting",
|
|
56
|
+
"upscale": "edit/upscale"
|
|
57
|
+
}
|
|
58
|
+
if task not in task_map:
|
|
59
|
+
raise ValueError(f"Unsupported task for this model family: {task}")
|
|
60
|
+
return f"{base_url}/{task_map[task]}"
|
|
61
|
+
|
|
62
|
+
def _decode_image_input(self, item: Union[str, Path, bytes]) -> Image.Image:
|
|
63
|
+
if isinstance(item, bytes):
|
|
64
|
+
return Image.open(BytesIO(item))
|
|
65
|
+
s = str(item).strip()
|
|
66
|
+
if s.startswith("data:image/") and ";base64," in s:
|
|
67
|
+
b64 = s.split(";base64,")[-1]
|
|
68
|
+
return Image.open(BytesIO(base64.b64decode(b64)))
|
|
69
|
+
try:
|
|
70
|
+
p = Path(s)
|
|
71
|
+
if p.exists():
|
|
72
|
+
return Image.open(p)
|
|
73
|
+
except:
|
|
74
|
+
pass
|
|
75
|
+
if s.startswith("http"):
|
|
76
|
+
response = requests.get(s, stream=True)
|
|
77
|
+
response.raise_for_status()
|
|
78
|
+
return Image.open(response.raw)
|
|
79
|
+
# Fallback for raw base64
|
|
80
|
+
return Image.open(BytesIO(base64.b64decode(s)))
|
|
81
|
+
|
|
82
|
+
def generate_image(self, prompt: str, negative_prompt: str = "", width: int = 1024, height: int = 1024, **kwargs) -> bytes:
|
|
83
|
+
url = self._get_api_url("text2image")
|
|
84
|
+
|
|
85
|
+
data = {
|
|
86
|
+
"prompt": prompt,
|
|
87
|
+
"negative_prompt": negative_prompt,
|
|
88
|
+
"output_format": "png",
|
|
89
|
+
"seed": kwargs.get("seed", 0)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
# SD3 uses aspect_ratio, older models use width/height
|
|
93
|
+
if "stable-diffusion-3" in self.model_name:
|
|
94
|
+
data["aspect_ratio"] = f"{width}:{height}"
|
|
95
|
+
data["model"] = self.model_name
|
|
96
|
+
else:
|
|
97
|
+
data["width"] = width
|
|
98
|
+
data["height"] = height
|
|
99
|
+
data["style_preset"] = kwargs.get("style_preset", "photographic")
|
|
100
|
+
|
|
101
|
+
headers = {"authorization": f"Bearer {self.api_key}", "accept": "image/*"}
|
|
102
|
+
|
|
103
|
+
try:
|
|
104
|
+
ASCIIColors.info(f"Requesting image from Stability AI ({self.model_name})...")
|
|
105
|
+
response = requests.post(url, headers=headers, files={"none": ''}, data=data)
|
|
106
|
+
response.raise_for_status()
|
|
107
|
+
return response.content
|
|
108
|
+
except Exception as e:
|
|
109
|
+
trace_exception(e)
|
|
110
|
+
try:
|
|
111
|
+
error_msg = response.json()
|
|
112
|
+
raise Exception(f"Stability AI API error: {error_msg}")
|
|
113
|
+
except:
|
|
114
|
+
raise Exception(f"Stability AI API request failed: {e}")
|
|
115
|
+
|
|
116
|
+
def edit_image(self, images: Union[str, List[str]], prompt: str, negative_prompt: Optional[str] = "", mask: Optional[str] = None, **kwargs) -> bytes:
|
|
117
|
+
init_image_bytes = BytesIO()
|
|
118
|
+
init_image = self._decode_image_input(images[0] if isinstance(images, list) else images)
|
|
119
|
+
init_image.save(init_image_bytes, format="PNG")
|
|
120
|
+
|
|
121
|
+
task = "inpainting" if mask else "image2image"
|
|
122
|
+
url = self._get_api_url(task)
|
|
123
|
+
|
|
124
|
+
files = {"image": init_image_bytes.getvalue()}
|
|
125
|
+
data = {
|
|
126
|
+
"prompt": prompt,
|
|
127
|
+
"negative_prompt": negative_prompt or "",
|
|
128
|
+
"output_format": "png",
|
|
129
|
+
"seed": kwargs.get("seed", 0)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if task == "inpainting":
|
|
133
|
+
mask_image_bytes = BytesIO()
|
|
134
|
+
mask_image = self._decode_image_input(mask)
|
|
135
|
+
mask_image.save(mask_image_bytes, format="PNG")
|
|
136
|
+
files["mask"] = mask_image_bytes.getvalue()
|
|
137
|
+
else: # image2image
|
|
138
|
+
data["strength"] = kwargs.get("strength", 0.6) # mode IMAGE_STRENGTH
|
|
139
|
+
|
|
140
|
+
headers = {"authorization": f"Bearer {self.api_key}", "accept": "image/*"}
|
|
141
|
+
|
|
142
|
+
try:
|
|
143
|
+
ASCIIColors.info(f"Requesting image edit from Stability AI ({self.model_name})...")
|
|
144
|
+
response = requests.post(url, headers=headers, files=files, data=data)
|
|
145
|
+
response.raise_for_status()
|
|
146
|
+
return response.content
|
|
147
|
+
except Exception as e:
|
|
148
|
+
trace_exception(e)
|
|
149
|
+
try:
|
|
150
|
+
error_msg = response.json()
|
|
151
|
+
raise Exception(f"Stability AI API error: {error_msg}")
|
|
152
|
+
except:
|
|
153
|
+
raise Exception(f"Stability AI API request failed: {e}")
|
|
154
|
+
|
|
155
|
+
if __name__ == '__main__':
|
|
156
|
+
ASCIIColors.magenta("--- Stability AI TTI Binding Test ---")
|
|
157
|
+
if "STABILITY_API_KEY" not in os.environ:
|
|
158
|
+
ASCIIColors.error("STABILITY_API_KEY environment variable not set. Cannot run test.")
|
|
159
|
+
exit(1)
|
|
160
|
+
|
|
161
|
+
try:
|
|
162
|
+
binding = StabilityAITTIBinding(model_name="stable-diffusion-3-medium")
|
|
163
|
+
|
|
164
|
+
ASCIIColors.cyan("\n--- Test: Text-to-Image ---")
|
|
165
|
+
prompt = "a cinematic photo of a robot drinking coffee in a Parisian cafe"
|
|
166
|
+
img_bytes = binding.generate_image(prompt, width=1024, height=1024)
|
|
167
|
+
|
|
168
|
+
assert len(img_bytes) > 1000, "Generated image bytes are too small."
|
|
169
|
+
output_path = Path(__file__).parent / "tmp_stability_t2i.png"
|
|
170
|
+
with open(output_path, "wb") as f:
|
|
171
|
+
f.write(img_bytes)
|
|
172
|
+
ASCIIColors.green(f"Text-to-Image generation OK. Image saved to {output_path}")
|
|
173
|
+
|
|
174
|
+
except Exception as e:
|
|
175
|
+
trace_exception(e)
|
|
176
|
+
ASCIIColors.error(f"Stability AI binding test failed: {e}")
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
lollms_client/__init__.py,sha256=
|
|
1
|
+
lollms_client/__init__.py,sha256=1ATuXFW5bb2NSxUu0nl6c3tXgX30-GS0pYWv6hkA8Vg,1146
|
|
2
2
|
lollms_client/lollms_agentic.py,sha256=pQiMEuB_XkG29-SW6u4KTaMFPr6eKqacInggcCuCW3k,13914
|
|
3
3
|
lollms_client/lollms_config.py,sha256=goEseDwDxYJf3WkYJ4IrLXwg3Tfw73CXV2Avg45M_hE,21876
|
|
4
|
-
lollms_client/lollms_core.py,sha256=
|
|
5
|
-
lollms_client/lollms_discussion.py,sha256=
|
|
4
|
+
lollms_client/lollms_core.py,sha256=aCEoxmEF6ZmkBgJgZd74lKkM4A3PVVyt2IwMvLfScWw,315053
|
|
5
|
+
lollms_client/lollms_discussion.py,sha256=jWw1lSq0Oz_X5pnkECf1XwdDP2Lf84im00VpwuvsXXk,123041
|
|
6
6
|
lollms_client/lollms_js_analyzer.py,sha256=01zUvuO2F_lnUe_0NLxe1MF5aHE1hO8RZi48mNPv-aw,8361
|
|
7
7
|
lollms_client/lollms_llm_binding.py,sha256=Dj1PI2bQBYv_JgPxCIaIC7DMUvWdFJGwXFdsP5hdGBg,25014
|
|
8
8
|
lollms_client/lollms_mcp_binding.py,sha256=psb27A23VFWDfZsR2WUbQXQxiZDW5yfOak6ZtbMfszI,10222
|
|
@@ -29,10 +29,12 @@ lollms_client/llm_bindings/llamacpp/__init__.py,sha256=llPF85AzYgMp7Cpo_4OvEHKlx
|
|
|
29
29
|
lollms_client/llm_bindings/lollms/__init__.py,sha256=XFQKtTJnkW8OwF1IoyzHqAZ8JAJ0PnAUKDdeOLGcbrE,24310
|
|
30
30
|
lollms_client/llm_bindings/lollms_webui/__init__.py,sha256=iuDfhZZoLC-PDEPLHrcjk5-962S5c7OeCI7PMdJxI_A,17753
|
|
31
31
|
lollms_client/llm_bindings/mistral/__init__.py,sha256=cddz9xIj8NRFLKHe2JMxzstpUrNIu5s9juci3mhiHfo,14133
|
|
32
|
+
lollms_client/llm_bindings/novita_ai/__init__.py,sha256=NOg6_NBCxuz9gwrijTCzrp9a78AbmBdT4k67baCTtuc,13877
|
|
32
33
|
lollms_client/llm_bindings/ollama/__init__.py,sha256=a6cgzXPuo8ZLhIZHJFy8QF0n5ZTk0X4OC1JSyXG1enk,46013
|
|
33
34
|
lollms_client/llm_bindings/open_router/__init__.py,sha256=cAFWtCWJx0WjIe1w2JReCf6WlAZjrXYA4jZ8l3zqxMs,14915
|
|
34
35
|
lollms_client/llm_bindings/openai/__init__.py,sha256=ElLbtHLwR61Uj3W6G4g6QIhxtCqUGOCQBYwhQyN60us,26142
|
|
35
36
|
lollms_client/llm_bindings/openllm/__init__.py,sha256=RC9dVeopslS-zXTsSJ7VC4iVsKgZCBwfmccmr_LCHA0,29971
|
|
37
|
+
lollms_client/llm_bindings/perplexity/__init__.py,sha256=lMRPdbVbGX_weByAdcsZakdxDg7nFF3uCbdzakQmBOc,15006
|
|
36
38
|
lollms_client/llm_bindings/pythonllamacpp/__init__.py,sha256=ZTuVa5ngu9GPVImjs_g8ArV7Bx7a1Rze518Tz8AFJ3U,31807
|
|
37
39
|
lollms_client/llm_bindings/tensor_rt/__init__.py,sha256=xiT-JAyNI_jo6CE0nle9Xoc7U8-UHAfEHrnCwmDTiOE,32023
|
|
38
40
|
lollms_client/llm_bindings/transformers/__init__.py,sha256=hEonNvmrVSc9YWg_1uVwxe31rC-fsjVGh6QvyBc0TEE,37598
|
|
@@ -49,10 +51,13 @@ lollms_client/stt_bindings/lollms/__init__.py,sha256=9Vmn1sQQZKLGLe7nZnc-0LnNeSY
|
|
|
49
51
|
lollms_client/stt_bindings/whisper/__init__.py,sha256=1Ej67GdRKBy1bba14jMaYDYHiZkxJASkWm5eF07ztDQ,15363
|
|
50
52
|
lollms_client/stt_bindings/whispercpp/__init__.py,sha256=xSAQRjAhljak3vWCpkP0Vmdb6WmwTzPjXyaIB85KLGU,21439
|
|
51
53
|
lollms_client/tti_bindings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
52
|
-
lollms_client/tti_bindings/diffusers/__init__.py,sha256=
|
|
54
|
+
lollms_client/tti_bindings/diffusers/__init__.py,sha256=Pi5Zw4nHGXVc0Vcb0ib7KkoiOx__0JukWtL01BUzd7c,41692
|
|
53
55
|
lollms_client/tti_bindings/gemini/__init__.py,sha256=f9fPuqnrBZ1Z-obcoP6EVvbEXNbNCSg21cd5efLCk8U,16707
|
|
56
|
+
lollms_client/tti_bindings/leonardo_ai/__init__.py,sha256=EvjKyV8kM7-tmLwC1agSQ-v7thrNgflrmFxhDLqzT8U,5884
|
|
54
57
|
lollms_client/tti_bindings/lollms/__init__.py,sha256=5Tnsn4b17djvieQkcjtIDBm3qf0pg5ZWWov-4_2wmo0,8762
|
|
58
|
+
lollms_client/tti_bindings/novita_ai/__init__.py,sha256=1PZbM_R7cZwImbYxeuLqTlrc6Sfg43_YCbjw2ZJLnhc,4802
|
|
55
59
|
lollms_client/tti_bindings/openai/__init__.py,sha256=YWJolJSQfIzTJvrLQVe8rQewP7rddf6z87g4rnp-lTs,4932
|
|
60
|
+
lollms_client/tti_bindings/stability_ai/__init__.py,sha256=GJxE0joQ0UZbheozysbN96AvQq60pjY2UjnSLFmRh4g,8025
|
|
56
61
|
lollms_client/ttm_bindings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
57
62
|
lollms_client/ttm_bindings/audiocraft/__init__.py,sha256=a0k6wTrHth6GaVOiNnVboeFY3oKVvCQPbQlqO38XEyc,14328
|
|
58
63
|
lollms_client/ttm_bindings/bark/__init__.py,sha256=Pr3ou2a-7hNYDqbkxrAbghZpO5HvGUhz7e-7VGXIHHA,18976
|
|
@@ -71,8 +76,8 @@ lollms_client/tts_bindings/xtts/server/main.py,sha256=T-Kn5NM-u1FJMygeV8rOoZKlqn
|
|
|
71
76
|
lollms_client/tts_bindings/xtts/server/setup_voices.py,sha256=UdHaPa5aNcw8dR-aRGkZr2OfSFFejH79lXgfwT0P3ss,1964
|
|
72
77
|
lollms_client/ttv_bindings/__init__.py,sha256=UZ8o2izQOJLQgtZ1D1cXoNST7rzqW22rL2Vufc7ddRc,3141
|
|
73
78
|
lollms_client/ttv_bindings/lollms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
74
|
-
lollms_client-1.4.
|
|
75
|
-
lollms_client-1.4.
|
|
76
|
-
lollms_client-1.4.
|
|
77
|
-
lollms_client-1.4.
|
|
78
|
-
lollms_client-1.4.
|
|
79
|
+
lollms_client-1.4.5.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
80
|
+
lollms_client-1.4.5.dist-info/METADATA,sha256=IJc5k53zOajOIIvuq-dhLQQ67bHpLwzNyTqxlQZNCz8,58689
|
|
81
|
+
lollms_client-1.4.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
82
|
+
lollms_client-1.4.5.dist-info/top_level.txt,sha256=Bk_kz-ri6Arwsk7YG-T5VsRorV66uVhcHGvb_g2WqgE,14
|
|
83
|
+
lollms_client-1.4.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|