vellum-ai 1.7.11__py3-none-any.whl → 1.7.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of vellum-ai might be problematic. Click here for more details.

Files changed (37) hide show
  1. vellum/__init__.py +2 -0
  2. vellum/client/core/client_wrapper.py +2 -2
  3. vellum/client/types/__init__.py +2 -0
  4. vellum/client/types/auth_type_enum.py +5 -0
  5. vellum/client/types/integration_name.py +4 -0
  6. vellum/client/types/slim_integration_auth_config_read.py +2 -0
  7. vellum/client/types/slim_workflow_execution_read.py +3 -3
  8. vellum/client/types/vellum_error_code_enum.py +1 -0
  9. vellum/client/types/vellum_sdk_error_code_enum.py +1 -0
  10. vellum/client/types/workflow_event_execution_read.py +3 -3
  11. vellum/client/types/workflow_execution_event_error_code.py +1 -0
  12. vellum/client/types/workflow_execution_snapshotted_body.py +1 -0
  13. vellum/types/auth_type_enum.py +3 -0
  14. vellum/workflows/events/workflow.py +18 -2
  15. vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +3 -0
  16. vellum/workflows/nodes/displayable/inline_prompt_node/tests/test_node.py +3 -0
  17. vellum/workflows/nodes/displayable/tool_calling_node/tests/test_node.py +52 -0
  18. vellum/workflows/nodes/displayable/tool_calling_node/utils.py +2 -0
  19. vellum/workflows/references/trigger.py +3 -9
  20. vellum/workflows/runner/runner.py +14 -8
  21. vellum/workflows/tests/triggers/test_vellum_integration_trigger.py +134 -176
  22. vellum/workflows/triggers/__init__.py +1 -2
  23. vellum/workflows/triggers/tests/test_integration.py +2 -2
  24. vellum/workflows/triggers/vellum_integration.py +133 -141
  25. vellum/workflows/types/trigger_exec_config.py +8 -11
  26. vellum/workflows/utils/uuids.py +33 -0
  27. {vellum_ai-1.7.11.dist-info → vellum_ai-1.7.13.dist-info}/METADATA +1 -1
  28. {vellum_ai-1.7.11.dist-info → vellum_ai-1.7.13.dist-info}/RECORD +34 -35
  29. vellum_ee/workflows/display/base.py +1 -3
  30. vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +3 -1
  31. vellum_ee/workflows/display/workflows/base_workflow_display.py +14 -7
  32. vellum/workflows/triggers/slack.py +0 -101
  33. vellum/workflows/triggers/tests/test_slack.py +0 -180
  34. vellum_ee/workflows/display/tests/workflow_serialization/test_slack_trigger_serialization.py +0 -52
  35. {vellum_ai-1.7.11.dist-info → vellum_ai-1.7.13.dist-info}/LICENSE +0 -0
  36. {vellum_ai-1.7.11.dist-info → vellum_ai-1.7.13.dist-info}/WHEEL +0 -0
  37. {vellum_ai-1.7.11.dist-info → vellum_ai-1.7.13.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,4 @@
1
- """Tests for VellumIntegrationTrigger factory pattern and behavior."""
1
+ """Tests for VellumIntegrationTrigger."""
2
2
 
3
3
  import pytest
4
4
 
@@ -7,46 +7,101 @@ from vellum.workflows.references.trigger import TriggerAttributeReference
7
7
  from vellum.workflows.triggers.vellum_integration import VellumIntegrationTrigger
8
8
 
9
9
 
10
- def test_factory_creates_trigger_class() -> None:
11
- """Factory method creates a trigger class with correct attributes."""
12
- SlackNewMessage = VellumIntegrationTrigger.for_trigger(
13
- integration_name="SLACK",
14
- slug="slack_new_message",
15
- trigger_nano_id="test_nano_123",
16
- attributes={"channel": "C123456"},
17
- )
18
-
19
- assert issubclass(SlackNewMessage, VellumIntegrationTrigger)
20
- assert SlackNewMessage.provider == VellumIntegrationProviderType.COMPOSIO
21
- assert SlackNewMessage.integration_name == "SLACK"
22
- assert SlackNewMessage.slug == "slack_new_message"
23
- assert SlackNewMessage.trigger_nano_id == "test_nano_123"
24
- assert SlackNewMessage.attributes == {"channel": "C123456"}
25
-
26
-
27
- def test_factory_caches_trigger_classes() -> None:
28
- """Factory returns the same class instance for identical parameters (ensures deterministic UUIDs)."""
29
- SlackNewMessage1 = VellumIntegrationTrigger.for_trigger(
30
- integration_name="SLACK",
31
- slug="slack_new_message",
32
- trigger_nano_id="test_nano_123",
33
- )
34
- SlackNewMessage2 = VellumIntegrationTrigger.for_trigger(
35
- integration_name="SLACK",
36
- slug="slack_new_message",
37
- trigger_nano_id="test_nano_123",
38
- )
39
-
40
- assert SlackNewMessage1 is SlackNewMessage2
41
-
42
-
43
- def test_populates_dynamic_attributes() -> None:
10
+ def test_requires_config():
11
+ """Trigger classes must declare Config with required fields."""
12
+
13
+ # This should fail - no Config class
14
+ with pytest.raises(TypeError, match="Config"):
15
+
16
+ class BadTrigger1(VellumIntegrationTrigger):
17
+ message: str
18
+ # Missing Config!
19
+
20
+ # This should fail - incomplete Config
21
+ with pytest.raises(TypeError, match="provider"):
22
+
23
+ class BadTrigger2(VellumIntegrationTrigger):
24
+ message: str
25
+
26
+ class Config(VellumIntegrationTrigger.Config):
27
+ integration_name = "SLACK"
28
+ slug = "slack_new_message"
29
+ # Missing provider!
30
+
31
+ # This should work
32
+ class GoodTrigger(VellumIntegrationTrigger):
33
+ message: str
34
+ user: str
35
+
36
+ class Config(VellumIntegrationTrigger.Config):
37
+ provider = VellumIntegrationProviderType.COMPOSIO
38
+ integration_name = "SLACK"
39
+ slug = "slack_new_message"
40
+
41
+ assert hasattr(GoodTrigger, "Config")
42
+
43
+
44
+ def test_top_level_annotations_create_references():
45
+ """Top-level type annotations (webhook event attributes) automatically create TriggerAttributeReference."""
46
+
47
+ class SlackTrigger(VellumIntegrationTrigger):
48
+ message: str
49
+ user: str
50
+ timestamp: float
51
+
52
+ class Config(VellumIntegrationTrigger.Config):
53
+ provider = VellumIntegrationProviderType.COMPOSIO
54
+ integration_name = "SLACK"
55
+ slug = "slack_new_message"
56
+
57
+ # Should auto-create references from annotations
58
+ assert isinstance(SlackTrigger.message, TriggerAttributeReference)
59
+ assert isinstance(SlackTrigger.user, TriggerAttributeReference)
60
+ assert isinstance(SlackTrigger.timestamp, TriggerAttributeReference)
61
+ assert SlackTrigger.message.types == (str,)
62
+ assert SlackTrigger.timestamp.types == (float,)
63
+
64
+ # Undeclared attributes should raise AttributeError
65
+ with pytest.raises(AttributeError):
66
+ _ = SlackTrigger.undefined_attribute
67
+
68
+
69
+ def test_attribute_ids_include_class_name():
70
+ """Attribute IDs should include class name (like nodes)."""
71
+
72
+ class Trigger1(VellumIntegrationTrigger):
73
+ message: str
74
+
75
+ class Config(VellumIntegrationTrigger.Config):
76
+ provider = VellumIntegrationProviderType.COMPOSIO
77
+ integration_name = "SLACK"
78
+ slug = "slack_new_message"
79
+
80
+ class Trigger2(VellumIntegrationTrigger):
81
+ message: str
82
+
83
+ class Config(VellumIntegrationTrigger.Config):
84
+ provider = VellumIntegrationProviderType.COMPOSIO
85
+ integration_name = "SLACK"
86
+ slug = "slack_new_message"
87
+
88
+ # Different class names = different IDs (like nodes)
89
+ # Type ignore: mypy sees message as str, but it's actually TriggerAttributeReference at class level
90
+ assert Trigger1.message.id != Trigger2.message.id # type: ignore[attr-defined]
91
+
92
+
93
+ def test_populates_dynamic_attributes():
44
94
  """Trigger dynamically populates attributes from event_data keys."""
45
- GithubPush = VellumIntegrationTrigger.for_trigger(
46
- integration_name="GITHUB",
47
- slug="github_push_event",
48
- trigger_nano_id="test_nano_456",
49
- )
95
+
96
+ class GithubPushTrigger(VellumIntegrationTrigger):
97
+ repository: str
98
+ branch: str
99
+ commits: list
100
+
101
+ class Config(VellumIntegrationTrigger.Config):
102
+ provider = VellumIntegrationProviderType.COMPOSIO
103
+ integration_name = "GITHUB"
104
+ slug = "github_push_event"
50
105
 
51
106
  event_data = {
52
107
  "repository": "vellum-ai/workflows",
@@ -54,41 +109,27 @@ def test_populates_dynamic_attributes() -> None:
54
109
  "commits": ["abc123", "def456"],
55
110
  }
56
111
 
57
- trigger = GithubPush(event_data=event_data)
112
+ trigger = GithubPushTrigger(event_data=event_data)
58
113
 
59
- assert getattr(trigger, "repository") == "vellum-ai/workflows"
60
- assert getattr(trigger, "branch") == "main"
61
- assert getattr(trigger, "commits") == ["abc123", "def456"]
114
+ assert trigger.repository == "vellum-ai/workflows"
115
+ assert trigger.branch == "main"
116
+ assert trigger.commits == ["abc123", "def456"]
62
117
 
63
118
 
64
- def test_supports_attribute_references() -> None:
65
- """Metaclass creates TriggerAttributeReference dynamically on attribute access."""
66
- SlackNewMessage = VellumIntegrationTrigger.for_trigger(
67
- integration_name="SLACK",
68
- slug="slack_new_message",
69
- trigger_nano_id="test_nano_123",
70
- )
71
-
72
- # Metaclass __getattribute__ creates references for undefined attributes
73
- message_ref = SlackNewMessage.message
74
- channel_ref = SlackNewMessage.channel
119
+ def test_to_trigger_attribute_values():
120
+ """to_trigger_attribute_values returns correct attribute mappings."""
75
121
 
76
- assert isinstance(message_ref, TriggerAttributeReference)
77
- assert isinstance(channel_ref, TriggerAttributeReference)
78
- assert message_ref.name == "message"
79
- assert channel_ref.name == "channel"
122
+ class SlackTrigger(VellumIntegrationTrigger):
123
+ message: str
124
+ channel: str
80
125
 
81
-
82
- def test_to_trigger_attribute_values() -> None:
83
- """to_trigger_attribute_values returns correct attribute mappings."""
84
- SlackNewMessage = VellumIntegrationTrigger.for_trigger(
85
- integration_name="SLACK",
86
- slug="slack_new_message",
87
- trigger_nano_id="test_nano_123",
88
- )
126
+ class Config(VellumIntegrationTrigger.Config):
127
+ provider = VellumIntegrationProviderType.COMPOSIO
128
+ integration_name = "SLACK"
129
+ slug = "slack_new_message"
89
130
 
90
131
  event_data = {"message": "Hello", "channel": "C123"}
91
- trigger = SlackNewMessage(event_data=event_data)
132
+ trigger = SlackTrigger(event_data=event_data)
92
133
 
93
134
  attr_values = trigger.to_trigger_attribute_values()
94
135
 
@@ -98,128 +139,45 @@ def test_to_trigger_attribute_values() -> None:
98
139
  assert set(attr_values.values()) == {"Hello", "C123"}
99
140
 
100
141
 
101
- def test_trigger_attribute_id_stability() -> None:
102
- """Trigger attribute IDs must be stable across factory calls."""
103
- Slack1 = VellumIntegrationTrigger.for_trigger(
104
- integration_name="SLACK",
105
- slug="slack_new_message",
106
- trigger_nano_id="test_nano_123",
107
- )
108
- Slack2 = VellumIntegrationTrigger.for_trigger(
109
- integration_name="SLACK",
110
- slug="slack_new_message",
111
- trigger_nano_id="test_nano_123",
112
- )
113
-
114
- # Factory caching ensures same class
115
- assert Slack1 is Slack2
116
-
117
- # Attribute references must be deterministic across accesses
118
- msg_ref_1 = Slack1.message
119
- msg_ref_2 = Slack2.message
142
+ def test_to_exec_config():
143
+ """to_exec_config() produces valid ComposioIntegrationTriggerExecConfig."""
120
144
 
121
- # Same trigger class + same attribute name = same reference
122
- assert msg_ref_1 == msg_ref_2
145
+ class SlackTrigger(VellumIntegrationTrigger):
146
+ message: str
147
+ user: str
123
148
 
149
+ class Config(VellumIntegrationTrigger.Config):
150
+ provider = VellumIntegrationProviderType.COMPOSIO
151
+ integration_name = "SLACK"
152
+ slug = "slack_new_message"
124
153
 
125
- def test_to_exec_config() -> None:
126
- """to_exec_config() produces valid ComposioIntegrationTriggerExecConfig."""
127
- SlackMessage = VellumIntegrationTrigger.for_trigger(
128
- integration_name="SLACK",
129
- slug="slack_new_message",
130
- trigger_nano_id="abc123def456",
131
- attributes={"channel": "C123456"},
132
- )
154
+ exec_config = SlackTrigger.to_exec_config()
133
155
 
134
- exec_config = SlackMessage.to_exec_config()
135
-
136
- assert exec_config.type == "COMPOSIO_INTEGRATION_TRIGGER"
156
+ assert exec_config.type == "INTEGRATION"
137
157
  assert exec_config.provider == VellumIntegrationProviderType.COMPOSIO
138
158
  assert exec_config.integration_name == "SLACK"
139
159
  assert exec_config.slug == "slack_new_message"
140
- assert exec_config.trigger_nano_id == "abc123def456"
141
- assert exec_config.attributes == {"channel": "C123456"}
160
+ assert exec_config.event_attributes == {"message": str, "user": str}
142
161
 
143
162
 
144
- def test_to_exec_config_base_class_fails() -> None:
163
+ def test_to_exec_config_base_class_fails():
145
164
  """to_exec_config() raises error on base class."""
146
- with pytest.raises(AttributeError, match="factory-generated trigger classes"):
165
+ with pytest.raises(AttributeError):
147
166
  VellumIntegrationTrigger.to_exec_config()
148
167
 
149
168
 
150
- def test_empty_event_data() -> None:
169
+ def test_empty_event_data():
151
170
  """Trigger handles empty event data gracefully."""
152
- SlackMessage = VellumIntegrationTrigger.for_trigger(
153
- integration_name="SLACK",
154
- slug="slack_new_message",
155
- trigger_nano_id="test_nano_123",
156
- )
157
- trigger = SlackMessage(event_data={})
158
171
 
159
- attr_values = trigger.to_trigger_attribute_values()
160
- assert attr_values == {}
172
+ class SlackTrigger(VellumIntegrationTrigger):
173
+ message: str
161
174
 
175
+ class Config(VellumIntegrationTrigger.Config):
176
+ provider = VellumIntegrationProviderType.COMPOSIO
177
+ integration_name = "SLACK"
178
+ slug = "slack_new_message"
162
179
 
163
- def test_attribute_name_does_not_conflict_with_class_variables() -> None:
164
- """Event data attributes don't conflict with class variables."""
165
- SlackMessage = VellumIntegrationTrigger.for_trigger(
166
- integration_name="SLACK",
167
- slug="slack_new_message",
168
- trigger_nano_id="test_nano_123",
169
- )
170
-
171
- # Event data with key that matches a class variable name
172
- event_data = {"provider": "some_value", "message": "Hello"}
173
- trigger = SlackMessage(event_data=event_data)
174
-
175
- # Instance attribute should be set from event_data
176
- assert trigger.provider == "some_value" # Instance attr from event_data
177
- # But class variable should be unchanged
178
- assert SlackMessage.provider == VellumIntegrationProviderType.COMPOSIO
179
-
180
-
181
- def test_non_json_serializable_attributes_fail_fast() -> None:
182
- """Non-JSON-serializable attributes raise ValueError with clear message."""
183
-
184
- # Custom objects are not JSON-serializable
185
- class CustomObject:
186
- pass
187
-
188
- with pytest.raises(ValueError, match="must be JSON-serializable"):
189
- VellumIntegrationTrigger.for_trigger(
190
- integration_name="SLACK",
191
- slug="slack_new_message",
192
- trigger_nano_id="test_nano_123",
193
- attributes={"custom": CustomObject()},
194
- )
195
-
196
- # Sets are not JSON-serializable
197
- with pytest.raises(ValueError, match="must be JSON-serializable"):
198
- VellumIntegrationTrigger.for_trigger(
199
- integration_name="SLACK",
200
- slug="slack_new_message",
201
- trigger_nano_id="test_nano_123",
202
- attributes={"tags": {"a", "b", "c"}},
203
- )
204
-
205
-
206
- def test_nested_json_serializable_attributes_work() -> None:
207
- """Nested JSON-serializable attributes work correctly."""
208
- SlackMessage = VellumIntegrationTrigger.for_trigger(
209
- integration_name="SLACK",
210
- slug="slack_new_message",
211
- trigger_nano_id="test_nano_123",
212
- attributes={
213
- "channel": "C123456",
214
- "filters": {"status": "active", "priority": ["high", "medium"]},
215
- "count": 42,
216
- "enabled": True,
217
- },
218
- )
219
-
220
- assert SlackMessage.attributes == {
221
- "channel": "C123456",
222
- "filters": {"status": "active", "priority": ["high", "medium"]},
223
- "count": 42,
224
- "enabled": True,
225
- }
180
+ trigger = SlackTrigger(event_data={})
181
+
182
+ attr_values = trigger.to_trigger_attribute_values()
183
+ assert attr_values == {}
@@ -1,7 +1,6 @@
1
1
  from vellum.workflows.triggers.base import BaseTrigger
2
2
  from vellum.workflows.triggers.integration import IntegrationTrigger
3
3
  from vellum.workflows.triggers.manual import ManualTrigger
4
- from vellum.workflows.triggers.slack import SlackTrigger
5
4
  from vellum.workflows.triggers.vellum_integration import VellumIntegrationTrigger
6
5
 
7
- __all__ = ["BaseTrigger", "IntegrationTrigger", "ManualTrigger", "SlackTrigger", "VellumIntegrationTrigger"]
6
+ __all__ = ["BaseTrigger", "IntegrationTrigger", "ManualTrigger", "VellumIntegrationTrigger"]
@@ -57,8 +57,8 @@ def test_integration_trigger__attribute_reference():
57
57
  reference = TestTrigger.value
58
58
  assert isinstance(reference, TriggerAttributeReference)
59
59
  assert reference.name == "value"
60
- assert TestTrigger.value is reference
61
- assert reference is TestTrigger.attribute_references()["value"]
60
+ assert TestTrigger.value == reference
61
+ assert reference == TestTrigger.attribute_references()["value"]
62
62
 
63
63
  state = BaseState()
64
64
  trigger = TestTrigger({"value": "data"})