bizyengine 1.2.76__py3-none-any.whl → 1.2.78__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.
- bizyengine/bizy_server/api_client.py +53 -66
- bizyengine/bizy_server/errno.py +10 -0
- bizyengine/bizy_server/server.py +19 -0
- bizyengine/bizyair_extras/third_party_api/__init__.py +1 -0
- bizyengine/bizyair_extras/third_party_api/nodes_doubao.py +32 -16
- bizyengine/bizyair_extras/third_party_api/nodes_flux.py +9 -6
- bizyengine/bizyair_extras/third_party_api/nodes_gemini.py +26 -10
- bizyengine/bizyair_extras/third_party_api/nodes_gpt.py +6 -6
- bizyengine/bizyair_extras/third_party_api/nodes_hailuo.py +6 -6
- bizyengine/bizyair_extras/third_party_api/nodes_kling.py +308 -21
- bizyengine/bizyair_extras/third_party_api/nodes_sora.py +6 -6
- bizyengine/bizyair_extras/third_party_api/nodes_veo3.py +9 -9
- bizyengine/bizyair_extras/third_party_api/nodes_vidu.py +269 -0
- bizyengine/bizyair_extras/third_party_api/nodes_wan_api.py +222 -6
- bizyengine/bizyair_extras/third_party_api/trd_nodes_base.py +3 -2
- bizyengine/misc/utils.py +18 -4
- bizyengine/version.txt +1 -1
- {bizyengine-1.2.76.dist-info → bizyengine-1.2.78.dist-info}/METADATA +1 -1
- {bizyengine-1.2.76.dist-info → bizyengine-1.2.78.dist-info}/RECORD +21 -20
- {bizyengine-1.2.76.dist-info → bizyengine-1.2.78.dist-info}/WHEEL +0 -0
- {bizyengine-1.2.76.dist-info → bizyengine-1.2.78.dist-info}/top_level.txt +0 -0
|
@@ -9,6 +9,7 @@ from openai import OpenAI
|
|
|
9
9
|
import bizyengine.core as core
|
|
10
10
|
from bizyengine.core.common import get_api_key
|
|
11
11
|
from bizyengine.core.common.env_var import (
|
|
12
|
+
BIZYAIR_DEBUG,
|
|
12
13
|
BIZYAIR_PRODUCTION_TEST,
|
|
13
14
|
BIZYAIR_SERVER_MODE,
|
|
14
15
|
BIZYAIR_X_SERVER,
|
|
@@ -62,88 +63,55 @@ class APIClient:
|
|
|
62
63
|
errnos.INVALID_API_KEY.message = error_message
|
|
63
64
|
return None, errnos.INVALID_API_KEY
|
|
64
65
|
|
|
66
|
+
async def _handle_response(self, response, method, url):
|
|
67
|
+
try:
|
|
68
|
+
resp_text = await response.text()
|
|
69
|
+
except Exception:
|
|
70
|
+
resp_text = ""
|
|
71
|
+
|
|
72
|
+
try:
|
|
73
|
+
resp_json = json.loads(resp_text)
|
|
74
|
+
except Exception:
|
|
75
|
+
resp_json = resp_text
|
|
76
|
+
if response.status != 200:
|
|
77
|
+
print(
|
|
78
|
+
f"\033[31m[BizyAir]\033[0m API Error: {method} {url} {response.status} Body: {resp_text}"
|
|
79
|
+
)
|
|
80
|
+
isJson = isinstance(resp_json, dict)
|
|
81
|
+
return None, ErrorNo(
|
|
82
|
+
response.status,
|
|
83
|
+
resp_json.get("code", response.status) if isJson else resp_json,
|
|
84
|
+
None,
|
|
85
|
+
{
|
|
86
|
+
user_profile.getLang(): (
|
|
87
|
+
resp_json.get("message", resp_text) if isJson else resp_json
|
|
88
|
+
)
|
|
89
|
+
},
|
|
90
|
+
)
|
|
91
|
+
return resp_json, None
|
|
92
|
+
|
|
65
93
|
async def do_get(self, url, params=None, headers=None):
|
|
66
94
|
if params:
|
|
67
95
|
query_string = urllib.parse.urlencode(params, doseq=True)
|
|
68
96
|
url = f"{url}?{query_string}"
|
|
69
97
|
async with await self.get_session() as session:
|
|
70
98
|
async with session.get(url, headers=headers) as response:
|
|
71
|
-
|
|
72
|
-
if response.status != 200:
|
|
73
|
-
isJson = isinstance(resp_json, dict)
|
|
74
|
-
return None, ErrorNo(
|
|
75
|
-
response.status,
|
|
76
|
-
resp_json.get("code", response.status) if isJson else resp_json,
|
|
77
|
-
None,
|
|
78
|
-
{
|
|
79
|
-
user_profile.getLang(): (
|
|
80
|
-
resp_json.get("message", await response.text())
|
|
81
|
-
if isJson
|
|
82
|
-
else resp_json
|
|
83
|
-
)
|
|
84
|
-
},
|
|
85
|
-
)
|
|
86
|
-
return resp_json, None
|
|
99
|
+
return await self._handle_response(response, "GET", url)
|
|
87
100
|
|
|
88
101
|
async def do_post(self, url, data=None, headers=None):
|
|
89
102
|
async with await self.get_session() as session:
|
|
90
103
|
async with session.post(url, json=data, headers=headers) as response:
|
|
91
|
-
|
|
92
|
-
if response.status != 200:
|
|
93
|
-
isJson = isinstance(resp_json, dict)
|
|
94
|
-
return None, ErrorNo(
|
|
95
|
-
response.status,
|
|
96
|
-
resp_json.get("code", response.status) if isJson else resp_json,
|
|
97
|
-
None,
|
|
98
|
-
{
|
|
99
|
-
user_profile.getLang(): (
|
|
100
|
-
resp_json.get("message", await response.text())
|
|
101
|
-
if isJson
|
|
102
|
-
else resp_json
|
|
103
|
-
)
|
|
104
|
-
},
|
|
105
|
-
)
|
|
106
|
-
return resp_json, None
|
|
104
|
+
return await self._handle_response(response, "POST", url)
|
|
107
105
|
|
|
108
106
|
async def do_put(self, url, data=None, headers=None):
|
|
109
107
|
async with await self.get_session() as session:
|
|
110
108
|
async with session.put(url, json=data, headers=headers) as response:
|
|
111
|
-
|
|
112
|
-
if response.status != 200:
|
|
113
|
-
isJson = isinstance(resp_json, dict)
|
|
114
|
-
return None, ErrorNo(
|
|
115
|
-
response.status,
|
|
116
|
-
resp_json.get("code", response.status) if isJson else resp_json,
|
|
117
|
-
None,
|
|
118
|
-
{
|
|
119
|
-
user_profile.getLang(): (
|
|
120
|
-
resp_json.get("message", await response.text())
|
|
121
|
-
if isJson
|
|
122
|
-
else resp_json
|
|
123
|
-
)
|
|
124
|
-
},
|
|
125
|
-
)
|
|
126
|
-
return resp_json, None
|
|
109
|
+
return await self._handle_response(response, "PUT", url)
|
|
127
110
|
|
|
128
111
|
async def do_delete(self, url, data=None, headers=None):
|
|
129
112
|
async with await self.get_session() as session:
|
|
130
113
|
async with session.delete(url, json=data, headers=headers) as response:
|
|
131
|
-
|
|
132
|
-
if response.status != 200:
|
|
133
|
-
isJson = isinstance(resp_json, dict)
|
|
134
|
-
return None, ErrorNo(
|
|
135
|
-
response.status,
|
|
136
|
-
resp_json.get("code", response.status) if isJson else resp_json,
|
|
137
|
-
None,
|
|
138
|
-
{
|
|
139
|
-
user_profile.getLang(): (
|
|
140
|
-
resp_json.get("message", await response.text())
|
|
141
|
-
if isJson
|
|
142
|
-
else resp_json
|
|
143
|
-
)
|
|
144
|
-
},
|
|
145
|
-
)
|
|
146
|
-
return resp_json, None
|
|
114
|
+
return await self._handle_response(response, "DELETE", url)
|
|
147
115
|
|
|
148
116
|
async def user_info(self) -> tuple[dict | None, ErrorNo | None]:
|
|
149
117
|
headers, err = self.auth_header()
|
|
@@ -1216,13 +1184,13 @@ class APIClient:
|
|
|
1216
1184
|
try:
|
|
1217
1185
|
data, err = await self.do_get(url, params=params, headers=headers)
|
|
1218
1186
|
if err is not None:
|
|
1219
|
-
print(f"fetch_all_models: error fetching models: {err}")
|
|
1187
|
+
print(f"fetch_all_models: error fetching models: {str(err)}")
|
|
1220
1188
|
return []
|
|
1221
1189
|
|
|
1222
1190
|
all_models = [model["id"] for model in data["data"]]
|
|
1223
1191
|
return all_models
|
|
1224
1192
|
except aiohttp.ClientError as e:
|
|
1225
|
-
print(f"Error fetching models: {e}")
|
|
1193
|
+
print(f"Error fetching models: {str(e)}")
|
|
1226
1194
|
return []
|
|
1227
1195
|
except asyncio.exceptions.TimeoutError:
|
|
1228
1196
|
print("Request to fetch models timed out")
|
|
@@ -1243,3 +1211,22 @@ class APIClient:
|
|
|
1243
1211
|
except aiohttp.ClientError as e:
|
|
1244
1212
|
print(f"get_plugin_tmp_token error: {e}")
|
|
1245
1213
|
return None, errnos.GET_PLUGIN_TMP_TOKEN
|
|
1214
|
+
|
|
1215
|
+
async def trd_api_pricing(self, model: str, data, request_api_key: str = None):
|
|
1216
|
+
server_url = f"{BIZYAIR_Y_SERVER}/trd_api/node/{model}/price"
|
|
1217
|
+
|
|
1218
|
+
headers, err = self.auth_header(api_key=request_api_key)
|
|
1219
|
+
if err is not None:
|
|
1220
|
+
return None, err
|
|
1221
|
+
|
|
1222
|
+
try:
|
|
1223
|
+
ret, err = await self.do_post(server_url, headers=headers, data=data)
|
|
1224
|
+
if err is not None:
|
|
1225
|
+
return None, err
|
|
1226
|
+
|
|
1227
|
+
return ret["data"], None
|
|
1228
|
+
except Exception as e:
|
|
1229
|
+
print(
|
|
1230
|
+
f"\033[31m[BizyAir]\033[0m Fail to get trd api node {model} pricing: {str(e)}"
|
|
1231
|
+
)
|
|
1232
|
+
return None, errnos.TRD_API_PRICING
|
bizyengine/bizy_server/errno.py
CHANGED
|
@@ -22,6 +22,9 @@ class ErrorNo:
|
|
|
22
22
|
def set_message(self, msg, lang="en"):
|
|
23
23
|
self.messages[lang] = msg
|
|
24
24
|
|
|
25
|
+
def __str__(self) -> str:
|
|
26
|
+
return f"ErrorNo(http_status_code={self.http_status_code}, code={self.code}, messages={self.messages}, data={self.data})"
|
|
27
|
+
|
|
25
28
|
message = property(fget=get_message, fset=set_message)
|
|
26
29
|
|
|
27
30
|
|
|
@@ -507,3 +510,10 @@ class errnos:
|
|
|
507
510
|
None,
|
|
508
511
|
{"en": "Failed to get tmp token", "zh": "获取临时令牌失败"},
|
|
509
512
|
)
|
|
513
|
+
|
|
514
|
+
TRD_API_PRICING = ErrorNo(
|
|
515
|
+
500,
|
|
516
|
+
500162,
|
|
517
|
+
None,
|
|
518
|
+
{"en": "Failed to get trd api node pricing", "zh": "获取第三方API节点定价失败"},
|
|
519
|
+
)
|
bizyengine/bizy_server/server.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import errno
|
|
2
3
|
import json
|
|
3
4
|
import logging
|
|
4
5
|
import re
|
|
@@ -951,6 +952,24 @@ class BizyAirServer:
|
|
|
951
952
|
print(f"\033[31m[BizyAir]\033[0m Chat request failed: {str(e)}")
|
|
952
953
|
return ErrResponse(errnos.MODEL_API_ERROR)
|
|
953
954
|
|
|
955
|
+
@self.prompt_server.routes.post(f"/{API_PREFIX}/trd_api_pricing")
|
|
956
|
+
async def trd_api_pricing(request):
|
|
957
|
+
request_api_key, err = _get_request_api_key(request.headers)
|
|
958
|
+
if err:
|
|
959
|
+
return ErrResponse(err)
|
|
960
|
+
model = request.rel_url.query.get("model", "")
|
|
961
|
+
if not model:
|
|
962
|
+
return ErrResponse(errnos.INVALID_MODEL_ID)
|
|
963
|
+
data = {}
|
|
964
|
+
if request.body_exists:
|
|
965
|
+
data = await request.json()
|
|
966
|
+
pricing, err = await self.api_client.trd_api_pricing(
|
|
967
|
+
model=model, data=data, request_api_key=request_api_key
|
|
968
|
+
)
|
|
969
|
+
if err:
|
|
970
|
+
return ErrResponse(err)
|
|
971
|
+
return OKResponse(pricing)
|
|
972
|
+
|
|
954
973
|
# 服务器模式独占
|
|
955
974
|
if BIZYAIR_SERVER_MODE:
|
|
956
975
|
return
|
|
@@ -4,8 +4,11 @@ from .trd_nodes_base import BizyAirTrdApiBaseNode
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class Seedream4(BizyAirTrdApiBaseNode):
|
|
7
|
-
RETURN_TYPES = (
|
|
8
|
-
|
|
7
|
+
RETURN_TYPES = (
|
|
8
|
+
"IMAGE",
|
|
9
|
+
"""{"doubao-seedream-4-0-250828": "doubao-seedream-4-0-250828"}""",
|
|
10
|
+
)
|
|
11
|
+
RETURN_NAMES = ("images", "bizyair_model_name")
|
|
9
12
|
CATEGORY = "☁️BizyAir/External APIs/Doubao"
|
|
10
13
|
NODE_DISPLAY_NAME = "Seedream4"
|
|
11
14
|
|
|
@@ -149,12 +152,15 @@ class Seedream4(BizyAirTrdApiBaseNode):
|
|
|
149
152
|
|
|
150
153
|
def handle_outputs(self, outputs):
|
|
151
154
|
images = self.combine_images(outputs[1])
|
|
152
|
-
return (images,)
|
|
155
|
+
return (images, "")
|
|
153
156
|
|
|
154
157
|
|
|
155
158
|
class Seedream4_5(BizyAirTrdApiBaseNode):
|
|
156
|
-
RETURN_TYPES = (
|
|
157
|
-
|
|
159
|
+
RETURN_TYPES = (
|
|
160
|
+
"IMAGE",
|
|
161
|
+
"""{"doubao-seedream-4-5-251128": "doubao-seedream-4-5-251128"}""",
|
|
162
|
+
)
|
|
163
|
+
RETURN_NAMES = ("images", "bizyair_model_name")
|
|
158
164
|
CATEGORY = "☁️BizyAir/External APIs/Doubao"
|
|
159
165
|
NODE_DISPLAY_NAME = "Seedream 4.5"
|
|
160
166
|
INPUT_IS_LIST = True
|
|
@@ -251,7 +257,8 @@ class Seedream4_5(BizyAirTrdApiBaseNode):
|
|
|
251
257
|
# 多图的情况可以认为图片输入都是List[Image Batch]
|
|
252
258
|
total_input_images = 0
|
|
253
259
|
for _, img_batch in enumerate(images if images is not None else []):
|
|
254
|
-
|
|
260
|
+
if img_batch is not None:
|
|
261
|
+
total_input_images += img_batch.shape[0]
|
|
255
262
|
extra_images, total_extra_images = self.get_extra_images(**kwargs)
|
|
256
263
|
total_input_images += total_extra_images
|
|
257
264
|
if total_input_images > 14:
|
|
@@ -316,12 +323,15 @@ class Seedream4_5(BizyAirTrdApiBaseNode):
|
|
|
316
323
|
|
|
317
324
|
def handle_outputs(self, outputs):
|
|
318
325
|
images = self.combine_images(outputs[1])
|
|
319
|
-
return (images,)
|
|
326
|
+
return (images, "")
|
|
320
327
|
|
|
321
328
|
|
|
322
329
|
class Seededit3(BizyAirTrdApiBaseNode):
|
|
323
|
-
RETURN_TYPES = (
|
|
324
|
-
|
|
330
|
+
RETURN_TYPES = (
|
|
331
|
+
"IMAGE",
|
|
332
|
+
"""{"doubao-seededit-3-0-i2i-250628": "doubao-seededit-3-0-i2i-250628"}""",
|
|
333
|
+
)
|
|
334
|
+
RETURN_NAMES = ("image", "bizyair_model_name")
|
|
325
335
|
CATEGORY = "☁️BizyAir/External APIs/Doubao"
|
|
326
336
|
NODE_DISPLAY_NAME = "Seededit3"
|
|
327
337
|
|
|
@@ -374,12 +384,15 @@ class Seededit3(BizyAirTrdApiBaseNode):
|
|
|
374
384
|
|
|
375
385
|
def handle_outputs(self, outputs):
|
|
376
386
|
images = self.combine_images(outputs[1])
|
|
377
|
-
return (images,)
|
|
387
|
+
return (images, "")
|
|
378
388
|
|
|
379
389
|
|
|
380
390
|
class Seedance_1_0_T2V_API(BizyAirTrdApiBaseNode):
|
|
381
|
-
RETURN_TYPES = (
|
|
382
|
-
|
|
391
|
+
RETURN_TYPES = (
|
|
392
|
+
"VIDEO",
|
|
393
|
+
"""{"doubao-seedance-1-0-pro-250528": "doubao-seedance-1-0","doubao-seedance-1-0-pro-fast-251015": "doubao-seedance-1-0"}""",
|
|
394
|
+
)
|
|
395
|
+
RETURN_NAMES = ("video", "bizyair_model_name")
|
|
383
396
|
CATEGORY = "☁️BizyAir/External APIs/Doubao"
|
|
384
397
|
NODE_DISPLAY_NAME = "Seedance 1.0 Pro Text To Video"
|
|
385
398
|
|
|
@@ -458,12 +471,15 @@ class Seedance_1_0_T2V_API(BizyAirTrdApiBaseNode):
|
|
|
458
471
|
return data, "doubao-seedance-1-0"
|
|
459
472
|
|
|
460
473
|
def handle_outputs(self, outputs):
|
|
461
|
-
return (outputs[0][0],)
|
|
474
|
+
return (outputs[0][0], "")
|
|
462
475
|
|
|
463
476
|
|
|
464
477
|
class Seedance_1_0_I2V_API(BizyAirTrdApiBaseNode):
|
|
465
|
-
RETURN_TYPES = (
|
|
466
|
-
|
|
478
|
+
RETURN_TYPES = (
|
|
479
|
+
"VIDEO",
|
|
480
|
+
"""{"doubao-seedance-1-0-pro-250528": "doubao-seedance-1-0","doubao-seedance-1-0-pro-fast-251015": "doubao-seedance-1-0"}""",
|
|
481
|
+
)
|
|
482
|
+
RETURN_NAMES = ("video", "bizyair_model_name")
|
|
467
483
|
CATEGORY = "☁️BizyAir/External APIs/Doubao"
|
|
468
484
|
NODE_DISPLAY_NAME = "Seedance 1.0 Pro Image To Video"
|
|
469
485
|
|
|
@@ -568,4 +584,4 @@ class Seedance_1_0_I2V_API(BizyAirTrdApiBaseNode):
|
|
|
568
584
|
return data, "doubao-seedance-1-0"
|
|
569
585
|
|
|
570
586
|
def handle_outputs(self, outputs):
|
|
571
|
-
return (outputs[0][0],)
|
|
587
|
+
return (outputs[0][0], "")
|
|
@@ -5,8 +5,11 @@ from .trd_nodes_base import BizyAirTrdApiBaseNode
|
|
|
5
5
|
|
|
6
6
|
class Flux_Kontext_API(BizyAirTrdApiBaseNode):
|
|
7
7
|
NODE_DISPLAY_NAME = "Flux Kontext API"
|
|
8
|
-
RETURN_TYPES = (
|
|
9
|
-
|
|
8
|
+
RETURN_TYPES = (
|
|
9
|
+
"IMAGE",
|
|
10
|
+
"""{"flux-kontext-pro": "flux-kontext","flux-kontext-max": "flux-kontext"}""",
|
|
11
|
+
)
|
|
12
|
+
RETURN_NAMES = ("image", "bizyair_model_name")
|
|
10
13
|
CATEGORY = "☁️BizyAir/External APIs/Flux"
|
|
11
14
|
|
|
12
15
|
@classmethod
|
|
@@ -58,13 +61,13 @@ class Flux_Kontext_API(BizyAirTrdApiBaseNode):
|
|
|
58
61
|
|
|
59
62
|
def handle_outputs(self, outputs):
|
|
60
63
|
images = self.combine_images(outputs[1])
|
|
61
|
-
return (images,)
|
|
64
|
+
return (images, "")
|
|
62
65
|
|
|
63
66
|
|
|
64
67
|
class Flux_2_API(BizyAirTrdApiBaseNode):
|
|
65
68
|
NODE_DISPLAY_NAME = "Flux 2 API"
|
|
66
|
-
RETURN_TYPES = ("IMAGE",)
|
|
67
|
-
RETURN_NAMES = ("image",)
|
|
69
|
+
RETURN_TYPES = ("IMAGE", """{"flux-2-pro": "flux-2","flux-2-flex": "flux-2"}""")
|
|
70
|
+
RETURN_NAMES = ("image", "bizyair_model_name")
|
|
68
71
|
CATEGORY = "☁️BizyAir/External APIs/Flux"
|
|
69
72
|
|
|
70
73
|
@classmethod
|
|
@@ -170,4 +173,4 @@ class Flux_2_API(BizyAirTrdApiBaseNode):
|
|
|
170
173
|
|
|
171
174
|
def handle_outputs(self, outputs):
|
|
172
175
|
images = self.combine_images(outputs[1])
|
|
173
|
-
return (images,)
|
|
176
|
+
return (images, "")
|
|
@@ -60,7 +60,12 @@ def build_prompt_for_operation(
|
|
|
60
60
|
|
|
61
61
|
class NanoBanana(BizyAirTrdApiBaseNode):
|
|
62
62
|
NODE_DISPLAY_NAME = "NanoBanana"
|
|
63
|
-
RETURN_TYPES = (
|
|
63
|
+
RETURN_TYPES = (
|
|
64
|
+
"IMAGE",
|
|
65
|
+
"STRING",
|
|
66
|
+
"""{"gemini-2.5-flash-image": "gemini-2.5-flash-image"}""",
|
|
67
|
+
)
|
|
68
|
+
RETURN_NAMES = ("image", "string", "bizyair_model_name")
|
|
64
69
|
CATEGORY = "☁️BizyAir/External APIs/Gemini"
|
|
65
70
|
|
|
66
71
|
@classmethod
|
|
@@ -114,6 +119,7 @@ class NanoBanana(BizyAirTrdApiBaseNode):
|
|
|
114
119
|
},
|
|
115
120
|
),
|
|
116
121
|
},
|
|
122
|
+
"hidden": {"bizyair_model_name": {"default": "gemini-2.5-flash-image"}},
|
|
117
123
|
}
|
|
118
124
|
|
|
119
125
|
def handle_inputs(self, headers, prompt_id, **kwargs):
|
|
@@ -176,13 +182,17 @@ class NanoBanana(BizyAirTrdApiBaseNode):
|
|
|
176
182
|
raise ValueError("No image found in response")
|
|
177
183
|
if len(outputs[2]) > 0:
|
|
178
184
|
text = outputs[2][0]
|
|
179
|
-
return (image, text)
|
|
185
|
+
return (image, text, "")
|
|
180
186
|
|
|
181
187
|
|
|
182
188
|
class NanoBananaPro(BizyAirTrdApiBaseNode):
|
|
183
189
|
NODE_DISPLAY_NAME = "NanoBananaPro"
|
|
184
|
-
RETURN_TYPES = (
|
|
185
|
-
|
|
190
|
+
RETURN_TYPES = (
|
|
191
|
+
"IMAGE",
|
|
192
|
+
"STRING",
|
|
193
|
+
"""{"gemini-3-pro-image-preview": "gemini-3-pro-image-preview"}""",
|
|
194
|
+
)
|
|
195
|
+
RETURN_NAMES = ("image", "string", "bizyair_model_name")
|
|
186
196
|
CATEGORY = "☁️BizyAir/External APIs/Gemini"
|
|
187
197
|
INPUT_IS_LIST = True
|
|
188
198
|
|
|
@@ -273,7 +283,8 @@ class NanoBananaPro(BizyAirTrdApiBaseNode):
|
|
|
273
283
|
# 多图的情况可以认为图片输入都是List[Image Batch]
|
|
274
284
|
total_input_images = 0
|
|
275
285
|
for _, img_batch in enumerate(images if images is not None else []):
|
|
276
|
-
|
|
286
|
+
if img_batch is not None:
|
|
287
|
+
total_input_images += img_batch.shape[0]
|
|
277
288
|
extra_images, total_extra_images = self.get_extra_images(**kwargs)
|
|
278
289
|
total_input_images += total_extra_images
|
|
279
290
|
if total_input_images > 14:
|
|
@@ -333,7 +344,7 @@ class NanoBananaPro(BizyAirTrdApiBaseNode):
|
|
|
333
344
|
raise ValueError("No image found in response")
|
|
334
345
|
if len(outputs[2]) > 0:
|
|
335
346
|
text = outputs[2][0]
|
|
336
|
-
return (image, text)
|
|
347
|
+
return (image, text, "")
|
|
337
348
|
|
|
338
349
|
|
|
339
350
|
class NanoBananaProOfficial(BizyAirTrdApiBaseNode):
|
|
@@ -390,8 +401,12 @@ class NanoBananaProOfficial(BizyAirTrdApiBaseNode):
|
|
|
390
401
|
},
|
|
391
402
|
}
|
|
392
403
|
|
|
393
|
-
RETURN_TYPES = (
|
|
394
|
-
|
|
404
|
+
RETURN_TYPES = (
|
|
405
|
+
"IMAGE",
|
|
406
|
+
"STRING",
|
|
407
|
+
"""{"gemini-3-pro-image-preview": "gemini-3-pro-image-preview"}""",
|
|
408
|
+
)
|
|
409
|
+
RETURN_NAMES = ("image", "string", "bizyair_model_name")
|
|
395
410
|
CATEGORY = "☁️BizyAir/External APIs/Gemini"
|
|
396
411
|
NODE_DISPLAY_NAME = "NanoBananaPro (Official Parameters)"
|
|
397
412
|
INPUT_IS_LIST = True
|
|
@@ -409,7 +424,8 @@ class NanoBananaProOfficial(BizyAirTrdApiBaseNode):
|
|
|
409
424
|
# 多图的情况可以认为图片输入都是List[Image Batch]
|
|
410
425
|
total_input_images = 0
|
|
411
426
|
for _, img_batch in enumerate(images if images is not None else []):
|
|
412
|
-
|
|
427
|
+
if img_batch is not None:
|
|
428
|
+
total_input_images += img_batch.shape[0]
|
|
413
429
|
total_input_images += total_extra_images
|
|
414
430
|
if total_input_images > 14:
|
|
415
431
|
raise ValueError("Maximum number of images is 14")
|
|
@@ -457,4 +473,4 @@ class NanoBananaProOfficial(BizyAirTrdApiBaseNode):
|
|
|
457
473
|
raise ValueError("No image found in response")
|
|
458
474
|
if len(outputs[2]) > 0:
|
|
459
475
|
text = outputs[2][0]
|
|
460
|
-
return (image, text)
|
|
476
|
+
return (image, text, "")
|
|
@@ -5,8 +5,8 @@ from .trd_nodes_base import BizyAirTrdApiBaseNode
|
|
|
5
5
|
|
|
6
6
|
class GPT_IMAGE_1_T2I_API(BizyAirTrdApiBaseNode):
|
|
7
7
|
NODE_DISPLAY_NAME = "GPT Image 1 Text To Image"
|
|
8
|
-
RETURN_TYPES = ("IMAGE",)
|
|
9
|
-
RETURN_NAMES = ("images",)
|
|
8
|
+
RETURN_TYPES = ("IMAGE", """{"gpt-image-1": "gpt-image-1"}""")
|
|
9
|
+
RETURN_NAMES = ("images", "bizyair_model_name")
|
|
10
10
|
CATEGORY = "☁️BizyAir/External APIs/OpenAI"
|
|
11
11
|
|
|
12
12
|
@classmethod
|
|
@@ -40,13 +40,13 @@ class GPT_IMAGE_1_T2I_API(BizyAirTrdApiBaseNode):
|
|
|
40
40
|
|
|
41
41
|
def handle_outputs(self, outputs):
|
|
42
42
|
images = self.combine_images(outputs[1])
|
|
43
|
-
return (images,)
|
|
43
|
+
return (images, "")
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
class GPT_IMAGE_EDIT_API(BizyAirTrdApiBaseNode):
|
|
47
47
|
NODE_DISPLAY_NAME = "GPT Image Edit"
|
|
48
|
-
RETURN_TYPES = ("IMAGE",)
|
|
49
|
-
RETURN_NAMES = ("images",)
|
|
48
|
+
RETURN_TYPES = ("IMAGE", """{"gpt-image-1": "gpt-image-1"}""")
|
|
49
|
+
RETURN_NAMES = ("images", "bizyair_model_name")
|
|
50
50
|
CATEGORY = "☁️BizyAir/External APIs/OpenAI"
|
|
51
51
|
|
|
52
52
|
@classmethod
|
|
@@ -98,4 +98,4 @@ class GPT_IMAGE_EDIT_API(BizyAirTrdApiBaseNode):
|
|
|
98
98
|
|
|
99
99
|
def handle_outputs(self, outputs):
|
|
100
100
|
images = self.combine_images(outputs[1])
|
|
101
|
-
return (images,)
|
|
101
|
+
return (images, "")
|
|
@@ -28,8 +28,8 @@ class Hailuo2_3_T2V(BizyAirTrdApiBaseNode):
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
NODE_DISPLAY_NAME = "Hailuo2.3 Text To Video"
|
|
31
|
-
RETURN_TYPES = ("VIDEO",)
|
|
32
|
-
RETURN_NAMES = ("video",)
|
|
31
|
+
RETURN_TYPES = ("VIDEO", """{"MiniMax-Hailuo-2.3-t2v": "MiniMax-Hailuo-2.3-t2v"}""")
|
|
32
|
+
RETURN_NAMES = ("video", "bizyair_model_name")
|
|
33
33
|
CATEGORY = "☁️BizyAir/External APIs/Hailuo"
|
|
34
34
|
|
|
35
35
|
def handle_inputs(self, headers, prompt_id, **kwargs):
|
|
@@ -50,7 +50,7 @@ class Hailuo2_3_T2V(BizyAirTrdApiBaseNode):
|
|
|
50
50
|
return data, "MiniMax-Hailuo-2.3-t2v"
|
|
51
51
|
|
|
52
52
|
def handle_outputs(self, outputs):
|
|
53
|
-
return (outputs[0][0],)
|
|
53
|
+
return (outputs[0][0], "")
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
class Hailuo2_3_I2V(BizyAirTrdApiBaseNode):
|
|
@@ -79,8 +79,8 @@ class Hailuo2_3_I2V(BizyAirTrdApiBaseNode):
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
NODE_DISPLAY_NAME = "Hailuo2.3 Image To Video"
|
|
82
|
-
RETURN_TYPES = ("VIDEO",)
|
|
83
|
-
RETURN_NAMES = ("video",)
|
|
82
|
+
RETURN_TYPES = ("VIDEO", """{"MiniMax-Hailuo-2.3-i2v": "MiniMax-Hailuo-2.3-i2v"}""")
|
|
83
|
+
RETURN_NAMES = ("video", "bizyair_model_name")
|
|
84
84
|
CATEGORY = "☁️BizyAir/External APIs/Hailuo"
|
|
85
85
|
|
|
86
86
|
def handle_inputs(self, headers, prompt_id, **kwargs):
|
|
@@ -112,4 +112,4 @@ class Hailuo2_3_I2V(BizyAirTrdApiBaseNode):
|
|
|
112
112
|
return data, "MiniMax-Hailuo-2.3-i2v"
|
|
113
113
|
|
|
114
114
|
def handle_outputs(self, outputs):
|
|
115
|
-
return (outputs[0][0],)
|
|
115
|
+
return (outputs[0][0], "")
|