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,158 @@
1
+ from unittest import TestCase
2
+ from pygeai.chat.clients import ChatClient
3
+
4
+ chat_client: ChatClient
5
+
6
+ class TestChatGenerateImageIntegration(TestCase):
7
+
8
+ def setUp(self):
9
+ self.chat_client = ChatClient(alias="beta")
10
+ self.new_image = self.__load_image()
11
+
12
+
13
+ def __load_image(self):
14
+ return {
15
+ "model": "openai/gpt-image-1",
16
+ "prompt": "generate an image of a futuristic city skyline at sunset",
17
+ "n": 1,
18
+ "quality": "high",
19
+ "size": "1024x1536"
20
+ }
21
+
22
+
23
+ def __generate_image(self, image = None):
24
+ image = image if image is not None else self.new_image
25
+ return self.chat_client.generate_image(
26
+ model=image["model"],
27
+ prompt=image["prompt"],
28
+ n=image["n"],
29
+ quality=image["quality"],
30
+ size=image["size"],
31
+ aspect_ratio= image["aspect_ratio"] if "aspect_ratio" in image else None
32
+ )
33
+
34
+
35
+ def test_generate_image(self):
36
+ created_image = self.__generate_image()
37
+ self.assertEqual(len(created_image["data"]), 1, "Expected an image to be generated")
38
+
39
+
40
+ def test_generate_image_invalid_model(self):
41
+ self.new_image["model"] = "openai/gpt-image-10",
42
+ created_image = self.__generate_image()
43
+
44
+ self.assertEqual(
45
+ created_image["error"]["code"], 400,
46
+ "Expected a 400 code for invalid model"
47
+ )
48
+ self.assertEqual(
49
+ created_image["error"]["message"],
50
+ 'Provider \'["openai\' does not exists.',
51
+ "Expected an error message when model does not exists"
52
+ )
53
+
54
+
55
+ def test_generate_image_no_model(self):
56
+ self.new_image["model"] = ""
57
+ created_image = self.__generate_image()
58
+
59
+ self.assertEqual(
60
+ created_image["error"]["message"],
61
+ "LLM Provider NOT provided. Pass in the LLM provider you are trying to call",
62
+ "Expected an error message when no model is provided"
63
+ )
64
+
65
+
66
+ def test_generate_image_no_prompt(self):
67
+ self.new_image["prompt"] = ""
68
+ created_image = self.__generate_image()
69
+
70
+ self.assertEqual(
71
+ created_image["error"]["type"],
72
+ "invalid_request_error",
73
+ "Expected a 400 code for no model"
74
+ )
75
+ self.assertEqual(
76
+ created_image["error"]["param"], "prompt",
77
+ "Expected an error message when no model is provided"
78
+ )
79
+
80
+
81
+ def test_generate_image_specific_n(self):
82
+ self.new_image["n"] = 2
83
+
84
+ created_image = self.__generate_image()
85
+ self.assertEqual(len(created_image["data"]), 2, "Expected two images to be generated")
86
+
87
+
88
+ def test_generate_image_no_n(self):
89
+ self.new_image["n"] = None # default is 1
90
+
91
+ created_image = self.__generate_image()
92
+ self.assertEqual(len(created_image["data"]), 1, "Expected an image to be generated")
93
+
94
+
95
+ def test_generate_image_no_supported_n(self):
96
+ self.new_image["model"] = "openai/dall-e-3"
97
+ self.new_image["n"] = 5
98
+
99
+ created_image = self.__generate_image()
100
+ self.assertIn(
101
+ "Invalid 'n': integer above maximum value",
102
+ created_image["error"]["message"],
103
+ "Expected an error message when n is not supported by the model"
104
+ )
105
+
106
+
107
+ def test_generate_image_no_quality(self):
108
+ self.new_image["quality"] = ""
109
+
110
+ created_image = self.__generate_image()
111
+ self.assertIn(
112
+ "Invalid value: ''. Supported values are: 'low', 'medium', 'high', and 'auto'",
113
+ created_image["error"]["message"],
114
+ "Expected an error message when quality is not provided"
115
+ )
116
+
117
+
118
+ def test_generate_image_no_supported_quality(self):
119
+ self.new_image["model"] = "openai/dall-e-3"
120
+
121
+ created_image = self.__generate_image()
122
+ self.assertIn(
123
+ "Invalid value: 'high'. Supported values are: 'standard' and 'hd'",
124
+ created_image["error"]["message"],
125
+ "Expected an error message when quality is not supported by the model"
126
+ )
127
+
128
+
129
+ def test_generate_image_no_size(self):
130
+ self.new_image["size"] = ""
131
+
132
+ created_image = self.__generate_image()
133
+ self.assertIn(
134
+ "Invalid value: ''. Supported values are: '1024x1024', '1024x1536', '1536x1024', and 'auto'",
135
+ created_image["error"]["message"],
136
+ "Expected an error message when no size is provided"
137
+ )
138
+
139
+
140
+ def test_generate_image_no_supported_size(self):
141
+ self.new_image["size"] = 1024
142
+ self.new_image["quality"] = None
143
+
144
+ created_image = self.__generate_image()
145
+ self.assertIn(
146
+ "Invalid type for 'size': expected one of '1024x1024', '1024x1536', '1536x1024', or 'auto', but got an integer instead",
147
+ created_image["error"]["message"],
148
+ "Expected an error message when no size is provided"
149
+ )
150
+
151
+
152
+ def test_generate_image_with_aspect_ratio(self):
153
+ self.new_image["model"] = "vertex_ai/imagen-3.0-generate-001"
154
+ self.new_image["aspect_ratio"] = "4:3"
155
+ self.new_image["quality"] = None
156
+
157
+ created_image = self.__generate_image()
158
+ self.assertEqual(len(created_image["data"]), 1, "Expected an image to be generated")
@@ -33,7 +33,6 @@ class TestAILabCreateAgentIntegration(TestCase):
33
33
  access_scope="public",
34
34
  public_name=f"public_{random_str}",
35
35
  job_description="Translator",
36
- avatar_image="https://www.shareicon.net/data/128x128/2016/11/09/851442_logo_512x512.png",
37
36
  description="Agent that translates from any language to english.",
38
37
  agent_data=AgentData(
39
38
  prompt=Prompt(
@@ -142,7 +141,6 @@ class TestAILabCreateAgentIntegration(TestCase):
142
141
  self.assertEqual(prompt.inputs, agent.agent_data.prompt.inputs)
143
142
 
144
143
 
145
- @unittest.skip("Skipping test due to mismatch in expected behavior")
146
144
  def test_create_agent_without_required_data(self):
147
145
  test_params = [ True, False ]
148
146
 
@@ -152,12 +150,19 @@ class TestAILabCreateAgentIntegration(TestCase):
152
150
  self.new_agent = Agent(
153
151
  name=str(uuid.uuid4())
154
152
  )
155
- with self.assertRaises(APIError) as exception:
156
- self.__create_agent(automatic_publish=auto_publish)
153
+ if auto_publish:
154
+
155
+ with self.assertRaises(APIError) as exception:
156
+ self.__create_agent(automatic_publish=auto_publish)
157
157
 
158
- #TODO: Change validation error to a more specific one
159
- self.assertIn("400",str(exception.exception))
160
- self.assertIn("Bad Request",str(exception.exception))
158
+ #TODO: Change validation error to a more specific one
159
+ self.assertIn(
160
+ "A valid prompt is required. To be valid, it must provide clear instructions to the model",
161
+ str(exception.exception)
162
+ )
163
+ else:
164
+ created_agent = self.__create_agent(automatic_publish=auto_publish)
165
+ self.assertTrue(isinstance(created_agent, Agent), "Expected a created agent")
161
166
 
162
167
 
163
168
  def test_create_agent_no_name(self):
@@ -287,21 +292,18 @@ class TestAILabCreateAgentIntegration(TestCase):
287
292
  )
288
293
 
289
294
 
290
- @unittest.skip("Agent is getting created regardless of the prompt instructions being empty")
291
295
  def test_create_agent_no_prompt_instructions(self):
292
296
  self.new_agent.agent_data.prompt.instructions = ""
293
- with self.assertRaises(ValidationError) as exception:
294
- self.__create_agent()
295
- self.assertIn(
296
- "instructions",
297
- str(exception.exception),
298
- "Expected a validation error about allowed values for instructions"
299
- )
297
+ self.created_agent = self.__create_agent()
300
298
 
301
- self.assertIn(
302
- "Input should be a valid string [type=string_type, input_value=None, input_type=NoneType]",
303
- str(exception.exception),
304
- "Expected a validation error about allowed values for instructions"
299
+ self.assertTrue(
300
+ isinstance(self.created_agent, Agent),
301
+ "Expected a created agent"
302
+ )
303
+
304
+ self.assertIsNone(
305
+ self.created_agent.agent_data.prompt.instructions,
306
+ "Expected the created agent to not have prompt instructions"
305
307
  )
306
308
 
307
309
 
@@ -1,4 +1,5 @@
1
1
  from unittest import TestCase
2
+ import unittest
2
3
  from pygeai.lab.managers import AILabManager
3
4
  from pygeai.lab.models import SharingLink
4
5
  from pygeai.core.common.exceptions import APIError, MissingRequirementException
@@ -16,7 +17,7 @@ class TestAILabCreateSharingLinkIntegration(TestCase):
16
17
  agent_id=self.agent_id if agent_id is None else agent_id
17
18
  )
18
19
 
19
-
20
+ @unittest.skip("Endpoint is not found. Validate if it was deleted")
20
21
  def test_create_sharing_link(self):
21
22
  shared_link = self.__create_sharing_link()
22
23
  self.assertIsInstance(shared_link, SharingLink, "Expected response to be an instance of SharingLink")
@@ -46,6 +47,7 @@ class TestAILabCreateSharingLinkIntegration(TestCase):
46
47
  )
47
48
 
48
49
 
50
+ @unittest.skip("Endpoint is not found. Validate if it was deleted")
49
51
  def test_create_sharing_link_no_agent_id(self):
50
52
  with self.assertRaises(MissingRequirementException) as context:
51
53
  self.__create_sharing_link(agent_id="")
@@ -56,6 +58,7 @@ class TestAILabCreateSharingLinkIntegration(TestCase):
56
58
  )
57
59
 
58
60
 
61
+ @unittest.skip("Endpoint is not found. Validate if it was deleted")
59
62
  def test_create_sharing_link_invalid_agent_id(self):
60
63
  with self.assertRaises(APIError) as exception:
61
64
  invalid_id = "0026e53d-ea78-4cac-af9f-12650invalid"
@@ -28,7 +28,6 @@ class TestAILabPublishAgentRevisionIntegration(TestCase):
28
28
  access_scope="public",
29
29
  public_name=f"public_{random_str}",
30
30
  job_description=f"SummarizerAgent{random_str}",
31
- avatar_image="https://www.shareicon.net/data/128x128/2016/11/09/851442_logo_512x512.png",
32
31
  description=f"Agent that summarized documents. {random_str}",
33
32
  agent_data=AgentData(
34
33
  prompt=Prompt(
@@ -25,7 +25,6 @@ class TestAILabUpdateAgentIntegration(TestCase):
25
25
  access_scope="public",
26
26
  public_name=f"public_{random_str}",
27
27
  job_description=f"SummarizerAgent{random_str}",
28
- avatar_image="https://www.shareicon.net/data/128x128/2016/11/09/851442_logo_512x512.png",
29
28
  description=f"Agent that summarized documents. {random_str}",
30
29
  agent_data=AgentData(
31
30
  prompt=Prompt(
@@ -192,43 +191,32 @@ class TestAILabUpdateAgentIntegration(TestCase):
192
191
  self.agent_to_update.agent_data.prompt.instructions = ""
193
192
 
194
193
  for auto_publish in test_params:
195
- with self.subTest(input=auto_publish):
196
- with self.assertRaises(ValidationError) as exception:
197
- self.__update_agent(automatic_publish=auto_publish)
198
-
199
- self.assertIn(
200
- "instructions",
201
- str(exception.exception),
202
- f"Expected a validation error about allowed values for instructions when autopublish is {'enabled' if auto_publish else 'disabled'}"
203
- )
204
- self.assertIn(
205
- "Input should be a valid string [type=string_type, input_value=None, input_type=NoneType]",
206
- str(exception.exception),
207
- f"Expected a validation error about allowed values for instructions when autopublish is {'enabled' if auto_publish else 'disabled'}"
208
- )
194
+ with self.subTest(input=auto_publish):
195
+ if auto_publish == True:
196
+ with self.assertRaises(ValidationError) as exception:
197
+ self.__update_agent(automatic_publish=auto_publish)
198
+ self.assertIn(
199
+ "agent_data.prompt must have at least instructions for publication",
200
+ str(exception.exception),
201
+ f"Expected a validation error about allowed values for instructions when autopublish is {'enabled' if auto_publish else 'disabled'}"
202
+ )
203
+ else:
204
+ updated_agent = self.__update_agent(automatic_publish=auto_publish)
205
+ self.assertTrue(isinstance(updated_agent, Agent))
209
206
 
210
-
211
- def test_update_agent_no_model(self):
207
+
208
+ def test_update_agent_no_model(self):
212
209
  test_params = [ True, False ]
213
210
  self.agent_to_update.agent_data.models[0].name = ""
214
211
 
215
212
  for auto_publish in test_params:
216
213
  with self.subTest(input=auto_publish):
217
- if auto_publish == False:
218
- with self.assertRaises(ValidationError) as exception:
219
- self.__update_agent(automatic_publish=auto_publish)
220
- error_msg = str(exception.exception)
214
+
215
+ # If the agent is not published, the API returns a warning message for invalid model name. However, the sdk mapping is not returning it.
216
+ if auto_publish == False:
217
+ updated_agent = self.__update_agent(automatic_publish=auto_publish)
221
218
 
222
- self.assertIn(
223
- "name",
224
- error_msg,
225
- "Expected a validation error about empty model name"
226
- )
227
- self.assertIn(
228
- "Input should be a valid string [type=string_type, input_value=None, input_type=NoneType]",
229
- error_msg,
230
- "Expected a validation error about empty model name"
231
- )
219
+ self.assertTrue(isinstance(updated_agent, Agent))
232
220
  else:
233
221
  with self.assertRaises(APIError) as exception:
234
222
  self.__update_agent(automatic_publish=auto_publish)
File without changes