vellum-ai 1.0.11__py3-none-any.whl → 1.1.0__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.
- vellum/__init__.py +2 -2
- vellum/client/__init__.py +0 -4
- vellum/client/core/client_wrapper.py +2 -2
- vellum/client/reference.md +2 -3
- vellum/client/resources/__init__.py +0 -2
- vellum/client/resources/workflow_deployments/client.py +119 -0
- vellum/client/types/__init__.py +2 -0
- vellum/client/types/api_request_parent_context.py +1 -0
- vellum/client/types/external_parent_context.py +36 -0
- vellum/client/types/node_execution_fulfilled_event.py +1 -0
- vellum/client/types/node_execution_initiated_event.py +1 -0
- vellum/client/types/node_execution_paused_event.py +1 -0
- vellum/client/types/node_execution_rejected_event.py +1 -0
- vellum/client/types/node_execution_resumed_event.py +1 -0
- vellum/client/types/node_execution_span.py +1 -0
- vellum/client/types/node_execution_span_attributes.py +1 -0
- vellum/client/types/node_execution_streaming_event.py +1 -0
- vellum/client/types/node_parent_context.py +1 -0
- vellum/client/types/parent_context.py +2 -0
- vellum/client/types/prompt_deployment_parent_context.py +1 -0
- vellum/client/types/slim_workflow_execution_read.py +1 -0
- vellum/client/types/span_link.py +1 -0
- vellum/client/types/workflow_deployment_event_executions_response.py +1 -0
- vellum/client/types/workflow_deployment_parent_context.py +1 -0
- vellum/client/types/workflow_event_execution_read.py +1 -0
- vellum/client/types/workflow_execution_detail.py +1 -0
- vellum/client/types/workflow_execution_fulfilled_event.py +1 -0
- vellum/client/types/workflow_execution_initiated_event.py +1 -0
- vellum/client/types/workflow_execution_paused_event.py +1 -0
- vellum/client/types/workflow_execution_rejected_event.py +1 -0
- vellum/client/types/workflow_execution_resumed_event.py +1 -0
- vellum/client/types/workflow_execution_snapshotted_event.py +1 -0
- vellum/client/types/workflow_execution_span.py +1 -0
- vellum/client/types/workflow_execution_span_attributes.py +1 -0
- vellum/client/types/workflow_execution_streaming_event.py +1 -0
- vellum/client/types/workflow_parent_context.py +1 -0
- vellum/client/types/workflow_sandbox_parent_context.py +1 -0
- vellum/{resources/release_reviews/__init__.py → types/external_parent_context.py} +1 -1
- vellum/workflows/emitters/vellum_emitter.py +3 -2
- vellum/workflows/events/types.py +6 -0
- vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py +5 -15
- vellum/workflows/nodes/displayable/tool_calling_node/node.py +6 -0
- vellum/workflows/nodes/displayable/tool_calling_node/utils.py +75 -0
- vellum/workflows/state/context.py +13 -2
- vellum/workflows/types/definition.py +2 -2
- vellum/workflows/types/tests/test_definition.py +2 -3
- vellum/workflows/utils/functions.py +1 -1
- vellum/workflows/utils/tests/test_functions.py +3 -3
- {vellum_ai-1.0.11.dist-info → vellum_ai-1.1.0.dist-info}/METADATA +1 -1
- {vellum_ai-1.0.11.dist-info → vellum_ai-1.1.0.dist-info}/RECORD +57 -58
- vellum_ee/workflows/display/nodes/vellum/tests/test_tool_calling_node.py +93 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_mcp_serialization.py +98 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_workflow_deployment_serialization.py +1 -1
- vellum_ee/workflows/display/utils/expressions.py +1 -1
- vellum/client/resources/release_reviews/__init__.py +0 -2
- vellum/client/resources/release_reviews/client.py +0 -139
- vellum/resources/release_reviews/client.py +0 -3
- {vellum_ai-1.0.11.dist-info → vellum_ai-1.1.0.dist-info}/LICENSE +0 -0
- {vellum_ai-1.0.11.dist-info → vellum_ai-1.1.0.dist-info}/WHEEL +0 -0
- {vellum_ai-1.0.11.dist-info → vellum_ai-1.1.0.dist-info}/entry_points.txt +0 -0
@@ -3,6 +3,7 @@ from vellum.workflows.inputs import BaseInputs
|
|
3
3
|
from vellum.workflows.nodes.displayable.inline_prompt_node.node import InlinePromptNode
|
4
4
|
from vellum.workflows.nodes.displayable.tool_calling_node.node import ToolCallingNode
|
5
5
|
from vellum.workflows.state.base import BaseState
|
6
|
+
from vellum.workflows.types.definition import AuthorizationType, EnvironmentVariableReference, MCPServer
|
6
7
|
from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
|
7
8
|
|
8
9
|
|
@@ -122,3 +123,95 @@ def test_serialize_node__prompt_inputs__mixed_values():
|
|
122
123
|
],
|
123
124
|
},
|
124
125
|
}
|
126
|
+
|
127
|
+
|
128
|
+
def test_serialize_node__tool_calling_node__mcp_server_api_key():
|
129
|
+
# GIVEN a tool calling node with an mcp server
|
130
|
+
class MyToolCallingNode(ToolCallingNode):
|
131
|
+
functions = [
|
132
|
+
MCPServer(
|
133
|
+
name="my-mcp-server",
|
134
|
+
url="https://my-mcp-server.com",
|
135
|
+
authorization_type=AuthorizationType.API_KEY,
|
136
|
+
api_key_header_key="my-api-key-header-key",
|
137
|
+
api_key_header_value=EnvironmentVariableReference(name="my-api-key-header-value"),
|
138
|
+
)
|
139
|
+
]
|
140
|
+
|
141
|
+
# AND a workflow with the tool calling node
|
142
|
+
class Workflow(BaseWorkflow):
|
143
|
+
graph = MyToolCallingNode
|
144
|
+
|
145
|
+
# WHEN the workflow is serialized
|
146
|
+
workflow_display = get_workflow_display(workflow_class=Workflow)
|
147
|
+
serialized_workflow: dict = workflow_display.serialize()
|
148
|
+
|
149
|
+
# THEN the node should properly serialize the mcp server
|
150
|
+
my_tool_calling_node = next(
|
151
|
+
node
|
152
|
+
for node in serialized_workflow["workflow_raw_data"]["nodes"]
|
153
|
+
if node["id"] == str(MyToolCallingNode.__id__)
|
154
|
+
)
|
155
|
+
|
156
|
+
functions_attribute = next(
|
157
|
+
attribute for attribute in my_tool_calling_node["attributes"] if attribute["name"] == "functions"
|
158
|
+
)
|
159
|
+
|
160
|
+
assert functions_attribute == {
|
161
|
+
"id": "6c0f7d4f-3c8a-4201-b588-8398d3c97480",
|
162
|
+
"name": "functions",
|
163
|
+
"value": {
|
164
|
+
"type": "ARRAY_REFERENCE",
|
165
|
+
"items": [
|
166
|
+
{
|
167
|
+
"type": "DICTIONARY_REFERENCE",
|
168
|
+
"entries": [
|
169
|
+
{
|
170
|
+
"id": "bcf2713b-19fc-4b4b-8ff5-b45c8e63c665",
|
171
|
+
"key": "type",
|
172
|
+
"value": {"type": "CONSTANT_VALUE", "value": {"type": "STRING", "value": "MCP_SERVER"}},
|
173
|
+
},
|
174
|
+
{
|
175
|
+
"id": "4e00439e-ce6f-4e0a-be4c-0fc05990ec44",
|
176
|
+
"key": "name",
|
177
|
+
"value": {"type": "CONSTANT_VALUE", "value": {"type": "STRING", "value": "my-mcp-server"}},
|
178
|
+
},
|
179
|
+
{
|
180
|
+
"id": "9a3dcca9-4595-4efb-ada6-c011721f7018",
|
181
|
+
"key": "url",
|
182
|
+
"value": {
|
183
|
+
"type": "CONSTANT_VALUE",
|
184
|
+
"value": {"type": "STRING", "value": "https://my-mcp-server.com"},
|
185
|
+
},
|
186
|
+
},
|
187
|
+
{
|
188
|
+
"id": "21c3a6ce-7607-42a4-92b8-9d7c4061edce",
|
189
|
+
"key": "authorization_type",
|
190
|
+
"value": {"type": "CONSTANT_VALUE", "value": {"type": "STRING", "value": "API_KEY"}},
|
191
|
+
},
|
192
|
+
{
|
193
|
+
"id": "dcf8e8f0-84d2-4ffb-b0e6-218c569015a4",
|
194
|
+
"key": "bearer_token_value",
|
195
|
+
"value": {"type": "CONSTANT_VALUE", "value": {"type": "JSON", "value": None}},
|
196
|
+
},
|
197
|
+
{
|
198
|
+
"id": "fe93f516-42c0-40cf-b476-50bd04857d5f",
|
199
|
+
"key": "api_key_header_key",
|
200
|
+
"value": {
|
201
|
+
"type": "CONSTANT_VALUE",
|
202
|
+
"value": {"type": "STRING", "value": "my-api-key-header-key"},
|
203
|
+
},
|
204
|
+
},
|
205
|
+
{
|
206
|
+
"id": "750ed8ca-3bf3-46be-96f0-2c92d19d2084",
|
207
|
+
"key": "api_key_header_value",
|
208
|
+
"value": {
|
209
|
+
"type": "ENVIRONMENT_VARIABLE",
|
210
|
+
"environment_variable": "my-api-key-header-value",
|
211
|
+
},
|
212
|
+
},
|
213
|
+
],
|
214
|
+
}
|
215
|
+
],
|
216
|
+
},
|
217
|
+
}
|
@@ -0,0 +1,98 @@
|
|
1
|
+
from deepdiff import DeepDiff
|
2
|
+
|
3
|
+
from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
|
4
|
+
|
5
|
+
from tests.workflows.basic_tool_calling_node_mcp_tool.workflow import BasicToolCallingNodeMCPWorkflow
|
6
|
+
|
7
|
+
|
8
|
+
def test_serialize_workflow():
|
9
|
+
# GIVEN a Workflow that uses a generic node
|
10
|
+
# WHEN we serialize it
|
11
|
+
workflow_display = get_workflow_display(workflow_class=BasicToolCallingNodeMCPWorkflow)
|
12
|
+
|
13
|
+
serialized_workflow: dict = workflow_display.serialize()
|
14
|
+
# THEN we should get a serialized representation of the Workflow
|
15
|
+
assert serialized_workflow.keys() == {
|
16
|
+
"workflow_raw_data",
|
17
|
+
"input_variables",
|
18
|
+
"state_variables",
|
19
|
+
"output_variables",
|
20
|
+
}
|
21
|
+
|
22
|
+
# AND its input variables should be what we expect
|
23
|
+
input_variables = serialized_workflow["input_variables"]
|
24
|
+
assert len(input_variables) == 1
|
25
|
+
|
26
|
+
# AND its output variables should be what we expect
|
27
|
+
output_variables = serialized_workflow["output_variables"]
|
28
|
+
assert len(output_variables) == 2
|
29
|
+
assert not DeepDiff(
|
30
|
+
[
|
31
|
+
{"id": "3934525a-4807-4dd3-a44f-8569033fece1", "key": "text", "type": "STRING"},
|
32
|
+
{"id": "a6ba35f0-306b-45a4-ad79-c1e9b9a5515c", "key": "chat_history", "type": "CHAT_HISTORY"},
|
33
|
+
],
|
34
|
+
output_variables,
|
35
|
+
ignore_order=True,
|
36
|
+
)
|
37
|
+
|
38
|
+
# AND its raw data should be what we expect
|
39
|
+
workflow_raw_data = serialized_workflow["workflow_raw_data"]
|
40
|
+
tool_calling_node = workflow_raw_data["nodes"][1]
|
41
|
+
function_attributes = next(
|
42
|
+
(attribute for attribute in tool_calling_node["attributes"] if attribute["name"] == "functions"),
|
43
|
+
)
|
44
|
+
assert function_attributes == {
|
45
|
+
"id": "20adf593-c4f0-4c67-8e36-37eb66f28f66",
|
46
|
+
"name": "functions",
|
47
|
+
"value": {
|
48
|
+
"type": "ARRAY_REFERENCE",
|
49
|
+
"items": [
|
50
|
+
{
|
51
|
+
"type": "DICTIONARY_REFERENCE",
|
52
|
+
"entries": [
|
53
|
+
{
|
54
|
+
"id": "bcf2713b-19fc-4b4b-8ff5-b45c8e63c665",
|
55
|
+
"key": "type",
|
56
|
+
"value": {"type": "CONSTANT_VALUE", "value": {"type": "STRING", "value": "MCP_SERVER"}},
|
57
|
+
},
|
58
|
+
{
|
59
|
+
"id": "5a3aef6f-b8a1-4f37-8688-b513da42a35a",
|
60
|
+
"key": "name",
|
61
|
+
"value": {"type": "CONSTANT_VALUE", "value": {"type": "STRING", "value": "github"}},
|
62
|
+
},
|
63
|
+
{
|
64
|
+
"id": "641decf3-79c5-4ef9-9fc8-06570d8a69af",
|
65
|
+
"key": "url",
|
66
|
+
"value": {
|
67
|
+
"type": "CONSTANT_VALUE",
|
68
|
+
"value": {"type": "STRING", "value": "https://api.githubcopilot.com/mcp/"},
|
69
|
+
},
|
70
|
+
},
|
71
|
+
{
|
72
|
+
"id": "801a74ca-7966-4ac3-b1b5-bebb71a7de07",
|
73
|
+
"key": "authorization_type",
|
74
|
+
"value": {"type": "CONSTANT_VALUE", "value": {"type": "STRING", "value": "BEARER_TOKEN"}},
|
75
|
+
},
|
76
|
+
{
|
77
|
+
"id": "fcd70e2f-0fb2-4011-a73b-90d5d7643be4",
|
78
|
+
"key": "bearer_token_value",
|
79
|
+
"value": {
|
80
|
+
"type": "ENVIRONMENT_VARIABLE",
|
81
|
+
"environment_variable": "GITHUB_PERSONAL_ACCESS_TOKEN",
|
82
|
+
},
|
83
|
+
},
|
84
|
+
{
|
85
|
+
"id": "b2fa2900-0e09-44ff-99db-c5399fd76d28",
|
86
|
+
"key": "api_key_header_key",
|
87
|
+
"value": {"type": "CONSTANT_VALUE", "value": {"type": "JSON", "value": None}},
|
88
|
+
},
|
89
|
+
{
|
90
|
+
"id": "6ab23414-5f1b-49c1-a0bc-891bbba9124c",
|
91
|
+
"key": "api_key_header_value",
|
92
|
+
"value": {"type": "CONSTANT_VALUE", "value": {"type": "JSON", "value": None}},
|
93
|
+
},
|
94
|
+
],
|
95
|
+
}
|
96
|
+
],
|
97
|
+
},
|
98
|
+
}
|
@@ -19,7 +19,7 @@ from tests.workflows.basic_tool_calling_node_workflow_deployment.workflow import
|
|
19
19
|
|
20
20
|
|
21
21
|
def test_serialize_workflow(vellum_client):
|
22
|
-
vellum_client.
|
22
|
+
vellum_client.workflow_deployments.retrieve_workflow_deployment_release.return_value = WorkflowDeploymentRelease(
|
23
23
|
id="test-id",
|
24
24
|
created=datetime.now(),
|
25
25
|
environment=ReleaseEnvironment(
|
@@ -358,7 +358,7 @@ def serialize_value(display_context: "WorkflowDisplayContext", value: Any) -> Js
|
|
358
358
|
}
|
359
359
|
|
360
360
|
if isinstance(value, DeploymentDefinition):
|
361
|
-
workflow_deployment_release = display_context.client.
|
361
|
+
workflow_deployment_release = display_context.client.workflow_deployments.retrieve_workflow_deployment_release(
|
362
362
|
value.deployment, value.release_tag
|
363
363
|
)
|
364
364
|
name = workflow_deployment_release.deployment.name or value.deployment
|
@@ -1,139 +0,0 @@
|
|
1
|
-
# This file was auto-generated by Fern from our API Definition.
|
2
|
-
|
3
|
-
from ...core.client_wrapper import SyncClientWrapper
|
4
|
-
import typing
|
5
|
-
from ...core.request_options import RequestOptions
|
6
|
-
from ...types.workflow_deployment_release import WorkflowDeploymentRelease
|
7
|
-
from ...core.jsonable_encoder import jsonable_encoder
|
8
|
-
from ...core.pydantic_utilities import parse_obj_as
|
9
|
-
from json.decoder import JSONDecodeError
|
10
|
-
from ...core.api_error import ApiError
|
11
|
-
from ...core.client_wrapper import AsyncClientWrapper
|
12
|
-
|
13
|
-
|
14
|
-
class ReleaseReviewsClient:
|
15
|
-
def __init__(self, *, client_wrapper: SyncClientWrapper):
|
16
|
-
self._client_wrapper = client_wrapper
|
17
|
-
|
18
|
-
def retrieve_workflow_deployment_release(
|
19
|
-
self, id: str, release_id_or_release_tag: str, *, request_options: typing.Optional[RequestOptions] = None
|
20
|
-
) -> WorkflowDeploymentRelease:
|
21
|
-
"""
|
22
|
-
Retrieve a specific Workflow Deployment Release by either its UUID or the name of a Release Tag that points to it.
|
23
|
-
|
24
|
-
Parameters
|
25
|
-
----------
|
26
|
-
id : str
|
27
|
-
Either the Workflow Deployment's ID or its unique name
|
28
|
-
|
29
|
-
release_id_or_release_tag : str
|
30
|
-
Either the UUID of Workflow Deployment Release you'd like to retrieve, or the name of a Release Tag that's pointing to the Workflow Deployment Release you'd like to retrieve.
|
31
|
-
|
32
|
-
request_options : typing.Optional[RequestOptions]
|
33
|
-
Request-specific configuration.
|
34
|
-
|
35
|
-
Returns
|
36
|
-
-------
|
37
|
-
WorkflowDeploymentRelease
|
38
|
-
|
39
|
-
|
40
|
-
Examples
|
41
|
-
--------
|
42
|
-
from vellum import Vellum
|
43
|
-
|
44
|
-
client = Vellum(
|
45
|
-
api_version="YOUR_API_VERSION",
|
46
|
-
api_key="YOUR_API_KEY",
|
47
|
-
)
|
48
|
-
client.release_reviews.retrieve_workflow_deployment_release(
|
49
|
-
id="id",
|
50
|
-
release_id_or_release_tag="release_id_or_release_tag",
|
51
|
-
)
|
52
|
-
"""
|
53
|
-
_response = self._client_wrapper.httpx_client.request(
|
54
|
-
f"v1/workflow-deployments/{jsonable_encoder(id)}/releases/{jsonable_encoder(release_id_or_release_tag)}",
|
55
|
-
base_url=self._client_wrapper.get_environment().default,
|
56
|
-
method="GET",
|
57
|
-
request_options=request_options,
|
58
|
-
)
|
59
|
-
try:
|
60
|
-
if 200 <= _response.status_code < 300:
|
61
|
-
return typing.cast(
|
62
|
-
WorkflowDeploymentRelease,
|
63
|
-
parse_obj_as(
|
64
|
-
type_=WorkflowDeploymentRelease, # type: ignore
|
65
|
-
object_=_response.json(),
|
66
|
-
),
|
67
|
-
)
|
68
|
-
_response_json = _response.json()
|
69
|
-
except JSONDecodeError:
|
70
|
-
raise ApiError(status_code=_response.status_code, body=_response.text)
|
71
|
-
raise ApiError(status_code=_response.status_code, body=_response_json)
|
72
|
-
|
73
|
-
|
74
|
-
class AsyncReleaseReviewsClient:
|
75
|
-
def __init__(self, *, client_wrapper: AsyncClientWrapper):
|
76
|
-
self._client_wrapper = client_wrapper
|
77
|
-
|
78
|
-
async def retrieve_workflow_deployment_release(
|
79
|
-
self, id: str, release_id_or_release_tag: str, *, request_options: typing.Optional[RequestOptions] = None
|
80
|
-
) -> WorkflowDeploymentRelease:
|
81
|
-
"""
|
82
|
-
Retrieve a specific Workflow Deployment Release by either its UUID or the name of a Release Tag that points to it.
|
83
|
-
|
84
|
-
Parameters
|
85
|
-
----------
|
86
|
-
id : str
|
87
|
-
Either the Workflow Deployment's ID or its unique name
|
88
|
-
|
89
|
-
release_id_or_release_tag : str
|
90
|
-
Either the UUID of Workflow Deployment Release you'd like to retrieve, or the name of a Release Tag that's pointing to the Workflow Deployment Release you'd like to retrieve.
|
91
|
-
|
92
|
-
request_options : typing.Optional[RequestOptions]
|
93
|
-
Request-specific configuration.
|
94
|
-
|
95
|
-
Returns
|
96
|
-
-------
|
97
|
-
WorkflowDeploymentRelease
|
98
|
-
|
99
|
-
|
100
|
-
Examples
|
101
|
-
--------
|
102
|
-
import asyncio
|
103
|
-
|
104
|
-
from vellum import AsyncVellum
|
105
|
-
|
106
|
-
client = AsyncVellum(
|
107
|
-
api_version="YOUR_API_VERSION",
|
108
|
-
api_key="YOUR_API_KEY",
|
109
|
-
)
|
110
|
-
|
111
|
-
|
112
|
-
async def main() -> None:
|
113
|
-
await client.release_reviews.retrieve_workflow_deployment_release(
|
114
|
-
id="id",
|
115
|
-
release_id_or_release_tag="release_id_or_release_tag",
|
116
|
-
)
|
117
|
-
|
118
|
-
|
119
|
-
asyncio.run(main())
|
120
|
-
"""
|
121
|
-
_response = await self._client_wrapper.httpx_client.request(
|
122
|
-
f"v1/workflow-deployments/{jsonable_encoder(id)}/releases/{jsonable_encoder(release_id_or_release_tag)}",
|
123
|
-
base_url=self._client_wrapper.get_environment().default,
|
124
|
-
method="GET",
|
125
|
-
request_options=request_options,
|
126
|
-
)
|
127
|
-
try:
|
128
|
-
if 200 <= _response.status_code < 300:
|
129
|
-
return typing.cast(
|
130
|
-
WorkflowDeploymentRelease,
|
131
|
-
parse_obj_as(
|
132
|
-
type_=WorkflowDeploymentRelease, # type: ignore
|
133
|
-
object_=_response.json(),
|
134
|
-
),
|
135
|
-
)
|
136
|
-
_response_json = _response.json()
|
137
|
-
except JSONDecodeError:
|
138
|
-
raise ApiError(status_code=_response.status_code, body=_response.text)
|
139
|
-
raise ApiError(status_code=_response.status_code, body=_response_json)
|
File without changes
|
File without changes
|
File without changes
|