vectorvein 0.2.55__tar.gz → 0.2.57__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. {vectorvein-0.2.55 → vectorvein-0.2.57}/PKG-INFO +1 -1
  2. {vectorvein-0.2.55 → vectorvein-0.2.57}/pyproject.toml +1 -1
  3. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/anthropic_client.py +12 -2
  4. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/graph/port.py +15 -3
  5. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/graph/workflow.py +12 -1
  6. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/nodes/control_flows.py +2 -0
  7. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/nodes/file_processing.py +5 -0
  8. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/nodes/image_generation.py +21 -0
  9. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/nodes/llms.py +19 -0
  10. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/nodes/media_editing.py +54 -0
  11. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/nodes/media_processing.py +21 -0
  12. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/nodes/output.py +7 -0
  13. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/nodes/relational_db.py +1 -0
  14. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/nodes/text_processing.py +4 -0
  15. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/nodes/tools.py +360 -356
  16. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/nodes/vector_db.py +4 -0
  17. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/nodes/web_crawlers.py +1 -0
  18. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/utils/check.py +79 -0
  19. {vectorvein-0.2.55 → vectorvein-0.2.57}/README.md +0 -0
  20. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/__init__.py +0 -0
  21. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/api/__init__.py +0 -0
  22. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/api/client.py +0 -0
  23. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/api/exceptions.py +0 -0
  24. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/api/models.py +0 -0
  25. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/__init__.py +0 -0
  26. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/baichuan_client.py +0 -0
  27. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/base_client.py +0 -0
  28. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/deepseek_client.py +0 -0
  29. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/ernie_client.py +0 -0
  30. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/gemini_client.py +0 -0
  31. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/groq_client.py +0 -0
  32. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/local_client.py +0 -0
  33. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/minimax_client.py +0 -0
  34. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/mistral_client.py +0 -0
  35. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/moonshot_client.py +0 -0
  36. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/openai_client.py +0 -0
  37. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/openai_compatible_client.py +0 -0
  38. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/py.typed +0 -0
  39. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/qwen_client.py +0 -0
  40. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/stepfun_client.py +0 -0
  41. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/utils.py +0 -0
  42. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/xai_client.py +0 -0
  43. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/yi_client.py +0 -0
  44. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/chat_clients/zhipuai_client.py +0 -0
  45. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/py.typed +0 -0
  46. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/server/token_server.py +0 -0
  47. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/settings/__init__.py +0 -0
  48. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/settings/py.typed +0 -0
  49. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/types/__init__.py +0 -0
  50. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/types/defaults.py +0 -0
  51. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/types/enums.py +0 -0
  52. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/types/exception.py +0 -0
  53. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/types/llm_parameters.py +0 -0
  54. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/types/py.typed +0 -0
  55. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/types/settings.py +0 -0
  56. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/utilities/media_processing.py +0 -0
  57. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/utilities/rate_limiter.py +0 -0
  58. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/utilities/retry.py +0 -0
  59. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/graph/edge.py +0 -0
  60. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/graph/node.py +0 -0
  61. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/nodes/__init__.py +0 -0
  62. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/nodes/audio_generation.py +0 -0
  63. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/nodes/triggers.py +0 -0
  64. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/nodes/video_generation.py +0 -0
  65. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/utils/json_to_code.py +0 -0
  66. {vectorvein-0.2.55 → vectorvein-0.2.57}/src/vectorvein/workflow/utils/layout.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vectorvein
3
- Version: 0.2.55
3
+ Version: 0.2.57
4
4
  Summary: VectorVein Python SDK
5
5
  Author-Email: Anderson <andersonby@163.com>
6
6
  License: MIT
@@ -17,7 +17,7 @@ description = "VectorVein Python SDK"
17
17
  name = "vectorvein"
18
18
  readme = "README.md"
19
19
  requires-python = ">=3.10"
20
- version = "0.2.55"
20
+ version = "0.2.57"
21
21
 
22
22
  [project.license]
23
23
  text = "MIT"
@@ -764,9 +764,14 @@ class AnthropicChatClient(BaseChatClient):
764
764
  "reasoning_content": "",
765
765
  "raw_content": [content_block.model_dump() for content_block in response.content],
766
766
  "usage": {
767
- "prompt_tokens": response.usage.input_tokens,
767
+ "prompt_tokens": response.usage.input_tokens + response.usage.cache_read_input_tokens
768
+ if response.usage.cache_read_input_tokens
769
+ else 0,
768
770
  "completion_tokens": response.usage.output_tokens,
769
771
  "total_tokens": response.usage.input_tokens + response.usage.output_tokens,
772
+ "prompt_tokens_details": {
773
+ "cached_tokens": response.usage.cache_read_input_tokens,
774
+ },
770
775
  },
771
776
  }
772
777
  tool_calls = []
@@ -1370,9 +1375,14 @@ class AsyncAnthropicChatClient(BaseAsyncChatClient):
1370
1375
  "reasoning_content": "",
1371
1376
  "raw_content": [content_block.model_dump() for content_block in response.content],
1372
1377
  "usage": {
1373
- "prompt_tokens": response.usage.input_tokens,
1378
+ "prompt_tokens": response.usage.input_tokens + response.usage.cache_read_input_tokens
1379
+ if response.usage.cache_read_input_tokens
1380
+ else 0,
1374
1381
  "completion_tokens": response.usage.output_tokens,
1375
1382
  "total_tokens": response.usage.input_tokens + response.usage.output_tokens,
1383
+ "prompt_tokens_details": {
1384
+ "cached_tokens": response.usage.cache_read_input_tokens,
1385
+ },
1376
1386
  },
1377
1387
  }
1378
1388
  tool_calls = []
@@ -1,5 +1,5 @@
1
1
  from enum import Enum
2
- from typing import Optional, Any, Dict, List, Union
2
+ from typing import Optional, Any, Dict, List, Union, Callable
3
3
 
4
4
 
5
5
  class PortType(Enum):
@@ -28,6 +28,7 @@ class Port:
28
28
  field_type: Optional[str] = None,
29
29
  is_output: bool = False,
30
30
  condition: Optional[str] = None,
31
+ condition_python: Optional[Callable[[Dict[str, "Port"]], bool]] = None,
31
32
  max_length: Optional[int] = None,
32
33
  support_file_types: Optional[List[str]] = None,
33
34
  multiple: Optional[bool] = None,
@@ -48,6 +49,7 @@ class Port:
48
49
  self.field_type = field_type
49
50
  self.is_output = is_output
50
51
  self.condition = condition
52
+ self.condition_python = condition_python
51
53
  self.max_length = max_length
52
54
  self.support_file_types = support_file_types
53
55
  self.multiple = multiple
@@ -75,7 +77,7 @@ class Port:
75
77
  "name": self.name,
76
78
  "display_name": self.name,
77
79
  "field_type": self.port_type.value if isinstance(self.port_type, PortType) else self.port_type,
78
- "required": self.required,
80
+ "required": False if not isinstance(self.value, bool) and self.value else self.required,
79
81
  "show": self.show,
80
82
  "value": self._value,
81
83
  "options": self.options,
@@ -104,6 +106,12 @@ class Port:
104
106
  raise ValueError(f"Value `{value}` is not in Port `{self.name}` options {self.options}")
105
107
  self._value = value
106
108
 
109
+ def __str__(self) -> str:
110
+ return f"Port(name={self.name}, port_type={self.port_type})"
111
+
112
+ def __repr__(self) -> str:
113
+ return self.__str__()
114
+
107
115
 
108
116
  class InputPort(Port):
109
117
  def __init__(
@@ -116,6 +124,7 @@ class InputPort(Port):
116
124
  options: Optional[List[Any]] = None,
117
125
  field_type: Optional[str] = None,
118
126
  condition: Optional[str] = None,
127
+ condition_python: Optional[Callable[[Dict[str, "Port"]], bool]] = None,
119
128
  max_length: Optional[int] = None,
120
129
  support_file_types: Optional[List[str]] = None,
121
130
  multiple: Optional[bool] = None,
@@ -137,6 +146,7 @@ class InputPort(Port):
137
146
  field_type=field_type,
138
147
  is_output=False,
139
148
  condition=condition,
149
+ condition_python=condition_python,
140
150
  max_length=max_length,
141
151
  support_file_types=support_file_types,
142
152
  multiple=multiple,
@@ -155,12 +165,13 @@ class OutputPort(Port):
155
165
  self,
156
166
  name: str = "output",
157
167
  port_type: Union[PortType, str] = PortType.TEXT,
158
- required: bool = True,
168
+ required: bool = False,
159
169
  show: bool = False,
160
170
  value: Any = None,
161
171
  options: Optional[List[Any]] = None,
162
172
  field_type: Optional[str] = None,
163
173
  condition: Optional[str] = None,
174
+ condition_python: Optional[Callable[[Dict[str, "Port"]], bool]] = None,
164
175
  max_length: Optional[int] = None,
165
176
  support_file_types: Optional[List[str]] = None,
166
177
  multiple: Optional[bool] = None,
@@ -182,6 +193,7 @@ class OutputPort(Port):
182
193
  field_type=field_type,
183
194
  is_output=True,
184
195
  condition=condition,
196
+ condition_python=condition_python,
185
197
  max_length=max_length,
186
198
  support_file_types=support_file_types,
187
199
  multiple=multiple,
@@ -4,7 +4,14 @@ from typing import List, Union, Dict, Any, Optional
4
4
  from .node import Node
5
5
  from .edge import Edge
6
6
  from ..utils.layout import layout
7
- from ..utils.check import WorkflowCheckResult, check_dag, check_ui, check_useless_nodes
7
+ from ..utils.check import (
8
+ WorkflowCheckResult,
9
+ check_dag,
10
+ check_ui,
11
+ check_useless_nodes,
12
+ check_required_ports,
13
+ check_override_ports,
14
+ )
8
15
 
9
16
 
10
17
  class Workflow:
@@ -128,6 +135,8 @@ class Workflow:
128
135
  dag_check = check_dag(self) # 检查流程图是否为有向无环图,并检测是否存在孤立节点。
129
136
  ui_check = check_ui(self)
130
137
  useless_nodes = check_useless_nodes(self)
138
+ required_ports = check_required_ports(self)
139
+ override_ports = check_override_ports(self)
131
140
 
132
141
  # 合并结果
133
142
  result: WorkflowCheckResult = {
@@ -135,6 +144,8 @@ class Workflow:
135
144
  "no_isolated_nodes": dag_check["no_isolated_nodes"],
136
145
  "ui_warnings": ui_check,
137
146
  "useless_nodes": useless_nodes,
147
+ "required_ports": required_ports,
148
+ "override_ports": override_ports,
138
149
  }
139
150
 
140
151
  return result
@@ -135,6 +135,7 @@ class JsonProcess(Node):
135
135
  port_type=PortType.INPUT,
136
136
  value="",
137
137
  condition="return fieldsData.process_mode.value == 'get_value'",
138
+ condition_python=lambda ports: ports["process_mode"].value == "get_value",
138
139
  ),
139
140
  "keys": InputPort(
140
141
  name="keys",
@@ -146,6 +147,7 @@ class JsonProcess(Node):
146
147
  port_type=PortType.INPUT,
147
148
  value="",
148
149
  condition="return fieldsData.process_mode.value == 'get_value'",
150
+ condition_python=lambda ports: ports["process_mode"].value == "get_value",
149
151
  ),
150
152
  "output": OutputPort(),
151
153
  },
@@ -33,24 +33,28 @@ class FileLoader(Node):
33
33
  port_type=PortType.CHECKBOX,
34
34
  value=True,
35
35
  condition="return fieldsData.parse_quality.value === 'default'",
36
+ condition_python=lambda ports: ports["parse_quality"].value == "default",
36
37
  ),
37
38
  "remove_url_and_email": InputPort(
38
39
  name="remove_url_and_email",
39
40
  port_type=PortType.CHECKBOX,
40
41
  value=True,
41
42
  condition="return fieldsData.parse_quality.value === 'default'",
43
+ condition_python=lambda ports: ports["parse_quality"].value == "default",
42
44
  ),
43
45
  "parse_table": InputPort(
44
46
  name="parse_table",
45
47
  port_type=PortType.CHECKBOX,
46
48
  value=True,
47
49
  condition="return fieldsData.parse_quality.value === 'high'",
50
+ condition_python=lambda ports: ports["parse_quality"].value == "high",
48
51
  ),
49
52
  "parse_formula": InputPort(
50
53
  name="parse_formula",
51
54
  port_type=PortType.CHECKBOX,
52
55
  value=False,
53
56
  condition="return fieldsData.parse_quality.value === 'high'",
57
+ condition_python=lambda ports: ports["parse_quality"].value == "high",
54
58
  ),
55
59
  "multiple": InputPort(
56
60
  name="multiple",
@@ -92,6 +96,7 @@ class FileUpload(Node):
92
96
  {"value": "dict", "label": "dict"},
93
97
  ],
94
98
  condition="return fieldsData.unzip_files.value",
99
+ condition_python=lambda ports: ports["unzip_files"].value,
95
100
  ),
96
101
  "allowed_file_types": InputPort(
97
102
  name="allowed_file_types",
@@ -35,6 +35,7 @@ class BackgroundGeneration(Node):
35
35
  {"value": "portrait", "label": "portrait"},
36
36
  ],
37
37
  condition="return fieldsData.remove_background.value",
38
+ condition_python=lambda ports: ports["remove_background"].value,
38
39
  ),
39
40
  "ref_image_url": InputPort(
40
41
  name="ref_image_url",
@@ -199,6 +200,7 @@ class Flux1(Node):
199
200
  value=1024,
200
201
  max=1536,
201
202
  condition="return fieldsData.model.value !== 'FLUX.1 [pro] ultra'",
203
+ condition_python=lambda ports: ports["model"].value != "FLUX.1 [pro] ultra",
202
204
  ),
203
205
  "height": InputPort(
204
206
  name="height",
@@ -206,6 +208,7 @@ class Flux1(Node):
206
208
  value=1024,
207
209
  max=1536,
208
210
  condition="return fieldsData.model.value !== 'FLUX.1 [pro] ultra'",
211
+ condition_python=lambda ports: ports["model"].value != "FLUX.1 [pro] ultra",
209
212
  ),
210
213
  "aspect_ratio": InputPort(
211
214
  name="aspect_ratio",
@@ -221,12 +224,14 @@ class Flux1(Node):
221
224
  {"value": "9:21", "label": "9:21"},
222
225
  ],
223
226
  condition="return fieldsData.model.value === 'FLUX.1 [pro] ultra'",
227
+ condition_python=lambda ports: ports["model"].value == "FLUX.1 [pro] ultra",
224
228
  ),
225
229
  "raw": InputPort(
226
230
  name="raw",
227
231
  port_type=PortType.CHECKBOX,
228
232
  value=False,
229
233
  condition="return fieldsData.model.value === 'FLUX.1 [pro] ultra'",
234
+ condition_python=lambda ports: ports["model"].value == "FLUX.1 [pro] ultra",
230
235
  ),
231
236
  "steps": InputPort(
232
237
  name="steps",
@@ -284,6 +289,7 @@ class Inpainting(Node):
284
289
  value=list(),
285
290
  support_file_types=[".jpg", ".jpeg", ".png", ".webp"],
286
291
  condition="return fieldsData.inpainting_method.value === 'custom'",
292
+ condition_python=lambda ports: ports["inpainting_method"].value == "custom",
287
293
  multiple=True,
288
294
  ),
289
295
  "prompt": InputPort(
@@ -314,6 +320,7 @@ class Inpainting(Node):
314
320
  "output": OutputPort(),
315
321
  "output_mask": OutputPort(
316
322
  condition="return fieldsData.inpainting_method.value === 'smart'",
323
+ condition_python=lambda ports: ports["inpainting_method"].value == "smart",
317
324
  ),
318
325
  },
319
326
  )
@@ -437,12 +444,14 @@ class Pulid(Node):
437
444
  port_type=PortType.NUMBER,
438
445
  value=1024,
439
446
  condition="return fieldsData.image_size.value === 'custom'",
447
+ condition_python=lambda ports: ports["image_size"].value == "custom",
440
448
  ),
441
449
  "custom_height": InputPort(
442
450
  name="custom_height",
443
451
  port_type=PortType.NUMBER,
444
452
  value=768,
445
453
  condition="return fieldsData.image_size.value === 'custom'",
454
+ condition_python=lambda ports: ports["image_size"].value == "custom",
446
455
  ),
447
456
  "num_inference_steps": InputPort(
448
457
  name="num_inference_steps",
@@ -518,12 +527,14 @@ class Recraft(Node):
518
527
  support_file_types=[".jpg", ".jpeg", ".png", ".webp"],
519
528
  multiple=True,
520
529
  condition="return fieldsData.generation_type.value === 'image_to_vector'",
530
+ condition_python=lambda ports: ports["generation_type"].value == "image_to_vector",
521
531
  ),
522
532
  "prompt": InputPort(
523
533
  name="prompt",
524
534
  port_type=PortType.TEXTAREA,
525
535
  value="",
526
536
  condition="return fieldsData.generation_type.value === 'text_to_image'",
537
+ condition_python=lambda ports: ports["generation_type"].value == "text_to_image",
527
538
  multiple=True,
528
539
  ),
529
540
  "base_style": InputPort(
@@ -537,6 +548,7 @@ class Recraft(Node):
537
548
  {"value": "vector_illustration", "label": "vector_illustration"},
538
549
  ],
539
550
  condition="return fieldsData.generation_type.value === 'text_to_image'",
551
+ condition_python=lambda ports: ports["generation_type"].value == "text_to_image",
540
552
  multiple=True,
541
553
  ),
542
554
  "substyle_realistic_image": InputPort(
@@ -554,6 +566,8 @@ class Recraft(Node):
554
566
  {"value": "motion_blur", "label": "motion_blur"},
555
567
  ],
556
568
  condition="return fieldsData.generation_type.value === 'text_to_image' && fieldsData.base_style.value === 'realistic_image'",
569
+ condition_python=lambda ports: ports["generation_type"].value == "text_to_image"
570
+ and ports["base_style"].value == "realistic_image",
557
571
  multiple=True,
558
572
  ),
559
573
  "substyle_digital_illustration": InputPort(
@@ -573,6 +587,8 @@ class Recraft(Node):
573
587
  {"value": "2d_art_poster_2", "label": "2d_art_poster_2"},
574
588
  ],
575
589
  condition="return fieldsData.generation_type.value === 'text_to_image' && fieldsData.base_style.value === 'digital_illustration'",
590
+ condition_python=lambda ports: ports["generation_type"].value == "text_to_image"
591
+ and ports["base_style"].value == "digital_illustration",
576
592
  multiple=True,
577
593
  ),
578
594
  "substyle_vector_illustration": InputPort(
@@ -587,6 +603,8 @@ class Recraft(Node):
587
603
  {"value": "linocut", "label": "linocut"},
588
604
  ],
589
605
  condition="return fieldsData.generation_type.value === 'text_to_image' && fieldsData.base_style.value === 'vector_illustration'",
606
+ condition_python=lambda ports: ports["generation_type"].value == "text_to_image"
607
+ and ports["base_style"].value == "vector_illustration",
590
608
  multiple=True,
591
609
  ),
592
610
  "size": InputPort(
@@ -611,6 +629,7 @@ class Recraft(Node):
611
629
  {"value": "1707x1024", "label": "1707x1024"},
612
630
  ],
613
631
  condition="return fieldsData.generation_type.value === 'text_to_image'",
632
+ condition_python=lambda ports: ports["generation_type"].value == "text_to_image",
614
633
  ),
615
634
  "colors": InputPort(
616
635
  name="colors",
@@ -618,6 +637,7 @@ class Recraft(Node):
618
637
  value=list(),
619
638
  multiple=True,
620
639
  condition="return fieldsData.generation_type.value === 'text_to_image'",
640
+ condition_python=lambda ports: ports["generation_type"].value == "text_to_image",
621
641
  ),
622
642
  "background_color": InputPort(
623
643
  name="background_color",
@@ -626,6 +646,7 @@ class Recraft(Node):
626
646
  multiple=True,
627
647
  max_count=1,
628
648
  condition="return fieldsData.generation_type.value === 'text_to_image'",
649
+ condition_python=lambda ports: ports["generation_type"].value == "text_to_image",
629
650
  ),
630
651
  "output_type": InputPort(
631
652
  name="output_type",
@@ -146,10 +146,12 @@ class Baichuan(Node):
146
146
  "function_call_output": OutputPort(
147
147
  name="function_call_output",
148
148
  condition="return fieldsData.use_function_call.value",
149
+ condition_python=lambda ports: ports["use_function_call"].value,
149
150
  ),
150
151
  "function_call_arguments": OutputPort(
151
152
  name="function_call_arguments",
152
153
  condition="return fieldsData.use_function_call.value",
154
+ condition_python=lambda ports: ports["use_function_call"].value,
153
155
  ),
154
156
  },
155
157
  )
@@ -269,10 +271,12 @@ class ChatGLM(Node):
269
271
  "function_call_output": OutputPort(
270
272
  name="function_call_output",
271
273
  condition="return fieldsData.use_function_call.value",
274
+ condition_python=lambda ports: ports["use_function_call"].value,
272
275
  ),
273
276
  "function_call_arguments": OutputPort(
274
277
  name="function_call_arguments",
275
278
  condition="return fieldsData.use_function_call.value",
279
+ condition_python=lambda ports: ports["use_function_call"].value,
276
280
  ),
277
281
  },
278
282
  )
@@ -404,14 +408,17 @@ class Deepseek(Node):
404
408
  "reasoning_content": OutputPort(
405
409
  name="reasoning_content",
406
410
  condition="return fieldsData.llm_model.value === 'deepseek-reasoner'",
411
+ condition_python=lambda ports: ports["llm_model"].value == "deepseek-reasoner",
407
412
  ),
408
413
  "function_call_output": OutputPort(
409
414
  name="function_call_output",
410
415
  condition="return fieldsData.use_function_call.value",
416
+ condition_python=lambda ports: ports["use_function_call"].value,
411
417
  ),
412
418
  "function_call_arguments": OutputPort(
413
419
  name="function_call_arguments",
414
420
  condition="return fieldsData.use_function_call.value",
421
+ condition_python=lambda ports: ports["use_function_call"].value,
415
422
  ),
416
423
  },
417
424
  )
@@ -505,10 +512,12 @@ class Gemini(Node):
505
512
  "function_call_output": OutputPort(
506
513
  name="function_call_output",
507
514
  condition="return fieldsData.use_function_call.value",
515
+ condition_python=lambda ports: ports["use_function_call"].value,
508
516
  ),
509
517
  "function_call_arguments": OutputPort(
510
518
  name="function_call_arguments",
511
519
  condition="return fieldsData.use_function_call.value",
520
+ condition_python=lambda ports: ports["use_function_call"].value,
512
521
  ),
513
522
  },
514
523
  )
@@ -636,10 +645,12 @@ class MiniMax(Node):
636
645
  "function_call_output": OutputPort(
637
646
  name="function_call_output",
638
647
  condition="return fieldsData.use_function_call.value",
648
+ condition_python=lambda ports: ports["use_function_call"].value,
639
649
  ),
640
650
  "function_call_arguments": OutputPort(
641
651
  name="function_call_arguments",
642
652
  condition="return fieldsData.use_function_call.value",
653
+ condition_python=lambda ports: ports["use_function_call"].value,
643
654
  ),
644
655
  },
645
656
  )
@@ -723,10 +734,12 @@ class Moonshot(Node):
723
734
  "function_call_output": OutputPort(
724
735
  name="function_call_output",
725
736
  condition="return fieldsData.use_function_call.value",
737
+ condition_python=lambda ports: ports["use_function_call"].value,
726
738
  ),
727
739
  "function_call_arguments": OutputPort(
728
740
  name="function_call_arguments",
729
741
  condition="return fieldsData.use_function_call.value",
742
+ condition_python=lambda ports: ports["use_function_call"].value,
730
743
  ),
731
744
  },
732
745
  )
@@ -814,10 +827,12 @@ class OpenAI(Node):
814
827
  "function_call_output": OutputPort(
815
828
  name="function_call_output",
816
829
  condition="return fieldsData.use_function_call.value",
830
+ condition_python=lambda ports: ports["use_function_call"].value,
817
831
  ),
818
832
  "function_call_arguments": OutputPort(
819
833
  name="function_call_arguments",
820
834
  condition="return fieldsData.use_function_call.value",
835
+ condition_python=lambda ports: ports["use_function_call"].value,
821
836
  ),
822
837
  },
823
838
  )
@@ -899,10 +914,12 @@ class XAi(Node):
899
914
  "function_call_output": OutputPort(
900
915
  name="function_call_output",
901
916
  condition="return fieldsData.use_function_call.value",
917
+ condition_python=lambda ports: ports["use_function_call"].value,
902
918
  ),
903
919
  "function_call_arguments": OutputPort(
904
920
  name="function_call_arguments",
905
921
  condition="return fieldsData.use_function_call.value",
922
+ condition_python=lambda ports: ports["use_function_call"].value,
906
923
  ),
907
924
  },
908
925
  )
@@ -988,10 +1005,12 @@ class CustomModel(Node):
988
1005
  "function_call_output": OutputPort(
989
1006
  name="function_call_output",
990
1007
  condition="return fieldsData.use_function_call.value",
1008
+ condition_python=lambda ports: ports["use_function_call"].value,
991
1009
  ),
992
1010
  "function_call_arguments": OutputPort(
993
1011
  name="function_call_arguments",
994
1012
  condition="return fieldsData.use_function_call.value",
1013
+ condition_python=lambda ports: ports["use_function_call"].value,
995
1014
  ),
996
1015
  },
997
1016
  )