pygeai 0.4.0b3__py3-none-any.whl → 0.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. pygeai/__init__.py +1 -1
  2. pygeai/assistant/rag/models.py +1 -1
  3. pygeai/chat/ui.py +0 -1
  4. pygeai/cli/__init__.py +1 -1
  5. pygeai/cli/commands/chat.py +54 -56
  6. pygeai/cli/commands/lab/ai_lab.py +129 -466
  7. pygeai/cli/commands/lab/options.py +8 -0
  8. pygeai/cli/commands/lab/utils.py +13 -0
  9. pygeai/cli/geai.py +5 -2
  10. pygeai/cli/texts/help.py +12 -0
  11. pygeai/core/base/session.py +1 -1
  12. pygeai/core/common/config.py +0 -2
  13. pygeai/core/common/exceptions.py +6 -0
  14. pygeai/lab/agents/clients.py +30 -61
  15. pygeai/lab/clients.py +20 -0
  16. pygeai/lab/managers.py +6 -58
  17. pygeai/lab/models.py +1 -1
  18. pygeai/lab/processes/clients.py +81 -129
  19. pygeai/lab/processes/mappers.py +2 -2
  20. pygeai/lab/strategies/clients.py +11 -17
  21. pygeai/lab/tools/clients.py +59 -59
  22. pygeai/lab/tools/mappers.py +5 -5
  23. pygeai/tests/cli/docker/__init__.py +0 -0
  24. pygeai/tests/integration/assistants/__init__.py +0 -0
  25. pygeai/tests/integration/assistants/rag/__init__.py +0 -0
  26. pygeai/tests/integration/assistants/rag/test_create_rag.py +91 -0
  27. pygeai/tests/integration/chat/__init__.py +0 -0
  28. pygeai/tests/integration/chat/test_generate_image.py +158 -0
  29. pygeai/tests/integration/lab/agents/test_create_agent.py +21 -19
  30. pygeai/tests/integration/lab/agents/test_create_sharing_link.py +4 -1
  31. pygeai/tests/integration/lab/agents/test_publish_agent_revision.py +0 -1
  32. pygeai/tests/integration/lab/agents/test_update_agent.py +19 -31
  33. pygeai/tests/integration/lab/processes/__init__.py +0 -0
  34. pygeai/tests/integration/lab/processes/test_create_process.py +345 -0
  35. pygeai/tests/integration/lab/processes/test_get_process.py +201 -0
  36. pygeai/tests/integration/lab/processes/test_update_process.py +289 -0
  37. pygeai/tests/integration/lab/reasoning_strategies/__init__.py +0 -0
  38. pygeai/tests/integration/lab/reasoning_strategies/test_get_reasoning_strategy.py +70 -0
  39. pygeai/tests/integration/lab/reasoning_strategies/test_list_reasoning_strategies.py +93 -0
  40. pygeai/tests/integration/lab/reasoning_strategies/test_update_reasoning_strategy.py +149 -0
  41. pygeai/tests/integration/lab/tools/test_create_tool.py +14 -20
  42. pygeai/tests/integration/lab/tools/test_delete_tool.py +3 -3
  43. pygeai/tests/integration/lab/tools/test_get_parameter.py +98 -0
  44. pygeai/tests/integration/lab/tools/test_get_tool.py +3 -3
  45. pygeai/tests/integration/lab/tools/test_list_tools.py +106 -0
  46. pygeai/tests/integration/lab/tools/test_publish_tool_revision.py +119 -0
  47. pygeai/tests/integration/lab/tools/test_set_parameter.py +114 -0
  48. pygeai/tests/integration/lab/tools/test_update_tool.py +267 -0
  49. pygeai/tests/snippets/lab/agentic_flow_example_4.py +23 -23
  50. pygeai/tests/snippets/lab/agents/get_sharing_link.py +1 -2
  51. pygeai/tests/snippets/lab/samples/summarize_files.py +3 -3
  52. pygeai/tests/snippets/lab/tools/create_tool.py +1 -1
  53. pygeai/tests/snippets/lab/use_cases/file_summarizer_example.py +3 -3
  54. pygeai/tests/snippets/lab/use_cases/file_summarizer_example_2.py +11 -11
  55. pygeai/tests/snippets/lab/use_cases/update_web_reader.py +1 -2
  56. {pygeai-0.4.0b3.dist-info → pygeai-0.5.0.dist-info}/METADATA +47 -19
  57. {pygeai-0.4.0b3.dist-info → pygeai-0.5.0.dist-info}/RECORD +61 -39
  58. {pygeai-0.4.0b3.dist-info → pygeai-0.5.0.dist-info}/WHEEL +0 -0
  59. {pygeai-0.4.0b3.dist-info → pygeai-0.5.0.dist-info}/entry_points.txt +0 -0
  60. {pygeai-0.4.0b3.dist-info → pygeai-0.5.0.dist-info}/licenses/LICENSE +0 -0
  61. {pygeai-0.4.0b3.dist-info → pygeai-0.5.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,345 @@
1
+ from unittest import TestCase
2
+ import unittest
3
+ import uuid
4
+ from pygeai.lab.managers import AILabManager
5
+ from pygeai.lab.models import (
6
+ AgenticProcess, KnowledgeBase, AgenticActivity, ArtifactSignal, Task,
7
+ UserSignal, Event, SequenceFlow, Variable
8
+ )
9
+ from pygeai.core.common.exceptions import APIResponseError, APIError
10
+
11
+
12
+ class TestAILabCreateProcessIntegration(TestCase):
13
+
14
+ def setUp(self):
15
+ """
16
+ Set up the test environment.
17
+ """
18
+ self.ai_lab_manager = AILabManager(alias="beta")
19
+ self.new_process = self.__load_process()
20
+ self.created_process: AgenticProcess = None
21
+
22
+
23
+ def tearDown(self):
24
+ """
25
+ Clean up after each test if necessary.
26
+ This can be used to delete the created process
27
+ """
28
+ if isinstance(self.created_process, AgenticProcess):
29
+ self.ai_lab_manager.delete_process(self.created_process.id)
30
+
31
+
32
+ def __load_process(self):
33
+ """
34
+ Helper to load a complete process configuration for testing.
35
+ """
36
+ unique_key = str(uuid.uuid4())
37
+ process = AgenticProcess(
38
+ key="product_def",
39
+ name=f"Test Process {unique_key[:8]}",
40
+ description="This is a sample process",
41
+ kb=KnowledgeBase(name="basic-sample", artifact_type_name=["sample-artifact"]),
42
+ agentic_activities=[
43
+ AgenticActivity(key="activityOne", name="First Step", task_name="basic-task", agent_name="GoogleSummarizer2", agent_revision_id=0)
44
+ ],
45
+ artifact_signals=[
46
+ ArtifactSignal(key="artifact.upload.1", name="artifact.upload", handling_type="C", artifact_type_name=["sample-artifact"])
47
+ ],
48
+ user_signals=[
49
+ UserSignal(key="signal_done", name="process-completed")
50
+ ],
51
+ start_event=Event(key="artifact.upload.1", name="artifact.upload"),
52
+ end_event=Event(key="end", name="Done"),
53
+ sequence_flows=[
54
+ SequenceFlow(key="step1", source_key="artifact.upload.1", target_key="activityOne"),
55
+ SequenceFlow(key="step2", source_key="activityOne", target_key="signal_done"),
56
+ SequenceFlow(key="stepEnd", source_key="signal_done", target_key="end")
57
+ ]
58
+ )
59
+ return process
60
+
61
+
62
+ def __create_process(self, process=None, automatic_publish=False):
63
+ """
64
+ Helper to create a process using ai_lab_manager.
65
+ """
66
+ return self.ai_lab_manager.create_process(
67
+ process=self.new_process if process is None else process,
68
+ automatic_publish=automatic_publish
69
+ )
70
+
71
+
72
+ def test_create_process_full_data(self):
73
+ """
74
+ Test creating a process with all available fields populated.
75
+ """
76
+ self.created_process = self.__create_process()
77
+ created_process = self.created_process
78
+ process = self.new_process
79
+
80
+ self.assertTrue(isinstance(created_process, AgenticProcess), "Expected a created process")
81
+
82
+ # Assert the main fields of the created process
83
+ self.assertIsNotNone(created_process.id)
84
+ #self.assertEqual(created_process.key, process.key)
85
+ self.assertEqual(created_process.name, process.name)
86
+ self.assertEqual(created_process.description, process.description)
87
+ self.assertEqual(created_process.status, "active")
88
+
89
+ # Assert knowledge base
90
+ self.assertIsNotNone(created_process.kb)
91
+ self.assertEqual(created_process.kb.name, process.kb.name)
92
+
93
+ # Assert agentic activities
94
+ created_activity = created_process.agentic_activities[0]
95
+ original_activity = process.agentic_activities[0]
96
+ self.assertTrue(isinstance(created_activity, AgenticActivity))
97
+ self.assertEqual(created_activity.key.lower(), original_activity.key.lower())
98
+ self.assertEqual(created_activity.name, original_activity.name)
99
+
100
+ # Assert artifact signals
101
+ created_signal = created_process.artifact_signals[0]
102
+ original_signal = process.artifact_signals[0]
103
+ self.assertTrue(isinstance(created_signal, ArtifactSignal))
104
+ self.assertEqual(created_signal.key.lower(), original_signal.key.lower())
105
+ self.assertEqual(created_signal.name, original_signal.name)
106
+ self.assertEqual(created_signal.handling_type, original_signal.handling_type)
107
+
108
+ # Assert user signals
109
+ created_user_signal = created_process.user_signals[0]
110
+ self.assertTrue(isinstance(created_user_signal, UserSignal))
111
+
112
+ # Assert events
113
+ self.assertIsNotNone(created_process.start_event)
114
+ self.assertEqual(created_process.start_event.key.lower(), process.start_event.key.lower())
115
+ self.assertEqual(created_process.start_event.name, process.start_event.name)
116
+
117
+ self.assertIsNotNone(created_process.end_event)
118
+ self.assertEqual(created_process.end_event.key.lower(), process.end_event.key.lower())
119
+ self.assertEqual(created_process.end_event.name, process.end_event.name)
120
+
121
+ # Assert sequence flows
122
+ created_flow = created_process.sequence_flows[0]
123
+ original_flow = process.sequence_flows[0]
124
+ self.assertIsNotNone(created_process.sequence_flows)
125
+ self.assertEqual(len(created_process.sequence_flows), len(process.sequence_flows))
126
+
127
+ self.assertEqual(created_flow.key.lower(), original_flow.key.lower())
128
+ self.assertEqual(created_flow.source_key.lower(), original_flow.source_key.lower())
129
+ self.assertEqual(created_flow.target_key.lower(), original_flow.target_key.lower())
130
+
131
+
132
+ def test_create_process_minimum_required_data(self):
133
+ """
134
+ Test creating a process with only minimum required fields (key and name).
135
+ """
136
+ unique_key = str(uuid.uuid4())
137
+ self.new_process = AgenticProcess(
138
+ key=unique_key,
139
+ name=f"Minimal Process {unique_key[:8]}"
140
+ )
141
+ self.created_process = self.__create_process()
142
+ process = self.new_process
143
+
144
+ self.assertTrue(isinstance(self.created_process, AgenticProcess), "Expected a created process")
145
+ self.assertIsNotNone(self.created_process.id)
146
+ self.assertEqual(self.created_process.name, process.name)
147
+
148
+
149
+ def test_create_process_without_key(self):
150
+ """
151
+ Test creating a process without a key should still work (key is optional).
152
+ """
153
+ self.new_process = AgenticProcess(
154
+ name=f"Process Without Key {str(uuid.uuid4())[:8]}"
155
+ )
156
+ self.created_process = self.__create_process()
157
+
158
+ self.assertTrue(isinstance(self.created_process, AgenticProcess), "Expected a created process")
159
+ self.assertIsNotNone(self.created_process.id)
160
+ self.assertEqual(self.created_process.name, self.new_process.name)
161
+
162
+
163
+ def test_create_process_no_name(self):
164
+ """
165
+ Test creating a process without a name should raise an error.
166
+ """
167
+ test_params = [True, False]
168
+
169
+ for auto_publish in test_params:
170
+ with self.subTest(input=auto_publish):
171
+ self.new_process.name = ""
172
+ with self.assertRaises(APIError) as exception:
173
+ self.__create_process(automatic_publish=auto_publish)
174
+
175
+ self.assertIn(
176
+ "Process name cannot be empty",
177
+ str(exception.exception),
178
+ f"Expected an error about empty process name with autopublish {'enabled' if auto_publish else 'disabled'}"
179
+ )
180
+
181
+
182
+ def test_create_process_duplicated_name(self):
183
+ """
184
+ Test creating a process with a duplicate name should raise an error.
185
+ """
186
+ test_params = [True, False]
187
+ created_process = self.__create_process()
188
+
189
+ for auto_publish in test_params:
190
+ with self.subTest(input=auto_publish):
191
+ loaded_process = self.__load_process()
192
+ loaded_process.name = created_process.name
193
+ with self.assertRaises(APIError) as exception:
194
+ self.__create_process(process = loaded_process, automatic_publish=auto_publish)
195
+
196
+ self.assertIn(
197
+ f"A process with this name already exists [name={created_process.name}].",
198
+ str(exception.exception),
199
+ f"Expected an error about duplicated process name with autopublish {'enabled' if auto_publish else 'disabled'}"
200
+ )
201
+
202
+
203
+ def test_create_process_invalid_name_characters(self):
204
+ """
205
+ Test creating a process with invalid characters in name should raise a validation error.
206
+ """
207
+ test_params = [True, False]
208
+
209
+ for auto_publish in test_params:
210
+ with self.subTest(input=auto_publish):
211
+ invalid_names = [
212
+ f"{str(uuid.uuid4())[:8]}:invalid",
213
+ f"{str(uuid.uuid4())[:8]}/invalid"
214
+ ]
215
+
216
+ for invalid_name in invalid_names:
217
+ new_process = self.__load_process()
218
+ new_process.name = invalid_name
219
+
220
+ with self.assertRaises(APIError) as exception:
221
+ self.__create_process(process=new_process, automatic_publish=auto_publish)
222
+
223
+ self.assertIn(
224
+ "Invalid character in name",
225
+ str(exception.exception),
226
+ f"Expected an error about invalid character in process name with autopublish {'enabled' if auto_publish else 'disabled'}"
227
+ )
228
+
229
+
230
+ @unittest.skip("Skipping test for now.KB is required but is marked as optional")
231
+ def test_create_process_with_no_kb(self):
232
+ """
233
+ Test creating a process with knowledge base in JSON format.
234
+ """
235
+ unique_key = str(uuid.uuid4())
236
+ self.new_process.kb = None
237
+ self.created_process = self.__create_process()
238
+
239
+ self.assertIsNotNone(self.created_process.kb)
240
+ self.assertEqual(self.created_process.kb.name, "basic-sample")
241
+
242
+
243
+ def test_create_process_with_empty_agentic_activities_array(self):
244
+ """
245
+ Test creating a process with empty agentic activities array (to clear all activities).
246
+ """
247
+ self.new_process.agentic_activities = []
248
+ self.new_process.sequence_flows = [] # Clear sequence flows as well because they depend on activities
249
+ self.created_process = self.__create_process()
250
+
251
+ # Empty array should be handled gracefully
252
+ self.assertTrue(
253
+ self.created_process.agentic_activities is None or
254
+ len(self.created_process.agentic_activities) == 0
255
+ )
256
+
257
+
258
+ def test_create_process_with_multiple_artifact_signals(self):
259
+ """
260
+ Test creating a process with multiple artifact signals.
261
+ """
262
+ self.new_process.artifact_signals=[
263
+ ArtifactSignal(key="artifact.upload.1", name="artifact.upload", handling_type="C", artifact_type_name=["sample-artifact"]),
264
+ ArtifactSignal(key="artifact.upload.2", name="artifact.upload.second", handling_type="C", artifact_type_name=["sample-artifact"])
265
+ ]
266
+ self.created_process = self.__create_process()
267
+
268
+ self.assertIsNotNone(self.created_process.artifact_signals)
269
+ self.assertEqual(len(self.created_process.artifact_signals), 2)
270
+
271
+ first_signal = self.created_process.artifact_signals[0]
272
+ second_signal = self.created_process.artifact_signals[1]
273
+
274
+ self.assertEqual(first_signal.key.lower(), "artifact.upload.1")
275
+ self.assertEqual(second_signal.key.lower(), "artifact.upload.2")
276
+
277
+
278
+ def test_create_process_with_multiple_user_signals(self):
279
+ """
280
+ Test creating a process with multiple user signals.
281
+ """
282
+ self.new_process.user_signals=[
283
+ UserSignal(key="signal_done", name="process-completed"),
284
+ UserSignal(key="signal_cancel", name="process-cancelled")
285
+ ]
286
+ self.created_process = self.__create_process()
287
+
288
+ self.assertIsNotNone(self.created_process.user_signals)
289
+ self.assertEqual(len(self.created_process.user_signals)-1, 2)
290
+ keys = [signal.key for signal in self.created_process.user_signals]
291
+
292
+ assert "SIGNAL_CANCEL" in keys
293
+ assert "SIGNAL_DONE" in keys
294
+
295
+
296
+ def test_create_process_autopublish_disabled(self):
297
+ """
298
+ Test creating a process without automatic publish (default behavior).
299
+ """
300
+ self.created_process = self.__create_process(automatic_publish=False)
301
+
302
+ # Process should be created as draft by default
303
+ self.assertTrue(
304
+ self.created_process.is_draft is True or
305
+ self.created_process.is_draft is None, # API might not return this field for drafts
306
+ "Expected the process to be created as draft when autopublish is disabled"
307
+ )
308
+
309
+
310
+ def test_create_process_autopublish_without_task(self):
311
+ """
312
+ Test creating a process with automatic publish enabled.
313
+ """
314
+
315
+ with self.assertRaises(APIError) as exception:
316
+ self.__create_process(automatic_publish=True)
317
+
318
+ self.assertIn(
319
+ "Failure on process publication",
320
+ str(exception.exception),
321
+ "Expected an error about failure on process publication"
322
+ )
323
+
324
+ self.assertIn(
325
+ "Task is required",
326
+ str(exception.exception),
327
+ "Expected an error about task being required"
328
+ )
329
+
330
+
331
+ def test_create_process_autopublish_enabled(self):
332
+ """
333
+ Test creating a process with automatic publish enabled.
334
+ """
335
+ unique_key = str(uuid.uuid4())
336
+ task = Task(name=unique_key, description="Basic task for process", title_template="Basic Task")
337
+ self.ai_lab_manager.create_task(task=task, automatic_publish=True)
338
+ self.new_process.agentic_activities[0].task_name = unique_key
339
+
340
+
341
+ self.created_process = self.__create_process(automatic_publish=True)
342
+ self.assertTrue(
343
+ self.created_process.is_draft is False,
344
+ "Expected the process to be created no draft when autopublish is enabled"
345
+ )
@@ -0,0 +1,201 @@
1
+ from unittest import TestCase
2
+ import unittest
3
+ from pygeai.lab.managers import AILabManager
4
+ from pygeai.lab.models import AgenticProcess, FilterSettings, KnowledgeBase, AgenticActivity, ArtifactSignal, UserSignal, Event, SequenceFlow
5
+ from pygeai.core.common.exceptions import APIResponseError, APIError, MissingRequirementException
6
+ import copy
7
+ import uuid
8
+
9
+
10
+ class TestAILabGetProcessIntegration(TestCase):
11
+
12
+ def setUp(self):
13
+ """
14
+ Set up the test environment.
15
+ """
16
+ self.ai_lab_manager = AILabManager(alias="beta")
17
+ self.process_id = "7e28e9ab-b9a2-417e-9e87-ed7f6ec9534b"
18
+ self.process_name = "Test Process For Sdk Project"
19
+ self.filter_settings = FilterSettings(
20
+ revision="0",
21
+ version="0"
22
+ )
23
+
24
+
25
+ def __get_process(self, process_id=None, process_name=None, filter_settings: FilterSettings = None):
26
+ """
27
+ Helper method to get a process.
28
+ """
29
+ return self.ai_lab_manager.get_process(
30
+ process_id=self.process_id if process_id is None else process_id,
31
+ process_name=self.process_name if process_name is None else process_name,
32
+ filter_settings=self.filter_settings if filter_settings is None else filter_settings
33
+ )
34
+
35
+ def test_get_process_by_id(self):
36
+ """
37
+ Test getting a process by ID.
38
+ """
39
+ process = self.__get_process(process_name="")
40
+ self.assertIsInstance(process, AgenticProcess, "Expected an AgenticProcess")
41
+ self.assertEqual(process.id, self.process_id)
42
+
43
+
44
+ def test_get_process_by_name(self):
45
+ """
46
+ Test getting a process by name instead of ID.
47
+ """
48
+ process = self.__get_process(process_id=None)
49
+ self.assertIsInstance(process, AgenticProcess, "Expected an AgenticProcess")
50
+ self.assertEqual(process.name, self.process_name)
51
+
52
+
53
+ def test_get_process_no_id_or_name(self):
54
+ """
55
+ Test getting a process without providing ID or name should raise an error.
56
+ """
57
+ with self.assertRaises(MissingRequirementException) as context:
58
+ self.__get_process(process_id="", process_name="")
59
+ self.assertIn(
60
+ "Either process_id or process_name must be provided",
61
+ str(context.exception),
62
+ "Expected an error for no id or name provided"
63
+ )
64
+
65
+
66
+ def test_get_process_invalid_process_id(self):
67
+ """
68
+ Test getting a process with an invalid ID.
69
+ """
70
+ invalid_id = "0026e53d-ea78-4cac-af9f-12650invalid"
71
+ with self.assertRaises(APIError) as context:
72
+ self.__get_process(process_id=invalid_id, process_name="")
73
+ self.assertIn(
74
+ f"Process not found [IdOrName= {invalid_id}]",
75
+ str(context.exception),
76
+ "Expected an error for invalid process id"
77
+ )
78
+
79
+
80
+ def test_get_process_invalid_process_name(self):
81
+ """
82
+ Test getting a process with an invalid name.
83
+ """
84
+ invalid_name = "NonExistentProcessName_12345"
85
+ with self.assertRaises(APIError) as context:
86
+ self.__get_process(process_id="", process_name=invalid_name)
87
+ self.assertIn(
88
+ f"Process not found [IdOrName= {invalid_name}]",
89
+ str(context.exception),
90
+ "Expected an error for invalid process name"
91
+ )
92
+
93
+ def test_get_process_no_revision(self):
94
+ """
95
+ Test getting a process without specifying revision (should return latest).
96
+ """
97
+ filter_settings = copy.deepcopy(self.filter_settings)
98
+ filter_settings.revision = None
99
+ process = self.__get_process(filter_settings=filter_settings)
100
+
101
+ self.assertIsInstance(process, AgenticProcess, "Expected an AgenticProcess")
102
+ self.assertGreaterEqual(process.revision or 0, 0, "Expected process revision to be the latest")
103
+
104
+
105
+ def test_get_process_by_revision(self):
106
+ """
107
+ Test getting a process by specific revision.
108
+ """
109
+ filter_settings = copy.deepcopy(self.filter_settings)
110
+ filter_settings.revision = 4
111
+ process = self.__get_process(filter_settings=filter_settings)
112
+
113
+ self.assertIsInstance(process, AgenticProcess, "Expected an AgenticProcess")
114
+ self.assertEqual(process.revision, filter_settings.revision, f"Expected process revision to be {filter_settings.revision}")
115
+
116
+
117
+ def test_get_process_by_earlier_revision(self):
118
+ """
119
+ Test getting a process by an earlier revision that might not exist.
120
+ """
121
+ filter_settings = copy.deepcopy(self.filter_settings)
122
+ filter_settings.revision = 3
123
+ process = self.__get_process(filter_settings=filter_settings)
124
+
125
+ self.assertIsInstance(process, AgenticProcess, "Expected an AgenticProcess")
126
+ self.assertEqual(process.revision, filter_settings.revision, f"Expected process revision to be {filter_settings.revision}")
127
+
128
+
129
+ def test_get_process_no_version(self):
130
+ """
131
+ Test getting a process without specifying version (should return latest).
132
+ """
133
+ filter_settings = copy.deepcopy(self.filter_settings)
134
+ filter_settings.version = None
135
+ process = self.__get_process(filter_settings=filter_settings)
136
+
137
+ self.assertIsInstance(process, AgenticProcess, "Expected an AgenticProcess")
138
+ self.assertGreaterEqual(process.version_id or 0, 0, "Expected process version to be the latest")
139
+
140
+
141
+ def test_get_process_by_version(self):
142
+ """
143
+ Test getting a process by specific version.
144
+ """
145
+ filter_settings = copy.deepcopy(self.filter_settings)
146
+ filter_settings.version = "2"
147
+ process = self.__get_process(filter_settings=filter_settings)
148
+
149
+ self.assertIsInstance(process, AgenticProcess, "Expected an AgenticProcess")
150
+ self.assertEqual(process.version_id, 2, "Expected process version to be 2")
151
+
152
+
153
+ def test_get_process_by_invalid_version(self):
154
+ """
155
+ Test getting a process by an invalid version.
156
+ """
157
+ filter_settings = copy.deepcopy(self.filter_settings)
158
+ filter_settings.version = "999" # Non-existent version
159
+
160
+ with self.assertRaises(APIError) as context:
161
+ self.__get_process(filter_settings=filter_settings)
162
+
163
+ self.assertIn(
164
+ "Requested version not found [version=999]",
165
+ str(context.exception),
166
+ "Expected an error for version not found"
167
+ )
168
+
169
+
170
+ def test_get_process_allow_drafts_true(self):
171
+ """
172
+ Test getting a process with allow_drafts=True (should include drafts).
173
+ """
174
+
175
+ filter_settings = copy.deepcopy(self.filter_settings)
176
+ filter_settings.allow_drafts = True
177
+ process = self.__get_process(filter_settings = filter_settings)
178
+ self.assertIsInstance(process, AgenticProcess, "Expected an AgenticProcess")
179
+ # Draft processes should be retrievable
180
+ self.assertTrue(
181
+ process.is_draft,
182
+ "Should be able to retrieve both draft and published processes"
183
+ )
184
+
185
+
186
+ def test_get_process_allow_drafts_false(self):
187
+ """
188
+ Test getting a process with allow_drafts=False (should exclude drafts).
189
+ """
190
+
191
+ filter_settings = copy.deepcopy(self.filter_settings)
192
+ filter_settings.allow_drafts = False
193
+ process = self.__get_process(filter_settings = filter_settings)
194
+
195
+ self.assertIsInstance(process, AgenticProcess, "Expected an AgenticProcess")
196
+ self.assertFalse(
197
+ process.is_draft,
198
+ "Should be able to retrieve published revisions"
199
+ )
200
+
201
+