vellum-ai 0.13.11__py3-none-any.whl → 0.13.12__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.
@@ -18,7 +18,7 @@ class BaseClientWrapper:
18
18
  headers: typing.Dict[str, str] = {
19
19
  "X-Fern-Language": "Python",
20
20
  "X-Fern-SDK-Name": "vellum-ai",
21
- "X-Fern-SDK-Version": "0.13.11",
21
+ "X-Fern-SDK-Version": "0.13.12",
22
22
  }
23
23
  headers["X_API_KEY"] = self.api_key
24
24
  return headers
@@ -250,11 +250,10 @@ class BaseNode(Generic[StateType], metaclass=BaseNodeMeta):
250
250
  Determines whether a Node's execution should be initiated. Override this method to define custom
251
251
  trigger criteria.
252
252
  """
253
+ if state.meta.node_execution_cache.is_node_execution_initiated(cls.node_class, node_span_id):
254
+ return False
253
255
 
254
256
  if cls.merge_behavior == MergeBehavior.AWAIT_ATTRIBUTES:
255
- if state.meta.node_execution_cache.is_node_execution_initiated(cls.node_class, node_span_id):
256
- return False
257
-
258
257
  is_ready = True
259
258
  for descriptor in cls.node_class:
260
259
  if not descriptor.instance:
@@ -268,15 +267,9 @@ class BaseNode(Generic[StateType], metaclass=BaseNodeMeta):
268
267
  return is_ready
269
268
 
270
269
  if cls.merge_behavior == MergeBehavior.AWAIT_ANY:
271
- if state.meta.node_execution_cache.is_node_execution_initiated(cls.node_class, node_span_id):
272
- return False
273
-
274
270
  return True
275
271
 
276
272
  if cls.merge_behavior == MergeBehavior.AWAIT_ALL:
277
- if state.meta.node_execution_cache.is_node_execution_initiated(cls.node_class, node_span_id):
278
- return False
279
-
280
273
  """
281
274
  A node utilizing an AWAIT_ALL merge strategy will only be considered ready for the Nth time
282
275
  when all of its dependencies have been executed N times.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 0.13.11
3
+ Version: 0.13.12
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0
@@ -21,7 +21,7 @@ vellum_ee/workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
21
21
  vellum_ee/workflows/display/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  vellum_ee/workflows/display/base.py,sha256=3ZFUYRNKL24fBqXhKpa_Dq2W1a-a86J20dmJYA3H2eY,1755
23
23
  vellum_ee/workflows/display/nodes/__init__.py,sha256=5XOcZJXYUgaLS55QgRJzyQ_W1tpeprjnYAeYVezqoGw,160
24
- vellum_ee/workflows/display/nodes/base_node_display.py,sha256=AnACr-QfL4Hwc3JEN9tUDmr0c8DE9uAjP8w7NyXAfj4,15413
24
+ vellum_ee/workflows/display/nodes/base_node_display.py,sha256=YBXHPwf453j-xaJoeJsoGhnW039WPSmhbQO-G5UGtcY,15787
25
25
  vellum_ee/workflows/display/nodes/base_node_vellum_display.py,sha256=pLO0dORfRu--Ne9NgoyFT_CNjfpr5fGCsgbsMkUF5GM,2845
26
26
  vellum_ee/workflows/display/nodes/get_node_display_class.py,sha256=VpGL-tnMM9wEOkuHNxX74RHAFhz5jcVXvmBkKciOBg0,1367
27
27
  vellum_ee/workflows/display/nodes/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -56,7 +56,7 @@ vellum_ee/workflows/display/tests/workflow_serialization/__init__.py,sha256=47DE
56
56
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
57
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/conftest.py,sha256=EenmEdBtHUFQ0OS-kE7Vboax3JnDdj-K4Qixt5oR0Po,2253
58
58
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py,sha256=pYBubuTzwNczAGFTYhaMCwvMLAcoJfCLkn5PMPbrlMI,7187
59
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py,sha256=9CV44pY33cL_RF9cKmNVwn5hDGEZbPIETavOrvIL3oY,10229
59
+ vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py,sha256=yPXhdZxEDunNl5LL5Obb0jeO34djt7F-GiaTJhp_fmo,16742
60
60
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_outputs_serialization.py,sha256=-12ZkZb3f5gyoNASV2yeQtMo5HmNsVEo8nXwL6IC-I8,6261
61
61
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_ports_serialization.py,sha256=6th6kCwzql6lddjkTQx4Jbvvs4ChqtJwctW-B4QuBhI,37352
62
62
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py,sha256=EbVgg_3_ipTt3MOop4RARX0fmNjwqZtkhIXzx9nGw7Y,4487
@@ -78,7 +78,7 @@ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_ser
78
78
  vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py,sha256=wQ97k-y9rZwKYlZSA6Z9XGUnGRaJ5BvCFu5QnhuEp4A,7404
79
79
  vellum_ee/workflows/display/types.py,sha256=jWTpfQv3baEWjbP12duc3MBz3TK03Ja1UI5458PVQVY,4211
80
80
  vellum_ee/workflows/display/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
- vellum_ee/workflows/display/utils/vellum.py,sha256=0H-c3OaQYZ_sGdI4YmyxEcZ77oWn_Rfts-MLs_QWqls,7289
81
+ vellum_ee/workflows/display/utils/vellum.py,sha256=kETI__jHR1lvO0SoFJgnpAOCK6eWmrSi4SbfZpRUmCA,7448
82
82
  vellum_ee/workflows/display/vellum.py,sha256=8xXRI8b8Tt661H-iZreTQTvLNEKUr4lf-XaKhE7_yUY,8147
83
83
  vellum_ee/workflows/display/workflows/__init__.py,sha256=kapXsC67VJcgSuiBMa86FdePG5A9kMB5Pi4Uy1O2ob4,207
84
84
  vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=x4C621UTH_SZLJYmVBiC1q-D-wadJlTiSGlKAI6CUbA,14082
@@ -112,7 +112,7 @@ vellum/client/README.md,sha256=JkCJjmMZl4jrPj46pkmL9dpK4gSzQQmP5I7z4aME4LY,4749
112
112
  vellum/client/__init__.py,sha256=8nZt88C9SVwWanjLbIQMU3rzb32h5UZfFMBx3VPHB50,111887
113
113
  vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
114
114
  vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
115
- vellum/client/core/client_wrapper.py,sha256=WdGHbGL6B-WAReI6C1XsH60HY57mtWSg-jZ-2xz4eiQ,1869
115
+ vellum/client/core/client_wrapper.py,sha256=0Wk8_I0SGILLte21ZUa6z0zq1xdrRWGhjEhD35ZQoik,1869
116
116
  vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
117
117
  vellum/client/core/file.py,sha256=X9IbmkZmB2bB_DpmZAO3crWdXagOakAyn6UCOCImCPg,2322
118
118
  vellum/client/core/http_client.py,sha256=R0pQpCppnEtxccGvXl4uJ76s7ro_65Fo_erlNNLp_AI,19228
@@ -1306,7 +1306,7 @@ vellum/workflows/inputs/base.py,sha256=1kMgr0WqCYdWUqgFvgSoAMw2067FAlgwhGXLgbIOr
1306
1306
  vellum/workflows/logging.py,sha256=_a217XogktV4Ncz6xKFz7WfYmZAzkfVRVuC0rWob8ls,437
1307
1307
  vellum/workflows/nodes/__init__.py,sha256=aVdQVv7Y3Ro3JlqXGpxwaU2zrI06plDHD2aumH5WUIs,1157
1308
1308
  vellum/workflows/nodes/bases/__init__.py,sha256=cniHuz_RXdJ4TQgD8CBzoiKDiPxg62ErdVpCbWICX64,58
1309
- vellum/workflows/nodes/bases/base.py,sha256=iYn8XmKZKj43vCx_xs5AbnnLgBydmjlElwjb-0xe63I,14459
1309
+ vellum/workflows/nodes/bases/base.py,sha256=qzuf8InU_DZtat-ZsROEHLwmd08pVsYxeoweU5PWQ74,14162
1310
1310
  vellum/workflows/nodes/bases/base_adornment_node.py,sha256=eFTgsPCYb3eyGS0-kw7C6crFnwFx437R5wh9-8bWYts,2905
1311
1311
  vellum/workflows/nodes/bases/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1312
1312
  vellum/workflows/nodes/bases/tests/test_base_node.py,sha256=51CueFVty9XYASC0rKr1cXWejho5WElmhfhp6cCONy0,3811
@@ -1441,8 +1441,8 @@ vellum/workflows/vellum_client.py,sha256=ODrq_TSl-drX2aezXegf7pizpWDVJuTXH-j6528
1441
1441
  vellum/workflows/workflows/__init__.py,sha256=KY45TqvavCCvXIkyCFMEc0dc6jTMOUci93U2DUrlZYc,66
1442
1442
  vellum/workflows/workflows/base.py,sha256=k0kUWWko4fHyCqLSU_1cBK_pXZpl9MXekWiG-bdOAo0,18353
1443
1443
  vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
1444
- vellum_ai-0.13.11.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1445
- vellum_ai-0.13.11.dist-info/METADATA,sha256=NHPCibqYzo79FZeV0pFNsUB0dbOubh76GZRnzEJAc74,5335
1446
- vellum_ai-0.13.11.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1447
- vellum_ai-0.13.11.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1448
- vellum_ai-0.13.11.dist-info/RECORD,,
1444
+ vellum_ai-0.13.12.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1445
+ vellum_ai-0.13.12.dist-info/METADATA,sha256=oExhNf6JV4I0y96hH_M3CazX8AVXv6dM9ryZW6tNo78,5335
1446
+ vellum_ai-0.13.12.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1447
+ vellum_ai-0.13.12.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1448
+ vellum_ai-0.13.12.dist-info/RECORD,,
@@ -31,7 +31,9 @@ from vellum.workflows.nodes.bases.base import BaseNode
31
31
  from vellum.workflows.nodes.utils import get_wrapped_node
32
32
  from vellum.workflows.ports import Port
33
33
  from vellum.workflows.references import OutputReference
34
+ from vellum.workflows.references.constant import ConstantValueReference
34
35
  from vellum.workflows.references.execution_count import ExecutionCountReference
36
+ from vellum.workflows.references.lazy import LazyReference
35
37
  from vellum.workflows.references.vellum_secret import VellumSecretReference
36
38
  from vellum.workflows.references.workflow_input import WorkflowInputReference
37
39
  from vellum.workflows.types.core import JsonArray, JsonObject
@@ -337,6 +339,12 @@ class BaseNodeDisplay(Generic[NodeType], metaclass=BaseNodeDisplayMeta):
337
339
  }
338
340
 
339
341
  def serialize_value(self, display_context: "WorkflowDisplayContext", value: BaseDescriptor) -> JsonObject:
342
+ if isinstance(value, ConstantValueReference):
343
+ return self.serialize_value(display_context, value._value)
344
+
345
+ if isinstance(value, LazyReference):
346
+ return self.serialize_value(display_context, value._get())
347
+
340
348
  if isinstance(value, WorkflowInputReference):
341
349
  workflow_input_display = display_context.global_workflow_input_displays[value]
342
350
  return {
@@ -4,6 +4,8 @@ from deepdiff import DeepDiff
4
4
 
5
5
  from vellum.workflows.inputs.base import BaseInputs
6
6
  from vellum.workflows.nodes.bases.base import BaseNode
7
+ from vellum.workflows.references.constant import ConstantValueReference
8
+ from vellum.workflows.references.lazy import LazyReference
7
9
  from vellum.workflows.references.vellum_secret import VellumSecretReference
8
10
  from vellum_ee.workflows.display.base import WorkflowInputsDisplay
9
11
  from vellum_ee.workflows.display.nodes.base_node_display import BaseNodeDisplay
@@ -19,11 +21,7 @@ class ConstantValueGenericNode(BaseNode):
19
21
 
20
22
 
21
23
  def test_serialize_node__constant_value(serialize_node):
22
- input_id = uuid4()
23
- serialized_node = serialize_node(
24
- node_class=ConstantValueGenericNode,
25
- global_workflow_input_displays={Inputs.input: WorkflowInputsDisplay(id=input_id)},
26
- )
24
+ serialized_node = serialize_node(ConstantValueGenericNode)
27
25
 
28
26
  assert not DeepDiff(
29
27
  {
@@ -67,6 +65,92 @@ def test_serialize_node__constant_value(serialize_node):
67
65
  )
68
66
 
69
67
 
68
+ class ConstantValueReferenceGenericNode(BaseNode):
69
+ attr: str = ConstantValueReference("hello")
70
+
71
+
72
+ def test_serialize_node__constant_value_reference(serialize_node):
73
+ serialized_node = serialize_node(ConstantValueReferenceGenericNode)
74
+
75
+ assert not DeepDiff(
76
+ {
77
+ "id": "9271e2b1-f47e-47a4-95ae-51299dedb62f",
78
+ "label": "ConstantValueReferenceGenericNode",
79
+ "type": "GENERIC",
80
+ "display_data": {"position": {"x": 0.0, "y": 0.0}},
81
+ "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
82
+ "definition": {
83
+ "name": "ConstantValueReferenceGenericNode",
84
+ "module": [
85
+ "vellum_ee",
86
+ "workflows",
87
+ "display",
88
+ "tests",
89
+ "workflow_serialization",
90
+ "generic_nodes",
91
+ "test_attributes_serialization",
92
+ ],
93
+ },
94
+ "trigger": {"id": "8cc0b4c4-4ae4-4248-8fd5-bfb2e658eb51", "merge_behavior": "AWAIT_ATTRIBUTES"},
95
+ "ports": [{"id": "fe696d84-47c2-4325-8020-34a1c586a759", "name": "default", "type": "DEFAULT"}],
96
+ "adornments": None,
97
+ "attributes": [
98
+ {
99
+ "id": "460aeb68-7369-43d2-9d3d-37caa425611f",
100
+ "name": "attr",
101
+ "value": {"type": "CONSTANT_VALUE", "value": {"type": "STRING", "value": "hello"}},
102
+ }
103
+ ],
104
+ "outputs": [],
105
+ },
106
+ serialized_node,
107
+ ignore_order=True,
108
+ )
109
+
110
+
111
+ class LazyReferenceGenericNode(BaseNode):
112
+ attr: str = LazyReference(lambda: ConstantValueReference("hello"))
113
+
114
+
115
+ def test_serialize_node__lazy_reference(serialize_node):
116
+ serialized_node = serialize_node(LazyReferenceGenericNode)
117
+
118
+ assert not DeepDiff(
119
+ {
120
+ "id": "29563b11-bd4d-47b0-b017-372f78aeaef5",
121
+ "label": "LazyReferenceGenericNode",
122
+ "type": "GENERIC",
123
+ "display_data": {"position": {"x": 0.0, "y": 0.0}},
124
+ "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
125
+ "definition": {
126
+ "name": "LazyReferenceGenericNode",
127
+ "module": [
128
+ "vellum_ee",
129
+ "workflows",
130
+ "display",
131
+ "tests",
132
+ "workflow_serialization",
133
+ "generic_nodes",
134
+ "test_attributes_serialization",
135
+ ],
136
+ },
137
+ "trigger": {"id": "56e9791a-078a-4bb7-90bc-a26c3991c70f", "merge_behavior": "AWAIT_ATTRIBUTES"},
138
+ "ports": [{"id": "acb761a0-fcc2-4d21-bc8c-d0d560912c04", "name": "default", "type": "DEFAULT"}],
139
+ "adornments": None,
140
+ "attributes": [
141
+ {
142
+ "id": "4370b381-9165-4fb4-881e-480507abe069",
143
+ "name": "attr",
144
+ "value": {"type": "CONSTANT_VALUE", "value": {"type": "STRING", "value": "hello"}},
145
+ }
146
+ ],
147
+ "outputs": [],
148
+ },
149
+ serialized_node,
150
+ ignore_order=True,
151
+ )
152
+
153
+
70
154
  class WorkflowInputGenericNode(BaseNode):
71
155
  attr: str = Inputs.input
72
156
 
@@ -284,3 +368,100 @@ def test_serialize_node__node_execution(serialize_node):
284
368
  serialized_node,
285
369
  ignore_order=True,
286
370
  )
371
+
372
+
373
+ class CoalesceNodeA(BaseNode):
374
+ class Outputs(BaseNode.Outputs):
375
+ output: str
376
+
377
+
378
+ class CoalesceNodeADisplay(BaseNodeDisplay[CoalesceNodeA]):
379
+ pass
380
+
381
+
382
+ class CoalesceNodeB(BaseNode):
383
+ class Outputs(BaseNode.Outputs):
384
+ output: str
385
+
386
+
387
+ class CoalesceNodeBDisplay(BaseNodeDisplay[CoalesceNodeB]):
388
+ pass
389
+
390
+
391
+ class CoalesceNodeFinal(BaseNode):
392
+ attr = CoalesceNodeA.Outputs.output.coalesce(CoalesceNodeB.Outputs.output)
393
+
394
+
395
+ class CoalesceNodeFinalDisplay(BaseNodeDisplay[CoalesceNodeFinal]):
396
+ pass
397
+
398
+
399
+ def test_serialize_node__coalesce(serialize_node):
400
+ coalesce_node_a_output_id = uuid4()
401
+ coalesce_node_b_output_id = uuid4()
402
+ serialized_node = serialize_node(
403
+ node_class=CoalesceNodeFinal,
404
+ global_node_displays={
405
+ CoalesceNodeA: CoalesceNodeADisplay(),
406
+ CoalesceNodeB: CoalesceNodeBDisplay(),
407
+ CoalesceNodeFinal: CoalesceNodeFinalDisplay(),
408
+ },
409
+ global_node_output_displays={
410
+ CoalesceNodeA.Outputs.output: (
411
+ CoalesceNodeA,
412
+ NodeOutputDisplay(id=coalesce_node_a_output_id, name="output"),
413
+ ),
414
+ CoalesceNodeB.Outputs.output: (
415
+ CoalesceNodeB,
416
+ NodeOutputDisplay(id=coalesce_node_b_output_id, name="output"),
417
+ ),
418
+ },
419
+ )
420
+
421
+ assert not DeepDiff(
422
+ {
423
+ "id": "84d0ce62-afd1-4186-b0e3-5dd8e5ca8b65",
424
+ "label": "CoalesceNodeFinal",
425
+ "type": "GENERIC",
426
+ "display_data": {"position": {"x": 0.0, "y": 0.0}},
427
+ "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
428
+ "definition": {
429
+ "name": "CoalesceNodeFinal",
430
+ "module": [
431
+ "vellum_ee",
432
+ "workflows",
433
+ "display",
434
+ "tests",
435
+ "workflow_serialization",
436
+ "generic_nodes",
437
+ "test_attributes_serialization",
438
+ ],
439
+ },
440
+ "trigger": {"id": "5165f887-153b-4ecd-9219-1beb3cf4f906", "merge_behavior": "AWAIT_ATTRIBUTES"},
441
+ "ports": [{"id": "08ab456d-f541-4400-8305-e97f30cbe745", "name": "default", "type": "DEFAULT"}],
442
+ "adornments": None,
443
+ "attributes": [
444
+ {
445
+ "id": "5a22dd48-9ef3-456b-85b8-7662cf7823eb",
446
+ "name": "attr",
447
+ "value": {
448
+ "type": "BINARY_EXPRESSION",
449
+ "lhs": {
450
+ "type": "NODE_OUTPUT",
451
+ "node_id": "20c340f2-409c-4d31-b44b-eeffd76938d5",
452
+ "node_output_id": str(coalesce_node_a_output_id),
453
+ },
454
+ "operator": "coalesce",
455
+ "rhs": {
456
+ "type": "NODE_OUTPUT",
457
+ "node_id": "9fac3c54-4e75-46ca-a1f2-a80fc6d8ad3f",
458
+ "node_output_id": str(coalesce_node_b_output_id),
459
+ },
460
+ },
461
+ }
462
+ ],
463
+ "outputs": [],
464
+ },
465
+ serialized_node,
466
+ ignore_order=True,
467
+ )
@@ -6,6 +6,7 @@ from vellum.workflows.descriptors.base import BaseDescriptor
6
6
  from vellum.workflows.expressions.and_ import AndExpression
7
7
  from vellum.workflows.expressions.begins_with import BeginsWithExpression
8
8
  from vellum.workflows.expressions.between import BetweenExpression
9
+ from vellum.workflows.expressions.coalesce_expression import CoalesceExpression
9
10
  from vellum.workflows.expressions.contains import ContainsExpression
10
11
  from vellum.workflows.expressions.does_not_begin_with import DoesNotBeginWithExpression
11
12
  from vellum.workflows.expressions.does_not_contain import DoesNotContainExpression
@@ -150,5 +151,7 @@ def convert_descriptor_to_operator(descriptor: BaseDescriptor) -> LogicalOperato
150
151
  return "and"
151
152
  elif isinstance(descriptor, OrExpression):
152
153
  return "or"
154
+ elif isinstance(descriptor, CoalesceExpression):
155
+ return "coalesce"
153
156
  else:
154
157
  raise ValueError(f"Unsupported descriptor type: {descriptor}")