vellum-ai 1.5.1__py3-none-any.whl → 1.5.3__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.
Files changed (27) hide show
  1. vellum/__init__.py +4 -0
  2. vellum/client/core/client_wrapper.py +2 -2
  3. vellum/client/reference.md +16 -0
  4. vellum/client/resources/document_indexes/client.py +26 -4
  5. vellum/client/resources/document_indexes/raw_client.py +22 -2
  6. vellum/client/resources/workflow_deployments/client.py +8 -2
  7. vellum/client/resources/workflow_deployments/raw_client.py +8 -0
  8. vellum/client/types/__init__.py +4 -0
  9. vellum/client/types/indexing_config_vectorizer.py +2 -0
  10. vellum/client/types/indexing_config_vectorizer_request.py +2 -0
  11. vellum/client/types/private_vectorizer.py +23 -0
  12. vellum/client/types/private_vectorizer_request.py +23 -0
  13. vellum/client/types/vellum_error_code_enum.py +1 -1
  14. vellum/types/private_vectorizer.py +3 -0
  15. vellum/types/private_vectorizer_request.py +3 -0
  16. vellum/workflows/integrations/tests/test_vellum_integration_service.py +173 -192
  17. vellum/workflows/integrations/vellum_integration_service.py +14 -12
  18. vellum/workflows/types/definition.py +11 -0
  19. vellum/workflows/utils/functions.py +5 -3
  20. {vellum_ai-1.5.1.dist-info → vellum_ai-1.5.3.dist-info}/METADATA +1 -1
  21. {vellum_ai-1.5.1.dist-info → vellum_ai-1.5.3.dist-info}/RECORD +27 -23
  22. vellum_ee/assets/node-definitions.json +49 -8
  23. vellum_ee/scripts/generate_node_definitions.py +1 -1
  24. vellum_ee/workflows/display/nodes/vellum/map_node.py +17 -3
  25. {vellum_ai-1.5.1.dist-info → vellum_ai-1.5.3.dist-info}/LICENSE +0 -0
  26. {vellum_ai-1.5.1.dist-info → vellum_ai-1.5.3.dist-info}/WHEEL +0 -0
  27. {vellum_ai-1.5.1.dist-info → vellum_ai-1.5.3.dist-info}/entry_points.txt +0 -0
vellum/__init__.py CHANGED
@@ -348,6 +348,8 @@ from .client.types import (
348
348
  PdfSearchResultMetaSourceRequest,
349
349
  PlainTextPromptBlock,
350
350
  Price,
351
+ PrivateVectorizer,
352
+ PrivateVectorizerRequest,
351
353
  ProcessingFailureReasonEnum,
352
354
  PromptBlock,
353
355
  PromptBlockState,
@@ -1073,6 +1075,8 @@ __all__ = [
1073
1075
  "PdfSearchResultMetaSourceRequest",
1074
1076
  "PlainTextPromptBlock",
1075
1077
  "Price",
1078
+ "PrivateVectorizer",
1079
+ "PrivateVectorizerRequest",
1076
1080
  "ProcessingFailureReasonEnum",
1077
1081
  "PromptBlock",
1078
1082
  "PromptBlockState",
@@ -27,10 +27,10 @@ class BaseClientWrapper:
27
27
 
28
28
  def get_headers(self) -> typing.Dict[str, str]:
29
29
  headers: typing.Dict[str, str] = {
30
- "User-Agent": "vellum-ai/1.5.1",
30
+ "User-Agent": "vellum-ai/1.5.3",
31
31
  "X-Fern-Language": "Python",
32
32
  "X-Fern-SDK-Name": "vellum-ai",
33
- "X-Fern-SDK-Version": "1.5.1",
33
+ "X-Fern-SDK-Version": "1.5.3",
34
34
  **(self.get_custom_headers() or {}),
35
35
  }
36
36
  if self._api_version is not None:
@@ -3122,6 +3122,14 @@ client.document_indexes.retrieve(
3122
3122
  <dl>
3123
3123
  <dd>
3124
3124
 
3125
+ **mask_indexing_config:** `typing.Optional[bool]` — Whether to mask the indexing configuration in the response
3126
+
3127
+ </dd>
3128
+ </dl>
3129
+
3130
+ <dl>
3131
+ <dd>
3132
+
3125
3133
  **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
3126
3134
 
3127
3135
  </dd>
@@ -5810,6 +5818,14 @@ client.workflow_deployments.list_workflow_deployment_event_executions(
5810
5818
  <dl>
5811
5819
  <dd>
5812
5820
 
5821
+ **ordering:** `typing.Optional[str]`
5822
+
5823
+ </dd>
5824
+ </dl>
5825
+
5826
+ <dl>
5827
+ <dd>
5828
+
5813
5829
  **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
5814
5830
 
5815
5831
  </dd>
@@ -163,7 +163,13 @@ class DocumentIndexesClient:
163
163
  )
164
164
  return _response.data
165
165
 
166
- def retrieve(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> DocumentIndexRead:
166
+ def retrieve(
167
+ self,
168
+ id: str,
169
+ *,
170
+ mask_indexing_config: typing.Optional[bool] = None,
171
+ request_options: typing.Optional[RequestOptions] = None,
172
+ ) -> DocumentIndexRead:
167
173
  """
168
174
  Used to retrieve a Document Index given its ID or name.
169
175
 
@@ -172,6 +178,9 @@ class DocumentIndexesClient:
172
178
  id : str
173
179
  Either the Document Index's ID or its unique name
174
180
 
181
+ mask_indexing_config : typing.Optional[bool]
182
+ Whether to mask the indexing configuration in the response
183
+
175
184
  request_options : typing.Optional[RequestOptions]
176
185
  Request-specific configuration.
177
186
 
@@ -192,7 +201,9 @@ class DocumentIndexesClient:
192
201
  id="id",
193
202
  )
194
203
  """
195
- _response = self._raw_client.retrieve(id, request_options=request_options)
204
+ _response = self._raw_client.retrieve(
205
+ id, mask_indexing_config=mask_indexing_config, request_options=request_options
206
+ )
196
207
  return _response.data
197
208
 
198
209
  def update(
@@ -558,7 +569,13 @@ class AsyncDocumentIndexesClient:
558
569
  )
559
570
  return _response.data
560
571
 
561
- async def retrieve(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> DocumentIndexRead:
572
+ async def retrieve(
573
+ self,
574
+ id: str,
575
+ *,
576
+ mask_indexing_config: typing.Optional[bool] = None,
577
+ request_options: typing.Optional[RequestOptions] = None,
578
+ ) -> DocumentIndexRead:
562
579
  """
563
580
  Used to retrieve a Document Index given its ID or name.
564
581
 
@@ -567,6 +584,9 @@ class AsyncDocumentIndexesClient:
567
584
  id : str
568
585
  Either the Document Index's ID or its unique name
569
586
 
587
+ mask_indexing_config : typing.Optional[bool]
588
+ Whether to mask the indexing configuration in the response
589
+
570
590
  request_options : typing.Optional[RequestOptions]
571
591
  Request-specific configuration.
572
592
 
@@ -595,7 +615,9 @@ class AsyncDocumentIndexesClient:
595
615
 
596
616
  asyncio.run(main())
597
617
  """
598
- _response = await self._raw_client.retrieve(id, request_options=request_options)
618
+ _response = await self._raw_client.retrieve(
619
+ id, mask_indexing_config=mask_indexing_config, request_options=request_options
620
+ )
599
621
  return _response.data
600
622
 
601
623
  async def update(
@@ -168,7 +168,11 @@ class RawDocumentIndexesClient:
168
168
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
169
169
 
170
170
  def retrieve(
171
- self, id: str, *, request_options: typing.Optional[RequestOptions] = None
171
+ self,
172
+ id: str,
173
+ *,
174
+ mask_indexing_config: typing.Optional[bool] = None,
175
+ request_options: typing.Optional[RequestOptions] = None,
172
176
  ) -> HttpResponse[DocumentIndexRead]:
173
177
  """
174
178
  Used to retrieve a Document Index given its ID or name.
@@ -178,6 +182,9 @@ class RawDocumentIndexesClient:
178
182
  id : str
179
183
  Either the Document Index's ID or its unique name
180
184
 
185
+ mask_indexing_config : typing.Optional[bool]
186
+ Whether to mask the indexing configuration in the response
187
+
181
188
  request_options : typing.Optional[RequestOptions]
182
189
  Request-specific configuration.
183
190
 
@@ -190,6 +197,9 @@ class RawDocumentIndexesClient:
190
197
  f"v1/document-indexes/{jsonable_encoder(id)}",
191
198
  base_url=self._client_wrapper.get_environment().default,
192
199
  method="GET",
200
+ params={
201
+ "mask_indexing_config": mask_indexing_config,
202
+ },
193
203
  request_options=request_options,
194
204
  )
195
205
  try:
@@ -580,7 +590,11 @@ class AsyncRawDocumentIndexesClient:
580
590
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
581
591
 
582
592
  async def retrieve(
583
- self, id: str, *, request_options: typing.Optional[RequestOptions] = None
593
+ self,
594
+ id: str,
595
+ *,
596
+ mask_indexing_config: typing.Optional[bool] = None,
597
+ request_options: typing.Optional[RequestOptions] = None,
584
598
  ) -> AsyncHttpResponse[DocumentIndexRead]:
585
599
  """
586
600
  Used to retrieve a Document Index given its ID or name.
@@ -590,6 +604,9 @@ class AsyncRawDocumentIndexesClient:
590
604
  id : str
591
605
  Either the Document Index's ID or its unique name
592
606
 
607
+ mask_indexing_config : typing.Optional[bool]
608
+ Whether to mask the indexing configuration in the response
609
+
593
610
  request_options : typing.Optional[RequestOptions]
594
611
  Request-specific configuration.
595
612
 
@@ -602,6 +619,9 @@ class AsyncRawDocumentIndexesClient:
602
619
  f"v1/document-indexes/{jsonable_encoder(id)}",
603
620
  base_url=self._client_wrapper.get_environment().default,
604
621
  method="GET",
622
+ params={
623
+ "mask_indexing_config": mask_indexing_config,
624
+ },
605
625
  request_options=request_options,
606
626
  )
607
627
  try:
@@ -127,6 +127,7 @@ class WorkflowDeploymentsClient:
127
127
  filters: typing.Optional[str] = None,
128
128
  limit: typing.Optional[int] = None,
129
129
  offset: typing.Optional[int] = None,
130
+ ordering: typing.Optional[str] = None,
130
131
  request_options: typing.Optional[RequestOptions] = None,
131
132
  ) -> WorkflowDeploymentEventExecutionsResponse:
132
133
  """
@@ -142,6 +143,8 @@ class WorkflowDeploymentsClient:
142
143
  offset : typing.Optional[int]
143
144
  The initial index from which to return the executions.
144
145
 
146
+ ordering : typing.Optional[str]
147
+
145
148
  request_options : typing.Optional[RequestOptions]
146
149
  Request-specific configuration.
147
150
 
@@ -163,7 +166,7 @@ class WorkflowDeploymentsClient:
163
166
  )
164
167
  """
165
168
  _response = self._raw_client.list_workflow_deployment_event_executions(
166
- id, filters=filters, limit=limit, offset=offset, request_options=request_options
169
+ id, filters=filters, limit=limit, offset=offset, ordering=ordering, request_options=request_options
167
170
  )
168
171
  return _response.data
169
172
 
@@ -546,6 +549,7 @@ class AsyncWorkflowDeploymentsClient:
546
549
  filters: typing.Optional[str] = None,
547
550
  limit: typing.Optional[int] = None,
548
551
  offset: typing.Optional[int] = None,
552
+ ordering: typing.Optional[str] = None,
549
553
  request_options: typing.Optional[RequestOptions] = None,
550
554
  ) -> WorkflowDeploymentEventExecutionsResponse:
551
555
  """
@@ -561,6 +565,8 @@ class AsyncWorkflowDeploymentsClient:
561
565
  offset : typing.Optional[int]
562
566
  The initial index from which to return the executions.
563
567
 
568
+ ordering : typing.Optional[str]
569
+
564
570
  request_options : typing.Optional[RequestOptions]
565
571
  Request-specific configuration.
566
572
 
@@ -590,7 +596,7 @@ class AsyncWorkflowDeploymentsClient:
590
596
  asyncio.run(main())
591
597
  """
592
598
  _response = await self._raw_client.list_workflow_deployment_event_executions(
593
- id, filters=filters, limit=limit, offset=offset, request_options=request_options
599
+ id, filters=filters, limit=limit, offset=offset, ordering=ordering, request_options=request_options
594
600
  )
595
601
  return _response.data
596
602
 
@@ -136,6 +136,7 @@ class RawWorkflowDeploymentsClient:
136
136
  filters: typing.Optional[str] = None,
137
137
  limit: typing.Optional[int] = None,
138
138
  offset: typing.Optional[int] = None,
139
+ ordering: typing.Optional[str] = None,
139
140
  request_options: typing.Optional[RequestOptions] = None,
140
141
  ) -> HttpResponse[WorkflowDeploymentEventExecutionsResponse]:
141
142
  """
@@ -151,6 +152,8 @@ class RawWorkflowDeploymentsClient:
151
152
  offset : typing.Optional[int]
152
153
  The initial index from which to return the executions.
153
154
 
155
+ ordering : typing.Optional[str]
156
+
154
157
  request_options : typing.Optional[RequestOptions]
155
158
  Request-specific configuration.
156
159
 
@@ -167,6 +170,7 @@ class RawWorkflowDeploymentsClient:
167
170
  "filters": filters,
168
171
  "limit": limit,
169
172
  "offset": offset,
173
+ "ordering": ordering,
170
174
  },
171
175
  request_options=request_options,
172
176
  )
@@ -589,6 +593,7 @@ class AsyncRawWorkflowDeploymentsClient:
589
593
  filters: typing.Optional[str] = None,
590
594
  limit: typing.Optional[int] = None,
591
595
  offset: typing.Optional[int] = None,
596
+ ordering: typing.Optional[str] = None,
592
597
  request_options: typing.Optional[RequestOptions] = None,
593
598
  ) -> AsyncHttpResponse[WorkflowDeploymentEventExecutionsResponse]:
594
599
  """
@@ -604,6 +609,8 @@ class AsyncRawWorkflowDeploymentsClient:
604
609
  offset : typing.Optional[int]
605
610
  The initial index from which to return the executions.
606
611
 
612
+ ordering : typing.Optional[str]
613
+
607
614
  request_options : typing.Optional[RequestOptions]
608
615
  Request-specific configuration.
609
616
 
@@ -620,6 +627,7 @@ class AsyncRawWorkflowDeploymentsClient:
620
627
  "filters": filters,
621
628
  "limit": limit,
622
629
  "offset": offset,
630
+ "ordering": ordering,
623
631
  },
624
632
  request_options=request_options,
625
633
  )
@@ -356,6 +356,8 @@ from .pdf_search_result_meta_source import PdfSearchResultMetaSource
356
356
  from .pdf_search_result_meta_source_request import PdfSearchResultMetaSourceRequest
357
357
  from .plain_text_prompt_block import PlainTextPromptBlock
358
358
  from .price import Price
359
+ from .private_vectorizer import PrivateVectorizer
360
+ from .private_vectorizer_request import PrivateVectorizerRequest
359
361
  from .processing_failure_reason_enum import ProcessingFailureReasonEnum
360
362
  from .prompt_block import PromptBlock
361
363
  from .prompt_block_state import PromptBlockState
@@ -1044,6 +1046,8 @@ __all__ = [
1044
1046
  "PdfSearchResultMetaSourceRequest",
1045
1047
  "PlainTextPromptBlock",
1046
1048
  "Price",
1049
+ "PrivateVectorizer",
1050
+ "PrivateVectorizerRequest",
1047
1051
  "ProcessingFailureReasonEnum",
1048
1052
  "PromptBlock",
1049
1053
  "PromptBlockState",
@@ -19,6 +19,7 @@ from .hkunlp_instructor_xl_vectorizer import HkunlpInstructorXlVectorizer
19
19
  from .open_ai_vectorizer_text_embedding_3_large import OpenAiVectorizerTextEmbedding3Large
20
20
  from .open_ai_vectorizer_text_embedding_3_small import OpenAiVectorizerTextEmbedding3Small
21
21
  from .open_ai_vectorizer_text_embedding_ada_002 import OpenAiVectorizerTextEmbeddingAda002
22
+ from .private_vectorizer import PrivateVectorizer
22
23
 
23
24
  IndexingConfigVectorizer = typing.Union[
24
25
  OpenAiVectorizerTextEmbedding3Small,
@@ -32,4 +33,5 @@ IndexingConfigVectorizer = typing.Union[
32
33
  GoogleVertexAiVectorizerTextMultilingualEmbedding002,
33
34
  GoogleVertexAiVectorizerGeminiEmbedding001,
34
35
  FastEmbedVectorizerBaaiBgeSmallEnV15,
36
+ PrivateVectorizer,
35
37
  ]
@@ -19,6 +19,7 @@ from .hkunlp_instructor_xl_vectorizer_request import HkunlpInstructorXlVectorize
19
19
  from .open_ai_vectorizer_text_embedding_3_large_request import OpenAiVectorizerTextEmbedding3LargeRequest
20
20
  from .open_ai_vectorizer_text_embedding_3_small_request import OpenAiVectorizerTextEmbedding3SmallRequest
21
21
  from .open_ai_vectorizer_text_embedding_ada_002_request import OpenAiVectorizerTextEmbeddingAda002Request
22
+ from .private_vectorizer_request import PrivateVectorizerRequest
22
23
 
23
24
  IndexingConfigVectorizerRequest = typing.Union[
24
25
  OpenAiVectorizerTextEmbedding3SmallRequest,
@@ -32,4 +33,5 @@ IndexingConfigVectorizerRequest = typing.Union[
32
33
  GoogleVertexAiVectorizerTextMultilingualEmbedding002Request,
33
34
  GoogleVertexAiVectorizerGeminiEmbedding001Request,
34
35
  FastEmbedVectorizerBaaiBgeSmallEnV15Request,
36
+ PrivateVectorizerRequest,
35
37
  ]
@@ -0,0 +1,23 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+
8
+
9
+ class PrivateVectorizer(UniversalBaseModel):
10
+ """
11
+ Serializer for private vectorizer.
12
+ """
13
+
14
+ model_name: typing.Literal["private-vectorizer"] = "private-vectorizer"
15
+
16
+ if IS_PYDANTIC_V2:
17
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
18
+ else:
19
+
20
+ class Config:
21
+ frozen = True
22
+ smart_union = True
23
+ extra = pydantic.Extra.allow
@@ -0,0 +1,23 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+
8
+
9
+ class PrivateVectorizerRequest(UniversalBaseModel):
10
+ """
11
+ Serializer for private vectorizer.
12
+ """
13
+
14
+ model_name: typing.Literal["private-vectorizer"] = "private-vectorizer"
15
+
16
+ if IS_PYDANTIC_V2:
17
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
18
+ else:
19
+
20
+ class Config:
21
+ frozen = True
22
+ smart_union = True
23
+ extra = pydantic.Extra.allow
@@ -7,7 +7,7 @@ VellumErrorCodeEnum = typing.Union[
7
7
  "INVALID_REQUEST",
8
8
  "INVALID_INPUTS",
9
9
  "PROVIDER_ERROR",
10
- "PROVIDER_CREDENTIALS_AVAILABLE",
10
+ "PROVIDER_CREDENTIALS_UNAVAILABLE",
11
11
  "REQUEST_TIMEOUT",
12
12
  "INTERNAL_SERVER_ERROR",
13
13
  "USER_DEFINED_ERROR",
@@ -0,0 +1,3 @@
1
+ # WARNING: This file will be removed in a future release. Please import from "vellum.client" instead.
2
+
3
+ from vellum.client.types.private_vectorizer import *
@@ -0,0 +1,3 @@
1
+ # WARNING: This file will be removed in a future release. Please import from "vellum.client" instead.
2
+
3
+ from vellum.client.types.private_vectorizer_request import *
@@ -1,225 +1,206 @@
1
1
  import pytest
2
2
  from unittest import mock
3
3
 
4
+ from vellum.workflows.constants import VellumIntegrationProviderType
4
5
  from vellum.workflows.exceptions import NodeException
5
6
  from vellum.workflows.integrations.vellum_integration_service import VellumIntegrationService
7
+ from vellum.workflows.types.definition import VellumIntegrationToolDetails
6
8
 
7
9
 
8
- def test_vellum_integration_service_get_tool_definition_success():
10
+ def test_vellum_integration_service_get_tool_definition_success(vellum_client):
9
11
  """Test that tool definitions are successfully retrieved from Vellum API"""
10
- with mock.patch(
11
- "vellum.workflows.integrations.vellum_integration_service.create_vellum_client"
12
- ) as mock_create_client:
13
- # GIVEN a mock Vellum client configured to return a tool definition
14
- mock_client = mock.MagicMock()
15
- mock_create_client.return_value = mock_client
16
-
17
- mock_response = mock.MagicMock()
18
- mock_response.name = "GITHUB_CREATE_AN_ISSUE"
19
- mock_response.description = "Create a new issue in a GitHub repository"
20
- mock_response.parameters = {
21
- "type": "object",
22
- "properties": {
23
- "repo": {"type": "string", "description": "Repository name"},
24
- "title": {"type": "string", "description": "Issue title"},
25
- "body": {"type": "string", "description": "Issue body"},
26
- },
27
- "required": ["repo", "title"],
28
- }
29
- mock_response.provider = "COMPOSIO"
30
-
31
- mock_client.integrations.retrieve_integration_tool_definition.return_value = mock_response
32
-
33
- # WHEN we request a tool definition
34
- service = VellumIntegrationService()
35
- result = service.get_tool_definition(
36
- integration="GITHUB",
37
- provider="COMPOSIO",
38
- tool_name="GITHUB_CREATE_AN_ISSUE",
39
- )
12
+ mock_client = vellum_client
13
+ mock_client.integrations = mock.MagicMock()
14
+
15
+ mock_response = mock.MagicMock()
16
+ mock_response.name = "GITHUB_CREATE_AN_ISSUE"
17
+ mock_response.description = "Create a new issue in a GitHub repository"
18
+ mock_response.parameters = {
19
+ "type": "object",
20
+ "properties": {
21
+ "repo": {"type": "string", "description": "Repository name"},
22
+ "title": {"type": "string", "description": "Issue title"},
23
+ "body": {"type": "string", "description": "Issue body"},
24
+ },
25
+ "required": ["repo", "title"],
26
+ }
27
+ mock_response.provider = "COMPOSIO"
28
+
29
+ mock_client.integrations.retrieve_integration_tool_definition.return_value = mock_response
30
+
31
+ # WHEN we request a tool definition
32
+ service = VellumIntegrationService(client=mock_client)
33
+ result = service.get_tool_definition(
34
+ integration="GITHUB",
35
+ provider="COMPOSIO",
36
+ tool_name="GITHUB_CREATE_AN_ISSUE",
37
+ )
38
+
39
+ # THEN the tool definition should be returned with all expected fields
40
+ assert isinstance(result, VellumIntegrationToolDetails)
41
+ assert result.name == "GITHUB_CREATE_AN_ISSUE"
42
+ assert result.description == "Create a new issue in a GitHub repository"
43
+ assert result.provider == VellumIntegrationProviderType.COMPOSIO
44
+ # Parameters should now be included in the tool details
45
+ assert result.parameters is not None
46
+ assert result.parameters["type"] == "object"
47
+ assert "properties" in result.parameters
48
+ assert "repo" in result.parameters["properties"]
49
+ assert "title" in result.parameters["properties"]
50
+
51
+ # AND the API should have been called with the correct parameters
52
+ mock_client.integrations.retrieve_integration_tool_definition.assert_called_once_with(
53
+ integration="GITHUB",
54
+ provider="COMPOSIO",
55
+ tool_name="GITHUB_CREATE_AN_ISSUE",
56
+ )
57
+
58
+
59
+ def test_vellum_integration_service_get_tool_definition_api_error(vellum_client):
60
+ """Test that API errors are properly handled when retrieving tool definitions"""
61
+ mock_client = vellum_client
62
+ mock_client.integrations = mock.MagicMock()
63
+ mock_client.integrations.retrieve_integration_tool_definition.side_effect = Exception("Tool not found")
40
64
 
41
- # THEN the tool definition should be returned with all expected fields
42
- assert result["name"] == "GITHUB_CREATE_AN_ISSUE"
43
- assert result["description"] == "Create a new issue in a GitHub repository"
44
- assert result["provider"] == "COMPOSIO"
45
- assert "properties" in result["parameters"]
46
- assert "repo" in result["parameters"]["properties"]
65
+ # WHEN we attempt to get a tool definition for an invalid tool
66
+ service = VellumIntegrationService(client=mock_client)
47
67
 
48
- # AND the API should have been called with the correct parameters
49
- mock_client.integrations.retrieve_integration_tool_definition.assert_called_once_with(
68
+ # THEN it should raise a NodeException with appropriate error message
69
+ with pytest.raises(NodeException) as exc_info:
70
+ service.get_tool_definition(
50
71
  integration="GITHUB",
51
72
  provider="COMPOSIO",
52
- tool_name="GITHUB_CREATE_AN_ISSUE",
73
+ tool_name="INVALID_TOOL",
53
74
  )
54
75
 
55
-
56
- def test_vellum_integration_service_get_tool_definition_api_error():
57
- """Test that API errors are properly handled when retrieving tool definitions"""
58
- with mock.patch(
59
- "vellum.workflows.integrations.vellum_integration_service.create_vellum_client"
60
- ) as mock_create_client:
61
- # GIVEN a mock client that raises an exception when retrieving tool definitions
62
- mock_client = mock.MagicMock()
63
- mock_create_client.return_value = mock_client
64
-
65
- mock_client.integrations.retrieve_integration_tool_definition.side_effect = Exception("Tool not found")
66
-
67
- # WHEN we attempt to get a tool definition for an invalid tool
68
- service = VellumIntegrationService()
69
-
70
- # THEN it should raise a NodeException with appropriate error message
71
- with pytest.raises(NodeException) as exc_info:
72
- service.get_tool_definition(
73
- integration="GITHUB",
74
- provider="COMPOSIO",
75
- tool_name="INVALID_TOOL",
76
- )
77
-
78
- assert "Failed to retrieve tool definition" in str(exc_info.value)
79
- assert "Tool not found" in str(exc_info.value)
76
+ assert "Failed to retrieve tool definition" in str(exc_info.value)
77
+ assert "Tool not found" in str(exc_info.value)
80
78
 
81
79
 
82
- def test_vellum_integration_service_execute_tool_success():
80
+ def test_vellum_integration_service_execute_tool_success(vellum_client):
83
81
  """Test that tools are successfully executed via Vellum API"""
84
- with mock.patch(
85
- "vellum.workflows.integrations.vellum_integration_service.create_vellum_client"
86
- ) as mock_create_client:
87
- # GIVEN a mock client configured to return successful execution results
88
- mock_client = mock.MagicMock()
89
- mock_create_client.return_value = mock_client
90
-
91
- mock_response = mock.MagicMock()
92
- mock_response.data = {
93
- "success": True,
94
- "issue_id": 123,
95
- "issue_url": "https://github.com/user/repo/issues/123",
96
- }
97
-
98
- mock_client.integrations.execute_integration_tool.return_value = mock_response
99
-
100
- # WHEN we execute a tool with valid arguments
101
- service = VellumIntegrationService()
102
- result = service.execute_tool(
103
- integration="GITHUB",
104
- provider="COMPOSIO",
105
- tool_name="GITHUB_CREATE_AN_ISSUE",
106
- arguments={
107
- "repo": "user/repo",
108
- "title": "Test Issue",
109
- "body": "Test body",
110
- },
111
- )
82
+ mock_client = vellum_client
83
+ mock_client.integrations = mock.MagicMock()
84
+
85
+ mock_response = mock.MagicMock()
86
+ mock_response.data = {
87
+ "success": True,
88
+ "issue_id": 123,
89
+ "issue_url": "https://github.com/user/repo/issues/123",
90
+ }
91
+
92
+ mock_client.integrations.execute_integration_tool.return_value = mock_response
93
+
94
+ # WHEN we execute a tool with valid arguments
95
+ service = VellumIntegrationService(client=mock_client)
96
+ result = service.execute_tool(
97
+ integration="GITHUB",
98
+ provider="COMPOSIO",
99
+ tool_name="GITHUB_CREATE_AN_ISSUE",
100
+ arguments={
101
+ "repo": "user/repo",
102
+ "title": "Test Issue",
103
+ "body": "Test body",
104
+ },
105
+ )
106
+
107
+ # THEN the execution result should contain expected data
108
+ assert result["success"] is True
109
+ assert result["issue_id"] == 123
110
+ assert result["issue_url"] == "https://github.com/user/repo/issues/123"
111
+
112
+ # AND the API should have been called with correct parameters
113
+ mock_client.integrations.execute_integration_tool.assert_called_once_with(
114
+ integration="GITHUB",
115
+ provider="COMPOSIO",
116
+ tool_name="GITHUB_CREATE_AN_ISSUE",
117
+ arguments={
118
+ "repo": "user/repo",
119
+ "title": "Test Issue",
120
+ "body": "Test body",
121
+ },
122
+ )
123
+
124
+
125
+ def test_vellum_integration_service_execute_tool_api_error(vellum_client):
126
+ """Test that execution errors are properly handled"""
127
+ mock_client = vellum_client
128
+ mock_client.integrations = mock.MagicMock()
129
+ mock_client.integrations.execute_integration_tool.side_effect = Exception("Authentication failed")
112
130
 
113
- # THEN the execution result should contain expected data
114
- assert result["success"] is True
115
- assert result["issue_id"] == 123
116
- assert result["issue_url"] == "https://github.com/user/repo/issues/123"
131
+ # WHEN we attempt to execute a tool that encounters an error
132
+ service = VellumIntegrationService(client=mock_client)
117
133
 
118
- # AND the API should have been called with correct parameters
119
- mock_client.integrations.execute_integration_tool.assert_called_once_with(
134
+ # THEN it should raise a NodeException with appropriate error message
135
+ with pytest.raises(NodeException) as exc_info:
136
+ service.execute_tool(
120
137
  integration="GITHUB",
121
138
  provider="COMPOSIO",
122
139
  tool_name="GITHUB_CREATE_AN_ISSUE",
123
- arguments={
124
- "repo": "user/repo",
125
- "title": "Test Issue",
126
- "body": "Test body",
127
- },
140
+ arguments={"repo": "user/repo"},
128
141
  )
129
142
 
143
+ assert "Failed to execute tool" in str(exc_info.value)
144
+ assert "Authentication failed" in str(exc_info.value)
130
145
 
131
- def test_vellum_integration_service_execute_tool_api_error():
132
- """Test that execution errors are properly handled"""
133
- with mock.patch(
134
- "vellum.workflows.integrations.vellum_integration_service.create_vellum_client"
135
- ) as mock_create_client:
136
- # GIVEN a mock client that raises an exception during tool execution
137
- mock_client = mock.MagicMock()
138
- mock_create_client.return_value = mock_client
139
-
140
- mock_client.integrations.execute_integration_tool.side_effect = Exception("Authentication failed")
141
-
142
- # WHEN we attempt to execute a tool that encounters an error
143
- service = VellumIntegrationService()
144
146
 
145
- # THEN it should raise a NodeException with appropriate error message
146
- with pytest.raises(NodeException) as exc_info:
147
- service.execute_tool(
148
- integration="GITHUB",
149
- provider="COMPOSIO",
150
- tool_name="GITHUB_CREATE_AN_ISSUE",
151
- arguments={"repo": "user/repo"},
152
- )
153
-
154
- assert "Failed to execute tool" in str(exc_info.value)
155
- assert "Authentication failed" in str(exc_info.value)
156
-
157
-
158
- def test_vellum_integration_service_execute_tool_empty_response():
147
+ def test_vellum_integration_service_execute_tool_empty_response(vellum_client):
159
148
  """Test that empty response data is handled gracefully"""
160
- with mock.patch(
161
- "vellum.workflows.integrations.vellum_integration_service.create_vellum_client"
162
- ) as mock_create_client:
163
- # GIVEN a mock client that returns an empty response
164
- mock_client = mock.MagicMock()
165
- mock_create_client.return_value = mock_client
166
-
167
- mock_response = mock.MagicMock()
168
- mock_response.data = {}
169
-
170
- mock_client.integrations.execute_integration_tool.return_value = mock_response
171
-
172
- # WHEN we execute a tool that returns empty data
173
- service = VellumIntegrationService()
174
- result = service.execute_tool(
175
- integration="SLACK",
176
- provider="COMPOSIO",
177
- tool_name="SLACK_SEND_MESSAGE",
178
- arguments={
179
- "channel": "#general",
180
- "message": "Hello, world!",
181
- },
182
- )
149
+ mock_client = vellum_client
150
+ mock_client.integrations = mock.MagicMock()
183
151
 
184
- # THEN an empty dictionary should be returned without errors
185
- assert result == {}
152
+ mock_response = mock.MagicMock()
153
+ mock_response.data = {}
186
154
 
155
+ mock_client.integrations.execute_integration_tool.return_value = mock_response
187
156
 
188
- def test_vellum_integration_service_multiple_tool_executions():
189
- """Test that the service handles multiple sequential tool executions"""
190
- with mock.patch(
191
- "vellum.workflows.integrations.vellum_integration_service.create_vellum_client"
192
- ) as mock_create_client:
193
- # GIVEN a mock client configured to return different responses for each call
194
- mock_client = mock.MagicMock()
195
- mock_create_client.return_value = mock_client
196
-
197
- responses = [
198
- mock.MagicMock(data={"result": "first"}),
199
- mock.MagicMock(data={"result": "second"}),
200
- ]
201
- mock_client.integrations.execute_integration_tool.side_effect = responses
202
-
203
- # WHEN we execute multiple tools in sequence
204
- service = VellumIntegrationService()
205
-
206
- result1 = service.execute_tool(
207
- integration="GITHUB",
208
- provider="COMPOSIO",
209
- tool_name="TOOL_1",
210
- arguments={"arg": "val1"},
211
- )
157
+ # WHEN we execute a tool that returns empty data
158
+ service = VellumIntegrationService(client=mock_client)
159
+ result = service.execute_tool(
160
+ integration="SLACK",
161
+ provider="COMPOSIO",
162
+ tool_name="SLACK_SEND_MESSAGE",
163
+ arguments={
164
+ "channel": "#general",
165
+ "message": "Hello, world!",
166
+ },
167
+ )
212
168
 
213
- result2 = service.execute_tool(
214
- integration="SLACK",
215
- provider="COMPOSIO",
216
- tool_name="TOOL_2",
217
- arguments={"arg": "val2"},
218
- )
169
+ # THEN an empty dictionary should be returned without errors
170
+ assert result == {}
219
171
 
220
- # THEN each tool execution should return its respective result
221
- assert result1["result"] == "first"
222
- assert result2["result"] == "second"
223
172
 
224
- # AND the API should have been called twice
225
- assert mock_client.integrations.execute_integration_tool.call_count == 2
173
+ def test_vellum_integration_service_multiple_tool_executions(vellum_client):
174
+ """Test that the service handles multiple sequential tool executions"""
175
+ mock_client = vellum_client
176
+ mock_client.integrations = mock.MagicMock()
177
+
178
+ responses = [
179
+ mock.MagicMock(data={"result": "first"}),
180
+ mock.MagicMock(data={"result": "second"}),
181
+ ]
182
+ mock_client.integrations.execute_integration_tool.side_effect = responses
183
+
184
+ # WHEN we execute multiple tools in sequence
185
+ service = VellumIntegrationService(client=mock_client)
186
+
187
+ result1 = service.execute_tool(
188
+ integration="GITHUB",
189
+ provider="COMPOSIO",
190
+ tool_name="TOOL_1",
191
+ arguments={"arg": "val1"},
192
+ )
193
+
194
+ result2 = service.execute_tool(
195
+ integration="SLACK",
196
+ provider="COMPOSIO",
197
+ tool_name="TOOL_2",
198
+ arguments={"arg": "val2"},
199
+ )
200
+
201
+ # THEN each tool execution should return its respective result
202
+ assert result1["result"] == "first"
203
+ assert result2["result"] == "second"
204
+
205
+ # AND the API should have been called twice
206
+ assert mock_client.integrations.execute_integration_tool.call_count == 2
@@ -1,7 +1,9 @@
1
- from typing import Any, Dict
1
+ from typing import Any, Dict, Optional
2
2
 
3
+ from vellum.workflows.constants import VellumIntegrationProviderType
3
4
  from vellum.workflows.errors.types import WorkflowErrorCode
4
5
  from vellum.workflows.exceptions import NodeException
6
+ from vellum.workflows.types.definition import VellumIntegrationToolDetails
5
7
  from vellum.workflows.vellum_client import create_vellum_client
6
8
 
7
9
 
@@ -13,16 +15,16 @@ class VellumIntegrationService:
13
15
  own integration infrastructure.
14
16
  """
15
17
 
16
- def __init__(self) -> None:
18
+ def __init__(self, client: Optional[Any] = None) -> None:
17
19
  """Initialize the VellumIntegrationService with a Vellum client."""
18
- self._client = create_vellum_client()
20
+ self._client = client or create_vellum_client()
19
21
 
20
22
  def get_tool_definition(
21
23
  self,
22
24
  integration: str,
23
25
  provider: str,
24
26
  tool_name: str,
25
- ) -> Dict[str, Any]:
27
+ ) -> VellumIntegrationToolDetails:
26
28
  """Retrieve a tool definition from Vellum integrations.
27
29
 
28
30
  Args:
@@ -31,7 +33,7 @@ class VellumIntegrationService:
31
33
  tool_name: The tool's unique name as specified by the provider
32
34
 
33
35
  Returns:
34
- Dict containing the tool definition with name, description, and parameters
36
+ VellumIntegrationToolDetails containing the tool definition with parameters
35
37
 
36
38
  Raises:
37
39
  NodeException: If the tool definition cannot be retrieved
@@ -43,13 +45,13 @@ class VellumIntegrationService:
43
45
  tool_name=tool_name,
44
46
  )
45
47
 
46
- # Convert the response to a dict format matching what's expected
47
- return {
48
- "name": response.name,
49
- "description": response.description,
50
- "parameters": response.parameters,
51
- "provider": response.provider,
52
- }
48
+ return VellumIntegrationToolDetails(
49
+ provider=VellumIntegrationProviderType(response.provider),
50
+ integration=integration,
51
+ name=response.name,
52
+ description=response.description,
53
+ parameters=response.parameters,
54
+ )
53
55
  except Exception as e:
54
56
  error_message = f"Failed to retrieve tool definition for {tool_name}: {str(e)}"
55
57
  raise NodeException(
@@ -177,6 +177,17 @@ class VellumIntegrationToolDefinition(UniversalBaseModel):
177
177
  description: str
178
178
 
179
179
 
180
+ class VellumIntegrationToolDetails(VellumIntegrationToolDefinition):
181
+ """Extended version of VellumIntegrationToolDefinition with runtime parameters.
182
+
183
+ This class includes the parameters field which is populated during compilation
184
+ from the Vellum integrations API response. It inherits all fields from the base
185
+ VellumIntegrationToolDefinition class.
186
+ """
187
+
188
+ parameters: Optional[Dict[str, Any]] = None
189
+
190
+
180
191
  class MCPServer(UniversalBaseModel):
181
192
  type: Literal["MCP_SERVER"] = "MCP_SERVER"
182
193
  name: str
@@ -335,13 +335,15 @@ def compile_vellum_integration_tool_definition(tool_def: VellumIntegrationToolDe
335
335
  try:
336
336
  service = VellumIntegrationService()
337
337
  tool_details = service.get_tool_definition(
338
- integration=tool_def.integration, provider=tool_def.provider.value, tool_name=tool_def.name
338
+ integration=tool_def.integration,
339
+ provider=tool_def.provider.value,
340
+ tool_name=tool_def.name,
339
341
  )
340
342
 
341
343
  return FunctionDefinition(
342
344
  name=tool_def.name,
343
- description=tool_details.get("description", tool_def.description),
344
- parameters=tool_details.get("parameters", {}),
345
+ description=tool_details.description,
346
+ parameters=tool_details.parameters or {},
345
347
  )
346
348
  except Exception:
347
349
  # Fallback for service failures
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 1.5.1
3
+ Version: 1.5.3
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0
@@ -22,9 +22,9 @@ vellum_cli/tests/test_ping.py,sha256=b3aQLd-N59_8w2rRiWqwpB1rlHaKEYVbAj1Y3hi7A-g
22
22
  vellum_cli/tests/test_pull.py,sha256=e2XHzcHIx9k-FyuNAl7wMSNsSSebPGyP6U05JGcddFs,49447
23
23
  vellum_cli/tests/test_push.py,sha256=2MjkNKr_9Guv5Exjsm3L1BeVXmPkKUcCSiKnp90HgW4,41996
24
24
  vellum_ee/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- vellum_ee/assets/node-definitions.json,sha256=Sn4fy0oUUCd_mj7vRNvQI5XR88A7-HKbe9pWaVnbz28,24293
25
+ vellum_ee/assets/node-definitions.json,sha256=UDx8gBZ4Vj853aY7CSHR8JipVjZSQiKdkOKwKqwwVKw,25499
26
26
  vellum_ee/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- vellum_ee/scripts/generate_node_definitions.py,sha256=1pVf2EA3LeX4kLKC2hSanyk2ZZDGVZ_lb83TE416XP8,3274
27
+ vellum_ee/scripts/generate_node_definitions.py,sha256=FOYQsXIqU45I0OAcsyZUGODF9JK44yunf58rR6YaAdA,3303
28
28
  vellum_ee/workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
29
  vellum_ee/workflows/display/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
30
  vellum_ee/workflows/display/base.py,sha256=R3f2T8FlZrXn2FawAmpVuLB3fKFWw11mCUulWAyIKA0,1912
@@ -48,7 +48,7 @@ vellum_ee/workflows/display/nodes/vellum/final_output_node.py,sha256=z4oeTgKnMGV
48
48
  vellum_ee/workflows/display/nodes/vellum/guardrail_node.py,sha256=9_AslWjzj4RHH2sq3SIaq9FU0NCg7ex5TIWrNMybqXg,2173
49
49
  vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py,sha256=muyLv3KMIsUnnXhiPbPhw5B0TO1Z8LUwytpVQKlz4tM,11906
50
50
  vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py,sha256=m20_ZZ3Au0ZCpI3TNC9xh54ld1X13CNq-T51VOtP23k,6434
51
- vellum_ee/workflows/display/nodes/vellum/map_node.py,sha256=kwLqptup7bzYUDkGDbpcJPMMusMezsYrG5rSUYl5TlQ,3750
51
+ vellum_ee/workflows/display/nodes/vellum/map_node.py,sha256=AW5JuHXtmtcJKeRiZKd7iB1re_D7G7jl_OlaZs8nUl0,4219
52
52
  vellum_ee/workflows/display/nodes/vellum/merge_node.py,sha256=xMHaPfTSZWYprQenlHm2g47u0a5O9Me_dhAjfqo8nKQ,3116
53
53
  vellum_ee/workflows/display/nodes/vellum/note_node.py,sha256=6PcAFA_EJn7vEMdqgoRjYTLHwnXCrJv80B10zuUx4jE,1026
54
54
  vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py,sha256=uo4YZRV48iX4peGAA1xkGniSPrepywvW_gS7codt-VQ,3378
@@ -153,12 +153,12 @@ vellum_ee/workflows/tests/test_registry.py,sha256=B8xRIuEyLWfSqrYoPldNQXhKPfe50P
153
153
  vellum_ee/workflows/tests/test_serialize_module.py,sha256=d4ZpMd3oIxiq-sBXeSQESS6ix6-1P6rdCRFqBEReJIU,2882
154
154
  vellum_ee/workflows/tests/test_server.py,sha256=dXFBraU99Y6cKp2aBhLFXQTScSRcE9WaWjo1z9piqdU,23344
155
155
  vellum_ee/workflows/tests/test_virtual_files.py,sha256=TJEcMR0v2S8CkloXNmCHA0QW0K6pYNGaIjraJz7sFvY,2762
156
- vellum/__init__.py,sha256=QWxRjUIOceGP7ARsXZVhWrwJDrbtyoZmXeAtJ8uud5A,47952
156
+ vellum/__init__.py,sha256=eR-V_gunexfXJhjtd2ayuyvACUUcNgGRf1lTGPJlp3w,48062
157
157
  vellum/client/README.md,sha256=flqu57ubZNTfpq60CdLtJC9gp4WEkyjb_n_eZ4OYf9w,6497
158
158
  vellum/client/__init__.py,sha256=-dZaD_0KtlkpQ-pULNNWcarC5xXlGMcGc2nBKLIyRlA,73661
159
159
  vellum/client/core/__init__.py,sha256=lTcqUPXcx4112yLDd70RAPeqq6tu3eFMe1pKOqkW9JQ,1562
160
160
  vellum/client/core/api_error.py,sha256=44vPoTyWN59gonCIZMdzw7M1uspygiLnr3GNFOoVL2Q,614
161
- vellum/client/core/client_wrapper.py,sha256=HGgXu4osF39E2IYXXZKqZ_UBngm-WseBYRAmezfoveA,2840
161
+ vellum/client/core/client_wrapper.py,sha256=bnEtzZoUPqygbLirwbvuRYuZY_jk14h67pGBxT4CwNs,2840
162
162
  vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
163
163
  vellum/client/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
164
164
  vellum/client/core/force_multipart.py,sha256=awxh5MtcRYe74ehY8U76jzv6fYM_w_D3Rur7KQQzSDk,429
@@ -179,7 +179,7 @@ vellum/client/errors/not_found_error.py,sha256=YrqVM0oc3qkQbFbmmm6xr300VGfUNxMSy
179
179
  vellum/client/errors/too_many_requests_error.py,sha256=SJJemdgUlQHV_VpxK8UfFNexgZebNT5_MTOeQs6oVgc,397
180
180
  vellum/client/errors/unauthorized_error.py,sha256=waPl5Swiqsk3FQK-Lljzx4KDh4RPZ0wL6BLHjM8onQ8,394
181
181
  vellum/client/raw_client.py,sha256=cmMR0t87iUYvkIE9L4g0dcCmw3uUQNze9rD9CBv5rzs,113481
182
- vellum/client/reference.md,sha256=Cmp2G_L5Xrw2y_R6NzOhJj4w8e1qdkM8bhHURgkY9yo,98843
182
+ vellum/client/reference.md,sha256=i1hKF-inDAc3CqodGJM0FdkgR10zO4nhHJDLdGjjkw4,99052
183
183
  vellum/client/resources/__init__.py,sha256=AlEiBj5gJLcaAJhAa-X1vtES-uujc6c83p6_C55U6FE,1647
184
184
  vellum/client/resources/ad_hoc/__init__.py,sha256=_VhToAyIt_5axN6CLJwtxg3-CO7THa_23pbUzqhXJa4,85
185
185
  vellum/client/resources/ad_hoc/client.py,sha256=v5I_YzJaaPezsE4KVuMSUXJISstKuJ_9-VUeXakIJhw,14353
@@ -194,8 +194,8 @@ vellum/client/resources/deployments/types/__init__.py,sha256=IjycypLdKnmutjjli7a
194
194
  vellum/client/resources/deployments/types/deployments_list_request_status.py,sha256=CxlQD16KZXme7x31YYCe_3aAgEueutDTeJo5A4Au-aU,174
195
195
  vellum/client/resources/deployments/types/list_deployment_release_tags_request_source.py,sha256=hRGgWMYZL9uKCmD_2dU8-u9RCPUUGItpNn1tUY-NXKY,180
196
196
  vellum/client/resources/document_indexes/__init__.py,sha256=cCCSLBe93_1w6-u6Q-IYM0XXS57PW9Xw14myKqdcaqc,185
197
- vellum/client/resources/document_indexes/client.py,sha256=cMJo6xEPnHW7-rX-3vOb4-jupdH_M3u9oA6uuxaTIO8,24213
198
- vellum/client/resources/document_indexes/raw_client.py,sha256=HOBjCtuP1slPMIShqkDv0uoDl2bbu7CQrGG3paLDFN4,32063
197
+ vellum/client/resources/document_indexes/client.py,sha256=pH9slCzMzC-x403hRwQQwcJB0spFFXBv3Hp7rwlIUK0,24791
198
+ vellum/client/resources/document_indexes/raw_client.py,sha256=jD717kJH4j5kdXx9rOp37uyjGAV5FiBBARYHdoWua-s,32679
199
199
  vellum/client/resources/document_indexes/types/__init__.py,sha256=HaAObnALQo1B9vq9-6NxBcr5z-IRjqaPojE2Q6thkPM,216
200
200
  vellum/client/resources/document_indexes/types/document_indexes_list_request_status.py,sha256=sfUEB0cvOSmlE2iITqnMVyHv05Zy2fWP4QjCIYqMg0M,178
201
201
  vellum/client/resources/documents/__init__.py,sha256=_VhToAyIt_5axN6CLJwtxg3-CO7THa_23pbUzqhXJa4,85
@@ -234,8 +234,8 @@ vellum/client/resources/test_suites/__init__.py,sha256=_VhToAyIt_5axN6CLJwtxg3-C
234
234
  vellum/client/resources/test_suites/client.py,sha256=xo197bXk84jj6gEieRmJuhqBbQ8IB-VMNLki7gdqhlo,20753
235
235
  vellum/client/resources/test_suites/raw_client.py,sha256=XfDqmJa7fngPsHAirTSSNBMHy2O4mKOaNS16IL567L8,22335
236
236
  vellum/client/resources/workflow_deployments/__init__.py,sha256=MVnGG7CkZA7F8p__MGerey22DTg6oYqfay77mdlDjBc,271
237
- vellum/client/resources/workflow_deployments/client.py,sha256=OjISxlNMMw241kmQN5uD3Cp9cOtQYJgbGh_yABG9J4o,27114
238
- vellum/client/resources/workflow_deployments/raw_client.py,sha256=ypDXg7CzASIiTsThqJZhTmgpKuDQERgNJenFPWAnugU,37281
237
+ vellum/client/resources/workflow_deployments/client.py,sha256=AolU-CJ7gKKTkVekNp9qZM5EyQQlsQyDtwJplwHIHLs,27328
238
+ vellum/client/resources/workflow_deployments/raw_client.py,sha256=LvOUJmHV7EVk734DQGH65XbTtIPGLFzWzaOaXLHU7Ss,37533
239
239
  vellum/client/resources/workflow_deployments/types/__init__.py,sha256=2Lrjd-cX_h9gZEgxsF7e9nhCWUcTNXQyEaOjytC1NEM,360
240
240
  vellum/client/resources/workflow_deployments/types/list_workflow_release_tags_request_source.py,sha256=LPETHLX9Ygha_JRT9oWZAZR6clv-W1tTelXzktkTBX8,178
241
241
  vellum/client/resources/workflow_deployments/types/workflow_deployments_list_request_status.py,sha256=FXVkVmGM6DZ2RpTGnZXWJYiVlLQ-K5fDtX3WMaBPaWk,182
@@ -258,7 +258,7 @@ vellum/client/resources/workspaces/client.py,sha256=36KYa2FDu6h65q2GscUFOJs4qKei
258
258
  vellum/client/resources/workspaces/raw_client.py,sha256=M3Ewk1ZfEZ44EeTvBtBNoNKi5whwfLY-1GR07SyfDTI,3517
259
259
  vellum/client/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
260
260
  vellum/client/tests/test_utils.py,sha256=zk8z45-2xrm9sZ2hq8PTqY8MXmXtPqMqYK0VBBX0GHg,1176
261
- vellum/client/types/__init__.py,sha256=n4NG8ONAsDGYTCAfh1BtPvO7DGKyov_L_fMKkGPshqA,72678
261
+ vellum/client/types/__init__.py,sha256=KhRC4aJBoLP3SMWUNlbLiqmpCB8Wh_5AUPhGXZRQi7c,72850
262
262
  vellum/client/types/ad_hoc_execute_prompt_event.py,sha256=B69EesIH6fpNsdoiJaSG9zF1Sl17FnjoTu4CBkUSoHk,608
263
263
  vellum/client/types/ad_hoc_expand_meta.py,sha256=Kajcj3dKKed5e7uZibRnE3ZonK_bB2JPM-3aLjLfUp4,1295
264
264
  vellum/client/types/ad_hoc_fulfilled_prompt_execution_meta.py,sha256=5kD6ZcbU8P8ynK0lMD8Mh7vHzvQt06ziMyphvWYg6FU,968
@@ -463,8 +463,8 @@ vellum/client/types/image_input_request.py,sha256=8WEE7LaFJ0M8ncxmts6yKTNAwGT-C1
463
463
  vellum/client/types/image_prompt_block.py,sha256=5VUNnsbmvK3RkWFq5PFq6_SleHR4XyHYFzKWBgpmwJ0,972
464
464
  vellum/client/types/image_vellum_value.py,sha256=aYtApnz5PeTYia0Mwmxi3LQ2F6KAoy3vDYzovzaEqzs,712
465
465
  vellum/client/types/image_vellum_value_request.py,sha256=1y5MyppljIcx748SLcC6N84RPNS2nGPdueuLZNrekxk,741
466
- vellum/client/types/indexing_config_vectorizer.py,sha256=nTHf22XEYxZpjzZg29IR2ow4r6zpgJqW1UiY6Ht-T8U,1827
467
- vellum/client/types/indexing_config_vectorizer_request.py,sha256=-ofzJtUpBZ1uykyE_io1wXtMwQdmVbDXJ0EfyD21S3s,2076
466
+ vellum/client/types/indexing_config_vectorizer.py,sha256=rK0JnE9lCCXiB71wkT5FCyky-_WYkgNyL0VrFM5UImg,1900
467
+ vellum/client/types/indexing_config_vectorizer_request.py,sha256=KGaJ4Z74RdjU27o4zIK_Hp32LE82-nFy1V-Tu_2UW8U,2171
468
468
  vellum/client/types/indexing_state_enum.py,sha256=KWYMz5DwJnVhu3ZlSDdqiC5MtiTIdrxE4EvwFYiel1U,213
469
469
  vellum/client/types/initiated_ad_hoc_execute_prompt_event.py,sha256=S2pwVWNs0sJKNfCLPd3N0xlYw1Tl67Js1waB5hSML5E,879
470
470
  vellum/client/types/initiated_execute_prompt_event.py,sha256=yrNgIGqJEfe2cxoE-3zIOFa6j976Qo2Hcbm-vU6wogs,857
@@ -601,6 +601,8 @@ vellum/client/types/pdf_search_result_meta_source.py,sha256=KaYx-xvNtOn_ADRDBbb4
601
601
  vellum/client/types/pdf_search_result_meta_source_request.py,sha256=Fh2EUxWyhdP7yW2CUNvSTSZo8EcukgogALr4HpppHvQ,1097
602
602
  vellum/client/types/plain_text_prompt_block.py,sha256=vqZESoqj6P1IyHFmRAk2kmdU3ktsM_852crRCBcYV64,894
603
603
  vellum/client/types/price.py,sha256=f-j-74UUDuX2c-IQxXH78KV8L-jLi6sdsHWVLRKqBy4,574
604
+ vellum/client/types/private_vectorizer.py,sha256=byAlExo-LWDBOMXrgMalUiV-IgWf1yk1LN9MmJ22p4o,642
605
+ vellum/client/types/private_vectorizer_request.py,sha256=ToGDgT3V_wsr75vpTYFVrhnrHcbzBe03QkadvWL7REg,649
604
606
  vellum/client/types/processing_failure_reason_enum.py,sha256=cQ3Rmryo7U0Lkh-XZzWIDI9Re-oVh1GZb2cDgMR5sL8,224
605
607
  vellum/client/types/prompt_block.py,sha256=950JeKeNKZ0DQXwCD-Sy9SDMtiR7F-BqCrJZoxZt7JM,886
606
608
  vellum/client/types/prompt_block_state.py,sha256=BRAzTYARoSU36IVZGWMeeqhl5fgFMXCyhJ8rCbfB-f0,163
@@ -815,7 +817,7 @@ vellum/client/types/vellum_code_resource_definition.py,sha256=XdueTR342BDjevZ3kt
815
817
  vellum/client/types/vellum_document.py,sha256=qwXqMS2Eud2a5KmF8QHhU_vJzDX0g5cesrCpmBqREsA,604
816
818
  vellum/client/types/vellum_document_request.py,sha256=P9vA7ZDNeaHNlMqyzfl-ZD4bpdf-xA5mH8R1QuOAmOY,611
817
819
  vellum/client/types/vellum_error.py,sha256=G4WSD-w_skoDDnsAt-TtImt-hZT-Sc8LjHvERBUVnhE,691
818
- vellum/client/types/vellum_error_code_enum.py,sha256=_Z1p2ExKwGLmNU5Hq-8MZ328LStQWbevipjYkBF-GSU,402
820
+ vellum/client/types/vellum_error_code_enum.py,sha256=kaqf7PNViS1cELE571Ql2-Xueh058MPzq_jvqLiMH48,404
819
821
  vellum/client/types/vellum_error_request.py,sha256=7l4Ux6wj3C9BdSXUPBrtxECsAirmvaLU42Y23VqncBU,698
820
822
  vellum/client/types/vellum_image.py,sha256=LAGUYBDsT0bmMOqgbaeCTCy2w4zAeHEyUIgPtmdjjJ4,601
821
823
  vellum/client/types/vellum_image_request.py,sha256=6DoI2AdJIG8NShHSslpHvsFUw5PwIMconjlHSipOP5Q,608
@@ -1396,6 +1398,8 @@ vellum/types/pdf_search_result_meta_source.py,sha256=tkM53z99Zky8ifkcfj1HoS7k-sc
1396
1398
  vellum/types/pdf_search_result_meta_source_request.py,sha256=TW9FWTdqZi-SuERKkjMdrKBgQEq3RA4W9nwefm8it6k,175
1397
1399
  vellum/types/plain_text_prompt_block.py,sha256=K5tGXMDCVTLDIDOL17TjLvZD6pMaHnRtcSYfXOrzQMM,161
1398
1400
  vellum/types/price.py,sha256=TTMB0kw-FD2OtTVWMPPB12zay8ncWtnAq48mg1Bwmz0,143
1401
+ vellum/types/private_vectorizer.py,sha256=MjfxUfZCwY-Yt7ksER7w4RfVqtIToJK080U5iq-o-b4,156
1402
+ vellum/types/private_vectorizer_request.py,sha256=sy498k6SmUSPGgaDfrQgb5NN-ebxE68MeGODv7DNXLA,164
1399
1403
  vellum/types/processing_failure_reason_enum.py,sha256=Pz9H8oNn8H6lLLVuLWsuRYzOiQkVXRAW_KeT3mPd5z8,168
1400
1404
  vellum/types/prompt_block.py,sha256=WU91uuWAvel_8EFjoBSJodOZdAVlZAFwQYCrT4Mt-dE,150
1401
1405
  vellum/types/prompt_block_state.py,sha256=tKqNrZnHWjvfGS_6oIUTpdCPGxvRJa31Le6qWL_3198,156
@@ -1824,8 +1828,8 @@ vellum/workflows/integrations/composio_service.py,sha256=rSliaZtNiBcDSvDxz9k5i1K
1824
1828
  vellum/workflows/integrations/mcp_service.py,sha256=9DYb8dg2_kgc1UOu830kxhaFlt9yTbhKPhK3L6kb1t4,9831
1825
1829
  vellum/workflows/integrations/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1826
1830
  vellum/workflows/integrations/tests/test_mcp_service.py,sha256=q_DYrDkIqI4sQBNgID4YdbM4e9tneLVWY8YmI4R26d8,8859
1827
- vellum/workflows/integrations/tests/test_vellum_integration_service.py,sha256=5Cw9fqw2DfIlD1h9xjso2WdocyhELVG8RMpMttUiqQ4,8903
1828
- vellum/workflows/integrations/vellum_integration_service.py,sha256=0pD__eFjhKpmkF110tW2L6btr9CCUOKHMo5mBU7Ykrs,3405
1831
+ vellum/workflows/integrations/tests/test_vellum_integration_service.py,sha256=qGDV1Tx3cWoaazjfnkv8MutLYscwvSZazRqtnz3EPhY,7607
1832
+ vellum/workflows/integrations/vellum_integration_service.py,sha256=AzF2QkEcLspTV5rySA2GToirNpMmTiY07OZx-6Vq3IA,3625
1829
1833
  vellum/workflows/logging.py,sha256=_a217XogktV4Ncz6xKFz7WfYmZAzkfVRVuC0rWob8ls,437
1830
1834
  vellum/workflows/nodes/__init__.py,sha256=zymtc3_iW2rFmMR-sayTLuN6ZsAw8VnJweWPsjQk2-Q,1197
1831
1835
  vellum/workflows/nodes/bases/__init__.py,sha256=cniHuz_RXdJ4TQgD8CBzoiKDiPxg62ErdVpCbWICX64,58
@@ -1985,7 +1989,7 @@ vellum/workflows/tests/test_undefined.py,sha256=zMCVliCXVNLrlC6hEGyOWDnQADJ2g83y
1985
1989
  vellum/workflows/types/__init__.py,sha256=KxUTMBGzuRCfiMqzzsykOeVvrrkaZmTTo1a7SLu8gRM,68
1986
1990
  vellum/workflows/types/code_execution_node_wrappers.py,sha256=fewX9bqF_4TZuK-gZYIn12s31-k03vHMGRpvFAPm11Y,3206
1987
1991
  vellum/workflows/types/core.py,sha256=yKm3sE02ult969q80DTmawiwYqodVjcAW-zlaUIgIv4,1495
1988
- vellum/workflows/types/definition.py,sha256=rVoiXhj7xcQS793qjt2gdv64ywfQrRvujURjIWeC6gA,7240
1992
+ vellum/workflows/types/definition.py,sha256=_wzpa0CtS60IIEPfhrLXmj2y9datz5XqJZhLYpml-NI,7663
1989
1993
  vellum/workflows/types/generics.py,sha256=8jptbEx1fnJV0Lhj0MpCJOT6yNiEWeTOYOwrEAb5CRU,1576
1990
1994
  vellum/workflows/types/stack.py,sha256=h7NE0vXR7l9DevFBIzIAk1Zh59K-kECQtDTKOUunwMY,1314
1991
1995
  vellum/workflows/types/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1993,7 +1997,7 @@ vellum/workflows/types/tests/test_definition.py,sha256=rvDYjdJ1rvAv0qHBN7i7s-_WA
1993
1997
  vellum/workflows/types/tests/test_utils.py,sha256=UnZog59tR577mVwqZRqqWn2fScoOU1H6up0EzS8zYhw,2536
1994
1998
  vellum/workflows/types/utils.py,sha256=mTctHITBybpt4855x32oCKALBEcMNLn-9cCmfEKgJHQ,6498
1995
1999
  vellum/workflows/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1996
- vellum/workflows/utils/functions.py,sha256=9KqkCOpuTEncjAxGHfcMGIsrD8-yFQp8NgzvU3w5Rd8,13066
2000
+ vellum/workflows/utils/functions.py,sha256=_esuDTYKEORjBoC0YGT3ANO--OswaKu6s-_42_kzlwU,13057
1997
2001
  vellum/workflows/utils/hmac.py,sha256=JJCczc6pyV6DuE1Oa0QVfYPUN_of3zEYmGFib3OZnrE,1135
1998
2002
  vellum/workflows/utils/names.py,sha256=QtHquoaGqRseu5gg2OcVGI2d_CMcEOvjb9KspwH4C-A,552
1999
2003
  vellum/workflows/utils/pydantic_schema.py,sha256=eR_bBtY-T0pttJP-ARwagSdCOnwPUtiT3cegm2lzDTQ,1310
@@ -2012,8 +2016,8 @@ vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnad
2012
2016
  vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2013
2017
  vellum/workflows/workflows/tests/test_base_workflow.py,sha256=Boa-_m9ii2Qsa1RvVM-VYniF7zCpzGgEGy-OnPZkrHg,23941
2014
2018
  vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
2015
- vellum_ai-1.5.1.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
2016
- vellum_ai-1.5.1.dist-info/METADATA,sha256=Ptz4NIBFWJ5foDFhe-2vq_L8oNt9HKbtTxgf0qN_Ei4,5547
2017
- vellum_ai-1.5.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
2018
- vellum_ai-1.5.1.dist-info/entry_points.txt,sha256=xVavzAKN4iF_NbmhWOlOkHluka0YLkbN_pFQ9pW3gLI,117
2019
- vellum_ai-1.5.1.dist-info/RECORD,,
2019
+ vellum_ai-1.5.3.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
2020
+ vellum_ai-1.5.3.dist-info/METADATA,sha256=TAWtp2asXx1CHMu82sElBaUAF2B9fF8IMK5dZvohhCQ,5547
2021
+ vellum_ai-1.5.3.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
2022
+ vellum_ai-1.5.3.dist-info/entry_points.txt,sha256=xVavzAKN4iF_NbmhWOlOkHluka0YLkbN_pFQ9pW3gLI,117
2023
+ vellum_ai-1.5.3.dist-info/RECORD,,
@@ -407,6 +407,51 @@
407
407
  }
408
408
  ]
409
409
  },
410
+ {
411
+ "id": "527a10bc-30b2-4e36-91d6-91c8e865bac8",
412
+ "display_data": {
413
+ "position": {
414
+ "x": 0.0,
415
+ "y": 0.0
416
+ },
417
+ "comment": {
418
+ "value": "\n Used to map over a list of items and execute a Subworkflow on each iteration.\n\n items: List[MapNodeItemType] - The items to map over\n max_concurrency: Optional[int] = None - The maximum number of concurrent subworkflow executions\n subworkflow: Type[\"BaseWorkflow\"] - The Subworkflow to execute\n ",
419
+ "expanded": true
420
+ }
421
+ },
422
+ "base": {
423
+ "name": "BaseAdornmentNode",
424
+ "module": [
425
+ "vellum",
426
+ "workflows",
427
+ "nodes",
428
+ "bases",
429
+ "base_adornment_node"
430
+ ]
431
+ },
432
+ "definition": {
433
+ "name": "MapNode",
434
+ "module": [
435
+ "vellum",
436
+ "workflows",
437
+ "nodes",
438
+ "core",
439
+ "map_node",
440
+ "node"
441
+ ]
442
+ },
443
+ "trigger": {
444
+ "id": "3a702aac-7b68-47d3-92e1-264883e9532c",
445
+ "merge_behavior": "AWAIT_ATTRIBUTES"
446
+ },
447
+ "ports": [
448
+ {
449
+ "id": "0ae85239-a159-48af-b39c-2484eac901df",
450
+ "name": "default",
451
+ "type": "DEFAULT"
452
+ }
453
+ ]
454
+ },
410
455
  {
411
456
  "id": "7426f273-a43d-4448-a2d2-76d0ee0d069c",
412
457
  "display_data": {
@@ -809,25 +854,21 @@
809
854
  }
810
855
  ],
811
856
  "errors": [
812
- {
813
- "node": "MapNode",
814
- "error": "Expected NodeReference items to have an instance"
815
- },
816
857
  {
817
858
  "node": "SubworkflowDeploymentNode",
818
- "error": "headers: {'server': 'gunicorn', 'date': 'Tue, 23 Sep 2025 21:40:16 GMT', 'content-type': 'application/json', 'allow': 'GET, PUT, PATCH, DELETE, HEAD, OPTIONS', 'x-frame-options': 'DENY', 'content-length': '58', 'vary': 'Accept-Language, Origin', 'content-language': 'en', 'strict-transport-security': 'max-age=60; includeSubDomains; preload', 'x-content-type-options': 'nosniff', 'referrer-policy': 'same-origin', 'cross-origin-opener-policy': 'same-origin', 'via': '1.1 google', 'alt-svc': 'h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000'}, status_code: 403, body: {'detail': 'Authentication credentials were not provided.'}"
859
+ "error": "ApiError: headers: {'server': 'gunicorn', 'date': 'Wed, 24 Sep 2025 04:58:53 GMT', 'content-type': 'application/json', 'allow': 'GET, PUT, PATCH, DELETE, HEAD, OPTIONS', 'x-frame-options': 'DENY', 'content-length': '58', 'vary': 'Accept-Language, Origin', 'content-language': 'en', 'strict-transport-security': 'max-age=60; includeSubDomains; preload', 'x-content-type-options': 'nosniff', 'referrer-policy': 'same-origin', 'cross-origin-opener-policy': 'same-origin', 'via': '1.1 google', 'alt-svc': 'h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000'}, status_code: 403, body: {'detail': 'Authentication credentials were not provided.'}"
819
860
  },
820
861
  {
821
862
  "node": "PromptDeploymentNode",
822
- "error": "headers: {'server': 'gunicorn', 'date': 'Tue, 23 Sep 2025 21:40:16 GMT', 'content-type': 'application/json', 'allow': 'GET, PUT, PATCH, DELETE, HEAD, OPTIONS', 'x-frame-options': 'DENY', 'content-length': '58', 'vary': 'Accept-Language, Origin', 'content-language': 'en', 'strict-transport-security': 'max-age=60; includeSubDomains; preload', 'x-content-type-options': 'nosniff', 'referrer-policy': 'same-origin', 'cross-origin-opener-policy': 'same-origin', 'via': '1.1 google', 'alt-svc': 'h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000'}, status_code: 403, body: {'detail': 'Authentication credentials were not provided.'}"
863
+ "error": "ApiError: headers: {'server': 'gunicorn', 'date': 'Wed, 24 Sep 2025 04:58:53 GMT', 'content-type': 'application/json', 'allow': 'GET, PUT, PATCH, DELETE, HEAD, OPTIONS', 'x-frame-options': 'DENY', 'content-length': '58', 'vary': 'Accept-Language, Origin', 'content-language': 'en', 'strict-transport-security': 'max-age=60; includeSubDomains; preload', 'x-content-type-options': 'nosniff', 'referrer-policy': 'same-origin', 'cross-origin-opener-policy': 'same-origin', 'via': '1.1 google', 'alt-svc': 'h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000'}, status_code: 403, body: {'detail': 'Authentication credentials were not provided.'}"
823
864
  },
824
865
  {
825
866
  "node": "SearchNode",
826
- "error": "Expected NodeReference query to have an instance"
867
+ "error": "ValueError: Expected NodeReference query to have an instance"
827
868
  },
828
869
  {
829
870
  "node": "TemplatingNode",
830
- "error": "TemplatingNode.Outputs.result"
871
+ "error": "KeyError: TemplatingNode.Outputs.result"
831
872
  }
832
873
  ]
833
874
  }
@@ -70,7 +70,7 @@ def main() -> None:
70
70
  display_instance = display_class()
71
71
  display_instance.serialize(display_context)
72
72
  except Exception as e:
73
- errors.append({"node": node_class.__name__, "error": str(e)})
73
+ errors.append({"node": node_class.__name__, "error": f"{e.__class__.__name__}: {str(e)}"})
74
74
 
75
75
  result = {"nodes": successful_nodes, "errors": errors}
76
76
 
@@ -1,7 +1,8 @@
1
1
  from uuid import UUID
2
- from typing import Generic, Optional, TypeVar, cast
2
+ from typing import Generic, Optional, Type, TypeVar, cast
3
3
 
4
4
  from vellum.workflows.nodes import MapNode
5
+ from vellum.workflows.state.base import BaseState
5
6
  from vellum.workflows.types.core import JsonObject
6
7
  from vellum.workflows.workflows.base import BaseWorkflow
7
8
  from vellum_ee.workflows.display.nodes.utils import raise_if_descriptor
@@ -22,12 +23,19 @@ class BaseMapNodeDisplay(BaseAdornmentNodeDisplay[_MapNodeType], Generic[_MapNod
22
23
  node = self._node
23
24
  node_id = self.node_id
24
25
 
25
- subworkflow = cast(type[BaseWorkflow], raise_if_descriptor(node.subworkflow))
26
+ subworkflow_value = raise_if_descriptor(node.subworkflow)
27
+ subworkflow = (
28
+ cast(type[BaseWorkflow], subworkflow_value)
29
+ if subworkflow_value is not None
30
+ else self._default_workflow_class()
31
+ )
32
+
33
+ items = raise_if_descriptor(node.items)
26
34
 
27
35
  items_node_input = create_node_input(
28
36
  node_id=node_id,
29
37
  input_name="items",
30
- value=node.items,
38
+ value=items or [],
31
39
  display_context=display_context,
32
40
  input_id=self.node_input_ids_by_name.get("items"),
33
41
  )
@@ -81,3 +89,9 @@ class BaseMapNodeDisplay(BaseAdornmentNodeDisplay[_MapNodeType], Generic[_MapNod
81
89
  },
82
90
  **self.serialize_generic_fields(display_context),
83
91
  }
92
+
93
+ def _default_workflow_class(self) -> Type[BaseWorkflow]:
94
+ class MapNodeSubworkflow(BaseWorkflow[MapNode.SubworkflowInputs, BaseState]):
95
+ pass
96
+
97
+ return MapNodeSubworkflow