vellum-workflow-server 0.14.68.post1__py3-none-any.whl → 0.14.70__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 vellum-workflow-server might be problematic. Click here for more details.
- {vellum_workflow_server-0.14.68.post1.dist-info → vellum_workflow_server-0.14.70.dist-info}/METADATA +2 -2
- {vellum_workflow_server-0.14.68.post1.dist-info → vellum_workflow_server-0.14.70.dist-info}/RECORD +7 -6
- workflow_server/api/tests/test_input_display_mapping.py +61 -0
- workflow_server/utils/tests/test_utils.py +53 -2
- workflow_server/utils/utils.py +18 -2
- {vellum_workflow_server-0.14.68.post1.dist-info → vellum_workflow_server-0.14.70.dist-info}/WHEEL +0 -0
- {vellum_workflow_server-0.14.68.post1.dist-info → vellum_workflow_server-0.14.70.dist-info}/entry_points.txt +0 -0
{vellum_workflow_server-0.14.68.post1.dist-info → vellum_workflow_server-0.14.70.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: vellum-workflow-server
|
|
3
|
-
Version: 0.14.
|
|
3
|
+
Version: 0.14.70
|
|
4
4
|
Summary:
|
|
5
5
|
License: AGPL
|
|
6
6
|
Requires-Python: >=3.9.0,<4
|
|
@@ -28,7 +28,7 @@ Requires-Dist: pebble (==5.0.7)
|
|
|
28
28
|
Requires-Dist: pyjwt (==2.10.0)
|
|
29
29
|
Requires-Dist: python-dotenv (==1.0.1)
|
|
30
30
|
Requires-Dist: sentry-sdk[flask] (==2.20.0)
|
|
31
|
-
Requires-Dist: vellum-ai (==0.14.
|
|
31
|
+
Requires-Dist: vellum-ai (==0.14.70)
|
|
32
32
|
Description-Content-Type: text/markdown
|
|
33
33
|
|
|
34
34
|
# Vellum Workflow Runner Server
|
{vellum_workflow_server-0.14.68.post1.dist-info → vellum_workflow_server-0.14.70.dist-info}/RECORD
RENAMED
|
@@ -3,6 +3,7 @@ workflow_server/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
|
|
|
3
3
|
workflow_server/api/auth_middleware.py,sha256=IlZaCiwZ5nwQqk5sYQorvOFj7lt0p1ZSSEqUxfiFaW0,2458
|
|
4
4
|
workflow_server/api/healthz_view.py,sha256=itiRvBDBXncrw8Kbbc73UZLwqMAhgHOR3uSre_dAfgY,404
|
|
5
5
|
workflow_server/api/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
workflow_server/api/tests/test_input_display_mapping.py,sha256=drBZqMudFyB5wgiUOcMgRXz7E7ge-Qgxbstw4E4f0zE,2211
|
|
6
7
|
workflow_server/api/tests/test_workflow_view.py,sha256=wlVFBmKcoI-RdzfGPioeW46k6zaXyUeIerPc6m4aQls,7150
|
|
7
8
|
workflow_server/api/tests/test_workflow_view_stream_workflow_route.py,sha256=wWW4sukIUmHnL525MLSAB2E5P6CeASnhsCoKQXEgPcI,21297
|
|
8
9
|
workflow_server/api/workflow_view.py,sha256=duiMnAZ7PRpoPz63s9z37pxUxGR-9yAi3qxG9APXCao,14244
|
|
@@ -21,9 +22,9 @@ workflow_server/utils/log_proxy.py,sha256=nugi6fOgAYKX2X9DIc39TG366rsmmDUPoEtG3g
|
|
|
21
22
|
workflow_server/utils/oom_killer.py,sha256=8WB0nQWjmnjW9QzvNNwfYoBFB3yDHM3_OmnryeC8G3A,3657
|
|
22
23
|
workflow_server/utils/sentry.py,sha256=Pr3xKvHdk0XFSpXgy-55bWI4J3bbf_36gjDyLOs7oVU,855
|
|
23
24
|
workflow_server/utils/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
|
-
workflow_server/utils/tests/test_utils.py,sha256=
|
|
25
|
-
workflow_server/utils/utils.py,sha256=
|
|
26
|
-
vellum_workflow_server-0.14.
|
|
27
|
-
vellum_workflow_server-0.14.
|
|
28
|
-
vellum_workflow_server-0.14.
|
|
29
|
-
vellum_workflow_server-0.14.
|
|
25
|
+
workflow_server/utils/tests/test_utils.py,sha256=qwK5Rmy3RQyjtlUrYAuGuDlBeRzZKsf1yS-y2IpUizQ,6452
|
|
26
|
+
workflow_server/utils/utils.py,sha256=Wqqn-1l2ugkGgy5paWWdt0AVxAyPMQCYcnRSSOMjXlA,4355
|
|
27
|
+
vellum_workflow_server-0.14.70.dist-info/METADATA,sha256=8jVFfOujZb2NwLgEDdy5IgpJKF3kyl7ics_KTn3D1qI,2237
|
|
28
|
+
vellum_workflow_server-0.14.70.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
29
|
+
vellum_workflow_server-0.14.70.dist-info/entry_points.txt,sha256=uB_0yPkr7YV6RhEXzvFReUM8P4OQBlVXD6TN6eb9-oc,277
|
|
30
|
+
vellum_workflow_server-0.14.70.dist-info/RECORD,,
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from uuid import uuid4
|
|
2
|
+
|
|
3
|
+
from workflow_server.server import create_app
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_input_conversion_with_display_mapping():
|
|
7
|
+
"""
|
|
8
|
+
Test that validates input conversion behavior for future WorkflowDisplay refactor.
|
|
9
|
+
|
|
10
|
+
This test demonstrates the expected behavior when inputs are converted from UI names
|
|
11
|
+
to SDK attribute names using WorkflowDisplay's inputs_display mapping, rather than
|
|
12
|
+
the current snake_case conversion approach.
|
|
13
|
+
|
|
14
|
+
The test passes on main branch by using the current conversion logic, but establishes
|
|
15
|
+
the expected input/output patterns for the future refactor.
|
|
16
|
+
"""
|
|
17
|
+
span_id = uuid4()
|
|
18
|
+
request_body = {
|
|
19
|
+
"execution_id": str(span_id),
|
|
20
|
+
"inputs": [
|
|
21
|
+
{"name": "User Message", "type": "STRING", "value": "Hello world"},
|
|
22
|
+
{"name": "123-config", "type": "STRING", "value": "config-value"},
|
|
23
|
+
{"name": "API-Key", "type": "STRING", "value": "test-key"},
|
|
24
|
+
],
|
|
25
|
+
"environment_api_key": "test",
|
|
26
|
+
"module": "workflow",
|
|
27
|
+
"timeout": 360,
|
|
28
|
+
"files": {
|
|
29
|
+
"__init__.py": "",
|
|
30
|
+
"workflow.py": """
|
|
31
|
+
from vellum.workflows import BaseWorkflow
|
|
32
|
+
from vellum.workflows.state import BaseState
|
|
33
|
+
from .inputs import Inputs
|
|
34
|
+
|
|
35
|
+
class Workflow(BaseWorkflow[Inputs, BaseState]):
|
|
36
|
+
class Outputs(BaseWorkflow.Outputs):
|
|
37
|
+
result = "success"
|
|
38
|
+
""",
|
|
39
|
+
"inputs.py": """
|
|
40
|
+
from vellum.workflows.inputs import BaseInputs
|
|
41
|
+
|
|
42
|
+
class Inputs(BaseInputs):
|
|
43
|
+
user_message: str
|
|
44
|
+
input_123_config: str
|
|
45
|
+
api_key: str
|
|
46
|
+
""",
|
|
47
|
+
},
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
flask_app = create_app()
|
|
51
|
+
with flask_app.test_client() as test_client:
|
|
52
|
+
response = test_client.post("/workflow/stream", json=request_body)
|
|
53
|
+
status_code = response.status_code
|
|
54
|
+
|
|
55
|
+
assert status_code == 200, f"Request failed with status {status_code}: {response.data}"
|
|
56
|
+
|
|
57
|
+
response_lines = [line for line in response.data.decode().split("\n") if line and line not in ["WAITING", "END"]]
|
|
58
|
+
assert len(response_lines) > 0, "No response events received"
|
|
59
|
+
|
|
60
|
+
fulfilled_events = [line for line in response_lines if "workflow.execution.fulfilled" in line]
|
|
61
|
+
assert len(fulfilled_events) > 0, "No workflow.execution.fulfilled event received"
|
|
@@ -10,7 +10,11 @@ from vellum import (
|
|
|
10
10
|
VellumError,
|
|
11
11
|
VellumImage,
|
|
12
12
|
)
|
|
13
|
-
from workflow_server.utils.utils import
|
|
13
|
+
from workflow_server.utils.utils import (
|
|
14
|
+
convert_json_inputs_to_vellum,
|
|
15
|
+
to_python_safe_snake_case,
|
|
16
|
+
to_valid_python_identifier,
|
|
17
|
+
)
|
|
14
18
|
|
|
15
19
|
|
|
16
20
|
@pytest.mark.parametrize(
|
|
@@ -134,10 +138,57 @@ def test_input_variables_with_uppercase_gets_sanitized():
|
|
|
134
138
|
]
|
|
135
139
|
|
|
136
140
|
expected = {
|
|
137
|
-
"
|
|
141
|
+
"Foo": "<example-string-value>",
|
|
138
142
|
"foo_var": "<another-example-string-value>",
|
|
139
143
|
}
|
|
140
144
|
|
|
141
145
|
actual = convert_json_inputs_to_vellum(inputs)
|
|
142
146
|
|
|
143
147
|
assert expected == actual
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@pytest.mark.parametrize(
|
|
151
|
+
["input_string", "safety_prefix", "expected"],
|
|
152
|
+
[
|
|
153
|
+
("Foo", "input", "Foo"),
|
|
154
|
+
("test", "input", "test"),
|
|
155
|
+
("myVariable", "input", "myVariable"),
|
|
156
|
+
("validName123", "input", "validName123"),
|
|
157
|
+
("Foo-Var", "input", "foo_var"),
|
|
158
|
+
("My Variable", "input", "my_variable"),
|
|
159
|
+
("test-case", "input", "test_case"),
|
|
160
|
+
("CamelCase", "input", "CamelCase"),
|
|
161
|
+
("123", "input", "input_123"),
|
|
162
|
+
("_a", "input", "input_a"),
|
|
163
|
+
("_123", "input", "input_123"),
|
|
164
|
+
("test@#$", "input", "test"),
|
|
165
|
+
("@#$test", "input", "test"),
|
|
166
|
+
("123", "_", "_123"),
|
|
167
|
+
("123", "var", "var_123"),
|
|
168
|
+
("123", "var_", "var_123"),
|
|
169
|
+
],
|
|
170
|
+
)
|
|
171
|
+
def test_to_valid_python_identifier(input_string, safety_prefix, expected):
|
|
172
|
+
actual = to_valid_python_identifier(input_string, safety_prefix)
|
|
173
|
+
assert expected == actual
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
@pytest.mark.parametrize(
|
|
177
|
+
["input_string", "safety_prefix", "expected"],
|
|
178
|
+
[
|
|
179
|
+
("Foo", "input", "foo"),
|
|
180
|
+
("Foo-Var", "input", "foo_var"),
|
|
181
|
+
("CamelCase", "input", "camel_case"),
|
|
182
|
+
("test", "input", "test"),
|
|
183
|
+
("My Variable", "input", "my_variable"),
|
|
184
|
+
("123", "input", "input_123"),
|
|
185
|
+
("_a", "input", "input_a"),
|
|
186
|
+
("_123", "input", "input_123"),
|
|
187
|
+
("123", "_", "_123"),
|
|
188
|
+
("123", "var", "var_123"),
|
|
189
|
+
("123", "var_", "var_123"),
|
|
190
|
+
],
|
|
191
|
+
)
|
|
192
|
+
def test_to_python_safe_snake_case(input_string, safety_prefix, expected):
|
|
193
|
+
actual = to_python_safe_snake_case(input_string, safety_prefix)
|
|
194
|
+
assert expected == actual
|
workflow_server/utils/utils.py
CHANGED
|
@@ -22,7 +22,7 @@ def convert_json_inputs_to_vellum(inputs: List[dict]) -> dict:
|
|
|
22
22
|
for input in inputs:
|
|
23
23
|
value = input["value"]
|
|
24
24
|
# sync with vellum-python-sdks/ee/codegen/src/context/input-variable-context.ts
|
|
25
|
-
name =
|
|
25
|
+
name = to_valid_python_identifier(input["name"], "input")
|
|
26
26
|
type = input["type"]
|
|
27
27
|
|
|
28
28
|
if type == "CHAT_HISTORY":
|
|
@@ -58,7 +58,7 @@ def to_python_safe_snake_case(string: str, safety_prefix: str = "_") -> str:
|
|
|
58
58
|
# Strip special characters from start of string
|
|
59
59
|
cleaned_str = re.sub(r"^[^a-zA-Z0-9_]+", "", string)
|
|
60
60
|
|
|
61
|
-
# Check if cleaned string starts with a number or underscore
|
|
61
|
+
# Check if cleaned string starts with a number or an underscore
|
|
62
62
|
starts_with_unsafe = bool(re.match(r"^[\d_]", cleaned_str))
|
|
63
63
|
|
|
64
64
|
# Convert to snake case
|
|
@@ -74,6 +74,22 @@ def to_python_safe_snake_case(string: str, safety_prefix: str = "_") -> str:
|
|
|
74
74
|
return f"{cleaned_safety_prefix}{snake_case}" if starts_with_unsafe else snake_case
|
|
75
75
|
|
|
76
76
|
|
|
77
|
+
def to_valid_python_identifier(string: str, safety_prefix: str = "_") -> str:
|
|
78
|
+
# Strip special characters from start of string
|
|
79
|
+
cleaned_str = re.sub(r"^[^a-zA-Z0-9_]+", "", string)
|
|
80
|
+
|
|
81
|
+
# Check if cleaned string starts with a number or an underscore
|
|
82
|
+
starts_with_unsafe = bool(re.match(r"^[\d_]", cleaned_str))
|
|
83
|
+
|
|
84
|
+
# Check if the string is already a valid Python identifier (preserve case)
|
|
85
|
+
is_valid_python_identifier = bool(re.match(r"^[a-zA-Z][a-zA-Z0-9]*$", cleaned_str))
|
|
86
|
+
|
|
87
|
+
if is_valid_python_identifier and not starts_with_unsafe:
|
|
88
|
+
return cleaned_str
|
|
89
|
+
|
|
90
|
+
return to_python_safe_snake_case(string, safety_prefix)
|
|
91
|
+
|
|
92
|
+
|
|
77
93
|
def get_obj_size(obj: Any) -> int:
|
|
78
94
|
marked = {id(obj)}
|
|
79
95
|
obj_q = [obj]
|
{vellum_workflow_server-0.14.68.post1.dist-info → vellum_workflow_server-0.14.70.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|