vectorvein 0.2.55__py3-none-any.whl → 0.2.57__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.
- vectorvein/chat_clients/anthropic_client.py +12 -2
- vectorvein/workflow/graph/port.py +15 -3
- vectorvein/workflow/graph/workflow.py +12 -1
- vectorvein/workflow/nodes/control_flows.py +2 -0
- vectorvein/workflow/nodes/file_processing.py +5 -0
- vectorvein/workflow/nodes/image_generation.py +21 -0
- vectorvein/workflow/nodes/llms.py +19 -0
- vectorvein/workflow/nodes/media_editing.py +54 -0
- vectorvein/workflow/nodes/media_processing.py +21 -0
- vectorvein/workflow/nodes/output.py +7 -0
- vectorvein/workflow/nodes/relational_db.py +1 -0
- vectorvein/workflow/nodes/text_processing.py +4 -0
- vectorvein/workflow/nodes/tools.py +360 -356
- vectorvein/workflow/nodes/vector_db.py +4 -0
- vectorvein/workflow/nodes/web_crawlers.py +1 -0
- vectorvein/workflow/utils/check.py +79 -0
- {vectorvein-0.2.55.dist-info → vectorvein-0.2.57.dist-info}/METADATA +1 -1
- {vectorvein-0.2.55.dist-info → vectorvein-0.2.57.dist-info}/RECORD +20 -20
- {vectorvein-0.2.55.dist-info → vectorvein-0.2.57.dist-info}/WHEEL +0 -0
- {vectorvein-0.2.55.dist-info → vectorvein-0.2.57.dist-info}/entry_points.txt +0 -0
@@ -52,24 +52,28 @@ class AddData(Node):
|
|
52
52
|
{"value": "table", "label": "table"},
|
53
53
|
],
|
54
54
|
condition="return fieldsData.data_type.value == 'text'",
|
55
|
+
condition_python=lambda ports: ports["data_type"].value == "text",
|
55
56
|
),
|
56
57
|
"chunk_length": InputPort(
|
57
58
|
name="chunk_length",
|
58
59
|
port_type=PortType.NUMBER,
|
59
60
|
value=500,
|
60
61
|
condition="return ['general', 'markdown'].includes(fieldsData.split_method.value)",
|
62
|
+
condition_python=lambda ports: ports["split_method"].value in ["general", "markdown"],
|
61
63
|
),
|
62
64
|
"chunk_overlap": InputPort(
|
63
65
|
name="chunk_overlap",
|
64
66
|
port_type=PortType.NUMBER,
|
65
67
|
value=30,
|
66
68
|
condition="return ['general', 'markdown'].includes(fieldsData.split_method.value)",
|
69
|
+
condition_python=lambda ports: ports["split_method"].value in ["general", "markdown"],
|
67
70
|
),
|
68
71
|
"delimiter": InputPort(
|
69
72
|
name="delimiter",
|
70
73
|
port_type=PortType.INPUT,
|
71
74
|
value="\\n",
|
72
75
|
condition="return fieldsData.split_method.value == 'delimiter'",
|
76
|
+
condition_python=lambda ports: ports["split_method"].value == "delimiter",
|
73
77
|
),
|
74
78
|
"remove_url_and_email": InputPort(
|
75
79
|
name="remove_url_and_email",
|
@@ -138,6 +138,7 @@ class YoutubeCrawler(Node):
|
|
138
138
|
{"value": "detailed", "label": "detailed"},
|
139
139
|
],
|
140
140
|
condition="return fieldsData.get_comments.value",
|
141
|
+
condition_python=lambda ports: ports["get_comments"].value,
|
141
142
|
),
|
142
143
|
"output_type": InputPort(
|
143
144
|
name="output_type",
|
@@ -5,6 +5,7 @@ from ..graph.port import InputPort
|
|
5
5
|
if TYPE_CHECKING:
|
6
6
|
from ..graph.workflow import Workflow
|
7
7
|
from ..graph.node import Node
|
8
|
+
from ..graph.port import Port
|
8
9
|
|
9
10
|
|
10
11
|
class UIWarning(TypedDict, total=False):
|
@@ -22,6 +23,8 @@ class WorkflowCheckResult(TypedDict):
|
|
22
23
|
no_isolated_nodes: bool # 工作流是否不包含孤立节点
|
23
24
|
useless_nodes: list["Node"] # 工作流中无用的节点
|
24
25
|
ui_warnings: UIWarning # UI相关警告
|
26
|
+
required_ports: list[tuple["Node", "Port"]] # 未连接的必填端口
|
27
|
+
override_ports: list[tuple["Node", "Port"]] # 被覆盖的端口
|
25
28
|
|
26
29
|
|
27
30
|
def check_dag(workflow: "Workflow"):
|
@@ -180,3 +183,79 @@ def check_useless_nodes(workflow: "Workflow") -> list["Node"]:
|
|
180
183
|
useless_nodes.append(node)
|
181
184
|
|
182
185
|
return useless_nodes
|
186
|
+
|
187
|
+
|
188
|
+
def check_required_ports(workflow: "Workflow") -> "list[tuple[Node, Port]]":
|
189
|
+
"""检查工作流中是否存在未连接的空的必填端口。"""
|
190
|
+
required_but_not_connected = []
|
191
|
+
|
192
|
+
# 找出所有连接的目标端口
|
193
|
+
connected_ports = {(edge.target, edge.target_handle) for edge in workflow.edges}
|
194
|
+
|
195
|
+
# 遍历所有节点及其端口
|
196
|
+
for node in workflow.nodes:
|
197
|
+
ports = node.ports if hasattr(node, "ports") else {}
|
198
|
+
for port_name, port in ports.items():
|
199
|
+
# 检查条件是否适用
|
200
|
+
condition_applies = True
|
201
|
+
if hasattr(port, "condition_python") and port.condition_python is not None:
|
202
|
+
try:
|
203
|
+
# 检查是否为可调用函数
|
204
|
+
if callable(port.condition_python):
|
205
|
+
# 如果是函数,传入ports作为参数
|
206
|
+
condition_result = port.condition_python(ports)
|
207
|
+
else:
|
208
|
+
raise ValueError(
|
209
|
+
f"condition_python 必须是可调用函数,当前类型为 {type(port.condition_python)}"
|
210
|
+
)
|
211
|
+
|
212
|
+
if not condition_result:
|
213
|
+
condition_applies = False
|
214
|
+
except Exception:
|
215
|
+
# 如果条件评估出错,假设条件不适用
|
216
|
+
condition_applies = False
|
217
|
+
|
218
|
+
# 检查端口是否必填
|
219
|
+
is_required = getattr(port, "required", False)
|
220
|
+
|
221
|
+
# 检查值是否为空
|
222
|
+
value_is_empty = getattr(port, "value", "") == ""
|
223
|
+
|
224
|
+
# 检查是否没有连线连接到这个端口
|
225
|
+
not_connected = (node.id, port_name) not in connected_ports
|
226
|
+
|
227
|
+
# 如果满足所有条件,将其添加到结果列表
|
228
|
+
if condition_applies and is_required and value_is_empty and not_connected:
|
229
|
+
required_but_not_connected.append((node, port))
|
230
|
+
|
231
|
+
return required_but_not_connected
|
232
|
+
|
233
|
+
|
234
|
+
def check_override_ports(workflow: "Workflow") -> list[tuple["Node", "Port"]]:
|
235
|
+
"""检查工作流中是否存在覆盖的端口。
|
236
|
+
|
237
|
+
一个端口如果其 value 值不是布尔值,且不为空(空字符串、空列表、空字典),
|
238
|
+
然后还被一个连线作为输出端口连接了,那么这个端口的 value 值会被覆盖。
|
239
|
+
"""
|
240
|
+
override_ports = []
|
241
|
+
|
242
|
+
# 找出所有作为输出端口的连接
|
243
|
+
target_ports = {(edge.target, edge.target_handle) for edge in workflow.edges}
|
244
|
+
|
245
|
+
for node in workflow.nodes:
|
246
|
+
for port_name, port in node.ports.items():
|
247
|
+
# 检查端口是否被作为输出端口连接
|
248
|
+
if (node.id, port_name) in target_ports:
|
249
|
+
value = port.value
|
250
|
+
|
251
|
+
# 检查 value 是否为布尔值
|
252
|
+
if isinstance(value, bool):
|
253
|
+
continue
|
254
|
+
|
255
|
+
# 检查 value 是否为空
|
256
|
+
is_empty = value == "" or value == [] or value == {} or value is None
|
257
|
+
|
258
|
+
if not is_empty:
|
259
|
+
override_ports.append((node, port))
|
260
|
+
|
261
|
+
return override_ports
|
@@ -1,13 +1,13 @@
|
|
1
|
-
vectorvein-0.2.
|
2
|
-
vectorvein-0.2.
|
3
|
-
vectorvein-0.2.
|
1
|
+
vectorvein-0.2.57.dist-info/METADATA,sha256=VJeKL2r_44yXAPf6bThgchug8uSWNxcx3IR2zB6iwyM,4570
|
2
|
+
vectorvein-0.2.57.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
|
3
|
+
vectorvein-0.2.57.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
|
4
4
|
vectorvein/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
5
|
vectorvein/api/__init__.py,sha256=lfY-XA46fgD2iIZTU0VYP8i07AwA03Egj4Qua0vUKrQ,738
|
6
6
|
vectorvein/api/client.py,sha256=xF-leKDQzVyyy9FnIRaz0k4eElYW1XbbzeRLcpnyk90,33047
|
7
7
|
vectorvein/api/exceptions.py,sha256=uS_PAdx0ksC0r3dgfSGWdbLMZm4qdLeWSSqCv1g3_Gc,772
|
8
8
|
vectorvein/api/models.py,sha256=xtPWMsB0yIJI7i-gY4B6MtvXv0ZIXnoeKspmeInH6fU,1449
|
9
9
|
vectorvein/chat_clients/__init__.py,sha256=UIytpIgwo8qkZpIyrHVxLYTyliUOTp4J7C4iHRjbtWE,23850
|
10
|
-
vectorvein/chat_clients/anthropic_client.py,sha256=
|
10
|
+
vectorvein/chat_clients/anthropic_client.py,sha256=yrGb87h_hpxhK-O3Ir0L5yMHLimPgzaJqdW4AjzskHk,68924
|
11
11
|
vectorvein/chat_clients/baichuan_client.py,sha256=CVMvpgjdrZGv0BWnTOBD-f2ufZ3wq3496wqukumsAr4,526
|
12
12
|
vectorvein/chat_clients/base_client.py,sha256=p7s-G4Wh9MSpDKEfG8wuFAeWy5DGvj5Go31hqrpQPhM,38817
|
13
13
|
vectorvein/chat_clients/deepseek_client.py,sha256=3qWu01NlJAP2N-Ff62d5-CZXZitlizE1fzb20LNetig,526
|
@@ -43,25 +43,25 @@ vectorvein/utilities/rate_limiter.py,sha256=dwolIUVw2wP83Odqpx0AAaE77de1GzxkYDGH
|
|
43
43
|
vectorvein/utilities/retry.py,sha256=6KFS9R2HdhqM3_9jkjD4F36ZSpEx2YNFGOVlpOsUetM,2208
|
44
44
|
vectorvein/workflow/graph/edge.py,sha256=1ckyyjCue_PLm7P1ItUfKOy6AKkemOpZ9m1WJ8UXIHQ,1072
|
45
45
|
vectorvein/workflow/graph/node.py,sha256=ZzOhl7pltPBR5gyyL2ZtYeByPxjDPnM179emliqGFi8,5192
|
46
|
-
vectorvein/workflow/graph/port.py,sha256=
|
47
|
-
vectorvein/workflow/graph/workflow.py,sha256=
|
46
|
+
vectorvein/workflow/graph/port.py,sha256=HcinzQqNP7ysTvBmi3c4iaWne8nV6m-BpFFX0jTrMIE,7122
|
47
|
+
vectorvein/workflow/graph/workflow.py,sha256=f5KAQUXTKii7UFYmSZeZZQ7JCKKPmJlUg0iFAfBEJQE,6366
|
48
48
|
vectorvein/workflow/nodes/__init__.py,sha256=dWrWtL3q0Vsn-MLgJ7gNgLCrwZ5BrqjrN2QFPNeBMuc,3240
|
49
49
|
vectorvein/workflow/nodes/audio_generation.py,sha256=ZRFZ_ycMTSJ2LKmekctagQdJYTl-3q4TNOIKETpS9AM,5870
|
50
|
-
vectorvein/workflow/nodes/control_flows.py,sha256=
|
51
|
-
vectorvein/workflow/nodes/file_processing.py,sha256=
|
52
|
-
vectorvein/workflow/nodes/image_generation.py,sha256=
|
53
|
-
vectorvein/workflow/nodes/llms.py,sha256=
|
54
|
-
vectorvein/workflow/nodes/media_editing.py,sha256=
|
55
|
-
vectorvein/workflow/nodes/media_processing.py,sha256=
|
56
|
-
vectorvein/workflow/nodes/output.py,sha256=
|
57
|
-
vectorvein/workflow/nodes/relational_db.py,sha256=
|
58
|
-
vectorvein/workflow/nodes/text_processing.py,sha256=
|
59
|
-
vectorvein/workflow/nodes/tools.py,sha256=
|
50
|
+
vectorvein/workflow/nodes/control_flows.py,sha256=fDySWek8Isbfznwn0thmbTwTP4c99w68Up9dlASAtIo,6805
|
51
|
+
vectorvein/workflow/nodes/file_processing.py,sha256=f4PlfgSAVFhwuqcEAvcLarNIkHUFP4FJucxnb3kekTU,4498
|
52
|
+
vectorvein/workflow/nodes/image_generation.py,sha256=a1ObkmvM8dwMxQvsnoYJwaURn0WwLXsqVkPybRnXT9A,35708
|
53
|
+
vectorvein/workflow/nodes/llms.py,sha256=ePnWAF4q-Uai5ZHgrYb7ZeoWzjIZ9B8XGAPPT5QEO10,40238
|
54
|
+
vectorvein/workflow/nodes/media_editing.py,sha256=ut4NN9_VUqnsqT2rlv0JrLhyxRLNUkvHb0c4QZDiKz8,34320
|
55
|
+
vectorvein/workflow/nodes/media_processing.py,sha256=_YuoJur2EeIeZfg8dSigDtqYcUpN6uVjGXJSVNqa6uI,22067
|
56
|
+
vectorvein/workflow/nodes/output.py,sha256=JHp-Y9EtuwD9qtZvVV2zHkH1OEK_6xlYh_DT1LrKuBs,13174
|
57
|
+
vectorvein/workflow/nodes/relational_db.py,sha256=Zg4G3xIQ94uoWE-Z4YER1bBhWgBQ6mYbJVQDeAN895I,5498
|
58
|
+
vectorvein/workflow/nodes/text_processing.py,sha256=BRmFSyLPADFplbUqUNjoJdmHzQvrPknJvBvvgtzaklk,8744
|
59
|
+
vectorvein/workflow/nodes/tools.py,sha256=ejIQO2hfuRr6m1jc9NMZEUK9ABEWPpX0PVO_UA5BtSc,13853
|
60
60
|
vectorvein/workflow/nodes/triggers.py,sha256=BolH4X6S8HSuU2kwHmYKr-ozHbgKBmdZRcnXpK5EfGA,597
|
61
|
-
vectorvein/workflow/nodes/vector_db.py,sha256=
|
61
|
+
vectorvein/workflow/nodes/vector_db.py,sha256=p9AT_E8ASbcYHZqHYTCIGvqkIqzxaFM4UxaUELJEe-c,6112
|
62
62
|
vectorvein/workflow/nodes/video_generation.py,sha256=qmdg-t_idpxq1veukd-jv_ChICMOoInKxprV9Z4Vi2w,4118
|
63
|
-
vectorvein/workflow/nodes/web_crawlers.py,sha256=
|
64
|
-
vectorvein/workflow/utils/check.py,sha256=
|
63
|
+
vectorvein/workflow/nodes/web_crawlers.py,sha256=FB0bTimkk___p3Z5UwQx2YarJyQCc45jjnbXbgGA_qw,5640
|
64
|
+
vectorvein/workflow/utils/check.py,sha256=Oj_S5WQf4_Fr_ro3ipjZt9unKFSFcuwZrrSmrS9kVLE,10193
|
65
65
|
vectorvein/workflow/utils/json_to_code.py,sha256=F7dhDy8kGc8ndOeihGLRLGFGlquoxVlb02ENtxnQ0C8,5914
|
66
66
|
vectorvein/workflow/utils/layout.py,sha256=j0bRD3uaXu40xCS6U6BGahBI8FrHa5MiF55GbTrZ1LM,4565
|
67
|
-
vectorvein-0.2.
|
67
|
+
vectorvein-0.2.57.dist-info/RECORD,,
|
File without changes
|
File without changes
|