pygeai 0.4.0b1__py3-none-any.whl → 0.4.0b3__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.
pygeai/lab/models.py CHANGED
@@ -161,12 +161,13 @@ class Prompt(CustomBaseModel):
161
161
  :param context: Optional[str] - Background context for the agent # NOT IMPLEMENTED YET
162
162
  :param examples: List[PromptExample] - List of example input-output pairs.
163
163
  """
164
- instructions: str = Field(..., alias="instructions")
164
+ instructions: Optional[str] = Field(None, alias="instructions")
165
165
  inputs: Optional[List[str]] = Field(None, alias="inputs")
166
166
  outputs: Optional[List[PromptOutput]] = Field([], alias="outputs")
167
167
  context: Optional[str] = Field(None, alias="context", description="Background context for the agent")
168
168
  examples: Optional[List[PromptExample]] = Field(None, alias="examples")
169
169
 
170
+ '''
170
171
  @field_validator("instructions")
171
172
  @classmethod
172
173
  def validate_instructions(cls, value: str) -> str:
@@ -174,6 +175,7 @@ class Prompt(CustomBaseModel):
174
175
  raise ValueError("instructions cannot be blank")
175
176
 
176
177
  return value
178
+ '''
177
179
 
178
180
  @field_validator("outputs", mode="before")
179
181
  @classmethod
@@ -687,7 +689,7 @@ class Tool(CustomBaseModel):
687
689
  :param status: Optional[str] - Current status of the tool (e.g., "active"), defaults to None.
688
690
  """
689
691
  name: str = Field(..., alias="name", description="The name of the tool")
690
- description: str = Field(..., alias="description", description="Description of the tool's purpose")
692
+ description: Optional[str] = Field(None, alias="description", description="Description of the tool's purpose")
691
693
  scope: str = Field("builtin", alias="scope", description="The scope of the tool (e.g., 'builtin', 'external', 'api')")
692
694
  parameters: Optional[List[ToolParameter]] = Field(None, alias="parameters", description="List of parameters required by the tool")
693
695
  access_scope: Optional[str] = Field(None, alias="accessScope", description="The access scope of the tool ('public' or 'private')")
@@ -730,6 +732,7 @@ class Tool(CustomBaseModel):
730
732
  raise ValueError("public_name is required if access_scope is 'public'")
731
733
  return self
732
734
 
735
+ '''
733
736
  @model_validator(mode="after")
734
737
  def validate_api_tool_requirements(self):
735
738
  if self.scope == "api" and not (self.open_api or self.open_api_json):
@@ -739,6 +742,7 @@ class Tool(CustomBaseModel):
739
742
  if len(param_keys) != len(set(param_keys)):
740
743
  raise ValueError("All parameter keys must be unique within the tool")
741
744
  return self
745
+ '''
742
746
 
743
747
  @field_validator("parameters", mode="before")
744
748
  @classmethod
@@ -124,11 +124,11 @@ class AgentMigrationStrategy(MigrationStrategy):
124
124
  def __migrate_agent(self):
125
125
  new_agent = None
126
126
  try:
127
- source_agent = self.source_manager.get_agent(project_id=self.from_project_id, agent_id=self.agent_id)
127
+ source_agent = self.source_manager.get_agent(agent_id=self.agent_id)
128
128
  if not isinstance(source_agent, Agent):
129
129
  raise ValueError("Unable to retrieve requested agent.")
130
130
 
131
- new_agent = self.destination_manager.create_agent(project_id=self.to_project_id, agent=source_agent)
131
+ new_agent = self.destination_manager.create_agent(agent=source_agent)
132
132
  except Exception as e:
133
133
  Console.write_stderr(f"Agent migration failed: {e} \n")
134
134
 
@@ -174,11 +174,11 @@ class ToolMigrationStrategy(MigrationStrategy):
174
174
  def __migrate_tool(self):
175
175
  new_tool = None
176
176
  try:
177
- source_tool = self.source_manager.get_tool(project_id=self.from_project_id, tool_id=self.tool_id)
177
+ source_tool = self.source_manager.get_tool(tool_id=self.tool_id)
178
178
  if not isinstance(source_tool, Tool):
179
179
  raise ValueError("Unable to retrieve requested tool.")
180
180
 
181
- new_tool = self.destination_manager.create_tool(project_id=self.to_project_id, tool=source_tool)
181
+ new_tool = self.destination_manager.create_tool(tool=source_tool)
182
182
  except Exception as e:
183
183
  Console.write_stderr(f"Tool migration failed: {e}")
184
184
 
@@ -224,11 +224,11 @@ class AgenticProcessMigrationStrategy(MigrationStrategy):
224
224
  def __migrate_process(self):
225
225
  new_process = None
226
226
  try:
227
- source_process = self.source_manager.get_process(project_id=self.from_project_id, process_id=self.process_id)
227
+ source_process = self.source_manager.get_process(process_id=self.process_id)
228
228
  if not isinstance(source_process, AgenticProcess):
229
229
  raise ValueError("Unable to retrieve requested process.")
230
230
 
231
- new_process = self.destination_manager.create_process(project_id=self.to_project_id, process=source_process)
231
+ new_process = self.destination_manager.create_process(process=source_process)
232
232
  except Exception as e:
233
233
  Console.write_stderr(f"Process migration failed: {e}")
234
234
 
@@ -274,11 +274,11 @@ class TaskMigrationStrategy(MigrationStrategy):
274
274
  def __migrate_task(self):
275
275
  new_task = None
276
276
  try:
277
- source_task = self.source_manager.get_task(project_id=self.from_project_id, task_id=self.task_id)
277
+ source_task = self.source_manager.get_task(task_id=self.task_id)
278
278
  if not isinstance(source_task, Task):
279
279
  raise ValueError("Unable to retrieve requested task.")
280
280
 
281
- new_task = self.destination_manager.create_task(project_id=self.to_project_id, task=source_task)
281
+ new_task = self.destination_manager.create_task(task=source_task)
282
282
  except Exception as e:
283
283
  Console.write_stderr(f"Task migration failed: {e}")
284
284
 
File without changes
@@ -0,0 +1,294 @@
1
+ from unittest import TestCase
2
+ import unittest
3
+ import uuid
4
+ from pygeai.lab.managers import AILabManager
5
+ from pygeai.lab.models import Agent, AgentData, Prompt, LlmConfig, Model, Tool, ToolParameter,Sampling, PromptExample, PromptOutput
6
+ from pydantic import ValidationError
7
+ from pygeai.core.common.exceptions import APIError, InvalidAPIResponseException
8
+
9
+
10
+ class TestAILabCreateToolIntegration(TestCase):
11
+ def setUp(self):
12
+ """
13
+ Set up the test environment.
14
+ """
15
+ self.ai_lab_manager = AILabManager(alias="beta")
16
+ self.new_tool = self.__load_tool()
17
+ self.created_tool: Agent = None
18
+
19
+
20
+ def tearDown(self):
21
+ """
22
+ Clean up after each test if necessary.
23
+ This can be used to delete the created tool
24
+ """
25
+ if isinstance(self.created_tool, Tool):
26
+
27
+ self.ai_lab_manager.delete_tool(self.created_tool.id)
28
+
29
+
30
+ def __load_tool(self):
31
+ #random_str = str(uuid.uuid4())
32
+ return Tool(
33
+ name=str(uuid.uuid4()),
34
+ description="Tool created for sdk testing purposes",
35
+ scope="builtin",
36
+ openApi="https://raw.usercontent.com//openapi.json",
37
+ openApiJson={"openapi": "3.0.0","info": {"title": "Simple API overview","version": "2.0.0"}},
38
+ accessScope="private",
39
+ reportEvents="None",
40
+ parameters=[{"key": "param", "description": "param description", "type":"app", "value":"param value", "data_type": "String", "isRequired": False}],
41
+ )
42
+
43
+
44
+ def __create_tool(self, tool=None, automatic_publish=False):
45
+ """
46
+ Helper to create a tool using ai_lab_manager.
47
+ """
48
+ return self.ai_lab_manager.create_tool(
49
+ tool=self.new_tool if tool is None else tool,
50
+ automatic_publish=automatic_publish
51
+ )
52
+
53
+
54
+ def test_create_tool_full_data(self):
55
+ self.created_tool = self.__create_tool()
56
+ created_tool = self.created_tool
57
+ tool = self.new_tool
58
+ self.assertTrue(isinstance(created_tool, Tool), "Expected a created tool")
59
+
60
+ # Assert the main fields of the created tool
61
+ self.assertIsNotNone(created_tool.id)
62
+ self.assertEqual(created_tool.name, tool.name)
63
+ self.assertEqual(created_tool.description, tool.description)
64
+ self.assertEqual(created_tool.scope, tool.scope)
65
+ self.assertEqual(created_tool.access_scope, tool.access_scope)
66
+ self.assertEqual(created_tool.open_api, tool.open_api)
67
+ self.assertEqual(created_tool.status, "active")
68
+
69
+ # Assert agentData fields
70
+ tool_param = created_tool.parameters[0]
71
+ self.assertTrue(isinstance(tool_param, ToolParameter), "Expected parameters to be of type ToolParameter")
72
+ self.assertEqual(tool_param.key, tool.parameters[0].key)
73
+ self.assertEqual(tool_param.data_type, tool.parameters[0].data_type)
74
+ self.assertEqual(tool_param.description, tool.parameters[0].description)
75
+ self.assertEqual(tool_param.is_required, tool.parameters[0].is_required)
76
+ self.assertEqual(tool_param.type, tool.parameters[0].type)
77
+ self.assertEqual(tool_param.value, tool.parameters[0].value)
78
+
79
+
80
+ def test_create_tool_minimum_required_data(self):
81
+ self.new_tool = Tool(
82
+ name=str(uuid.uuid4()),
83
+ description="Tool created for sdk testing purposes",
84
+ scope="builtin"
85
+ )
86
+ self.created_tool = self.__create_tool()
87
+ tool = self.new_tool
88
+
89
+ self.assertIsNotNone(self.created_tool.id)
90
+ self.assertEqual(self.created_tool.name, tool.name)
91
+ self.assertEqual(self.created_tool.description, tool.description)
92
+
93
+
94
+ def test_create_tool_without_required_data(self):
95
+ test_params = [ True, False ]
96
+
97
+ for auto_publish in test_params:
98
+
99
+ with self.subTest(input=auto_publish):
100
+ with self.assertRaises(ValidationError) as context:
101
+ self.new_tool = Tool(
102
+ name=str(uuid.uuid4())
103
+ )
104
+ self.__create_tool(automatic_publish=auto_publish)
105
+
106
+ self.assertIn("description", str(context.exception))
107
+ self.assertIn("Field required", str(context.exception))
108
+
109
+
110
+ def test_create_tool_no_name(self):
111
+ test_params = [ True, False ]
112
+
113
+ for auto_publish in test_params:
114
+ with self.subTest(input=auto_publish):
115
+ self.new_tool.name = ""
116
+ with self.assertRaises(APIError) as exception:
117
+ self.__create_tool(automatic_publish=auto_publish)
118
+
119
+ self.assertIn(
120
+ "Tool name cannot be empty.",
121
+ str(exception.exception),
122
+ f"Expected an error about the missing tool name with autopublish {'enabled' if auto_publish else 'disabled'}"
123
+ )
124
+
125
+
126
+ def test_create_tool_duplicated_name(self):
127
+ test_params = [ True, False ]
128
+
129
+ for auto_publish in test_params:
130
+
131
+ with self.subTest(input=auto_publish):
132
+ self.new_tool.name = "sdk_project_gemini_tool"
133
+ with self.assertRaises(APIError) as exception:
134
+ self.__create_tool(automatic_publish=auto_publish)
135
+ self.assertIn(
136
+ "Tool already exists [name=sdk_project_gemini_tool]..",
137
+ str(exception.exception),
138
+ f"Expected an error about duplicated tool name with autopublish {'enabled' if auto_publish else 'disabled'}"
139
+ )
140
+
141
+
142
+ def test_create_tool_invalid_name(self):
143
+ test_params = [ True, False ]
144
+
145
+ for auto_publish in test_params:
146
+ with self.subTest(input=auto_publish):
147
+ new_tool = self.__load_tool()
148
+ new_tool2 = self.__load_tool()
149
+
150
+ with self.assertRaises(APIError) as exception:
151
+ new_tool.name = f"{new_tool.name}:invalid"
152
+ self.__create_tool(tool=new_tool, automatic_publish=auto_publish)
153
+ self.assertIn(
154
+ "Invalid character in name (: is not allowed).",
155
+ str(exception.exception),
156
+ f"Expected an error about invalid character (:) in tool name with autopublish {'enabled' if auto_publish else 'disabled'}"
157
+ )
158
+
159
+ with self.assertRaises(APIError) as exception:
160
+ new_tool2.name = f"{new_tool2.name}/invalid"
161
+ self.__create_tool(tool=new_tool2, automatic_publish=auto_publish)
162
+ self.assertIn(
163
+ "Invalid character in name (/ is not allowed).",
164
+ str(exception.exception),
165
+ f"Expected an error about invalid character (/) in tool name with autopublish {'enabled' if auto_publish else 'disabled'}"
166
+ )
167
+
168
+
169
+ def test_create_tool_invalid_access_scope(self):
170
+ self.new_tool.access_scope = "project"
171
+ with self.assertRaises(ValueError) as exc:
172
+ self.__create_tool()
173
+ self.assertEqual(
174
+ str(exc.exception),
175
+ "Access scope must be one of public, private.",
176
+ "Expected a ValueError exception for invalid access scope"
177
+ )
178
+
179
+
180
+ def test_create_tool_default_scope(self):
181
+ self.new_tool.access_scope = None
182
+ self.created_tool = self.__create_tool()
183
+
184
+ self.assertEqual(self.created_tool.access_scope, "private", "Expected the default access scope to be 'private' when not specified")
185
+
186
+
187
+ def test_create_tool_no_public_name(self):
188
+ test_params = [ True, False ]
189
+
190
+ for auto_publish in test_params:
191
+
192
+ with self.subTest(input=auto_publish):
193
+ self.new_tool.access_scope = "public"
194
+ self.new_tool.public_name = None
195
+ with self.assertRaises(APIError) as exception:
196
+ self.__create_tool(automatic_publish=auto_publish)
197
+ self.assertIn(
198
+ "Tool publicName is required for tools with accessScope=public.",
199
+ str(exception.exception),
200
+ f"Expected an error about missing publicName for public access scope with autopublish {'enabled' if auto_publish else 'disabled'}"
201
+ )
202
+
203
+
204
+ def test_create_tool_invalid_public_name(self):
205
+ test_params = [ True, False ]
206
+
207
+ for auto_publish in test_params:
208
+ with self.subTest(input=auto_publish):
209
+ self.new_tool.access_scope = "public"
210
+ self.new_tool.public_name = "com.sdk.testing#" # Add invalid character to public name
211
+ with self.assertRaises(APIError) as exception:
212
+ self.__create_tool(automatic_publish=auto_publish)
213
+
214
+ self.assertIn(
215
+ "Invalid public name, it can only contain lowercase letters, numbers, periods (.), dashes (-), and underscores (_). Please remove any other characters.",
216
+ str(exception.exception),
217
+ f"The expected error about invalid publicName was not returned when autopublish is {'enabled' if auto_publish else 'disabled'}"
218
+ )
219
+
220
+
221
+ def test_create_tool_duplicated_public_name(self):
222
+ test_params = [ True, False ]
223
+
224
+ # Set the scope as public and assign a public name
225
+ self.new_tool.access_scope = "public"
226
+ self.new_tool.public_name=f"public_{self.new_tool.name}"
227
+ self.created_tool = self.__create_tool()
228
+
229
+ for auto_publish in test_params:
230
+ with self.subTest(input=auto_publish):
231
+
232
+ # Create a new with the same public name of created_tool
233
+ duplicated_pn_tool = self.__load_tool()
234
+ duplicated_pn_tool.access_scope = "public"
235
+ duplicated_pn_tool.public_name = self.created_tool.public_name
236
+
237
+ with self.assertRaises(APIError) as exception:
238
+ self.__create_tool(tool=duplicated_pn_tool, automatic_publish=auto_publish)
239
+ self.assertIn(
240
+ f"Tool already exists [publicName={self.created_tool.public_name}].",
241
+ str(exception.exception),
242
+ f"Expected an error about the duplicated public name when autopublish is {'enabled' if auto_publish else 'disabled'}"
243
+ )
244
+
245
+
246
+ def test_create_tool_api_scope_with_no_open_api(self):
247
+ self.new_tool.scope = "api"
248
+ with self.assertRaises(ValueError) as exception:
249
+ self.new_tool.openApi = ""
250
+ self.assertIn(
251
+ '"Tool" object has no field "openApi"',
252
+ str(exception.exception),
253
+ "Expected a validation error when openApi is not provided for api scope"
254
+ )
255
+
256
+
257
+ def test_create_tool_api_scope_with_no_open_api_json(self):
258
+ self.new_tool.scope = "api"
259
+ with self.assertRaises(ValueError) as exception:
260
+ self.new_tool.openApiJson = ""
261
+
262
+ self.assertIn(
263
+ '"Tool" object has no field "openApiJson"',
264
+ str(exception.exception),
265
+ "Expected a validation error when openApiJson is not provided for api scope"
266
+ )
267
+
268
+
269
+ def test_create_tool_invalid_scope(self):
270
+ test_params = [ True, False ]
271
+
272
+ for auto_publish in test_params:
273
+ with self.subTest(input=auto_publish):
274
+
275
+ with self.assertRaises(ValueError) as exception:
276
+ self.new_tool.scope = "source"
277
+ self.__create_tool()
278
+ self.assertIn(
279
+ 'Scope must be one of builtin, external, api, proxied',
280
+ str(exception.exception),
281
+ "Expected a validation error about allowed values for instructions"
282
+ )
283
+
284
+
285
+ def test_create_tool_autopublish(self):
286
+ self.created_tool = self.__create_tool(automatic_publish=True)
287
+ self.assertFalse(self.created_tool.is_draft, "Expected the tool to be published automatically")
288
+
289
+
290
+ def test_create_tool_autopublish_private_scope(self):
291
+ self.new_tool.access_scope = "private"
292
+
293
+ self.created_tool = self.__create_tool(automatic_publish=True)
294
+ self.assertFalse(self.created_tool.is_draft, "Expected the tool to be published automatically even with private scope")
@@ -0,0 +1,87 @@
1
+ from unittest import TestCase
2
+ import uuid
3
+ from pygeai.lab.managers import AILabManager
4
+ from pygeai.lab.models import Tool, AgentData, Prompt, LlmConfig, Model
5
+ from pygeai.core.common.exceptions import MissingRequirementException, InvalidAPIResponseException
6
+
7
+ ai_lab_manager: AILabManager
8
+
9
+ class TestAILabDeleteToolIntegration(TestCase):
10
+
11
+ def setUp(self):
12
+ self.ai_lab_manager = AILabManager(alias="beta")
13
+
14
+
15
+ def __create_tool(self):
16
+ """
17
+ Helper to create a tool
18
+ """
19
+ tool = Tool(
20
+ name=str(uuid.uuid4()),
21
+ description="Agent that translates from any language to english.",
22
+ scope="builtin"
23
+ )
24
+
25
+
26
+ return self.ai_lab_manager.create_tool(
27
+ tool=tool
28
+ )
29
+
30
+ def __delete_tool(self, tool_id: str = None, tool_name: str = None):
31
+ return self.ai_lab_manager.delete_tool(tool_id=tool_id, tool_name=tool_name)
32
+
33
+
34
+ def test_delete_tool_by_id(self):
35
+ created_tool = self.__create_tool()
36
+ deleted_tool = self.__delete_tool(tool_id=created_tool.id)
37
+
38
+ self.assertEqual(
39
+ deleted_tool.content,
40
+ "Tool deleted successfully",
41
+ "Expected confirmation message after deletion"
42
+ )
43
+
44
+
45
+ def test_delete_tool_by_name(self):
46
+ created_tool = self.__create_tool()
47
+ deleted_tool = self.__delete_tool(tool_name=created_tool.name)
48
+
49
+ self.assertEqual(
50
+ deleted_tool.content,
51
+ "Tool deleted successfully",
52
+ "Expected confirmation message after deletion"
53
+ )
54
+
55
+
56
+ def test_delete_tool_no_id_nor_name(self):
57
+ with self.assertRaises(MissingRequirementException) as exception:
58
+ self.__delete_tool()
59
+ self.assertIn(
60
+ "Either tool_id or tool_name must be provided",
61
+ str(exception.exception),
62
+ "Expected error message when neither tool_id nor tool_name is provided"
63
+ )
64
+
65
+
66
+ def test_delete_tool_invalid_id_valid_name(self):
67
+ invalid_id = "0026e53d-ea78-4cac-af9f-12650invalid"
68
+ created_tool = self.__create_tool()
69
+ with self.assertRaises(InvalidAPIResponseException) as exception:
70
+ self.__delete_tool(tool_name=created_tool.name, tool_id=invalid_id)
71
+
72
+ self.assertIn(
73
+ f"Tool not found [IdOrName= {invalid_id}].",
74
+ str(exception.exception),
75
+ "Expected error message for valid tool name and invalid tool id"
76
+ )
77
+
78
+
79
+ def test_delete_tool_invalid_name_valid_id(self):
80
+ created_tool = self.__create_tool()
81
+ deleted_tool = self.__delete_tool(tool_id=created_tool.id, tool_name="toolName")
82
+
83
+ self.assertEqual(
84
+ deleted_tool.content,
85
+ "Tool deleted successfully",
86
+ "Expected confirmation message after deletion"
87
+ )
@@ -0,0 +1,91 @@
1
+ from unittest import TestCase
2
+ import unittest
3
+ from pygeai.lab.managers import AILabManager
4
+ from pygeai.lab.models import Tool, FilterSettings
5
+ from pygeai.core.common.exceptions import APIError
6
+ import copy
7
+
8
+ ai_lab_manager: AILabManager
9
+
10
+ class TestAILabGetToolIntegration(TestCase):
11
+
12
+ def setUp(self):
13
+ self.ai_lab_manager = AILabManager(alias="beta")
14
+ self.tool_id = "e3e4d64f-ce52-467e-90a9-aa4d08425e82"
15
+ self.filter_settings = FilterSettings(
16
+ revision="0",
17
+ version="0"
18
+ )
19
+
20
+ def __get_tool(self, tool_id=None, filter_settings: FilterSettings = None):
21
+ return self.ai_lab_manager.get_tool(
22
+ tool_id=self.tool_id if tool_id is None else tool_id,
23
+ filter_settings=self.filter_settings if filter_settings is None else filter_settings
24
+ )
25
+
26
+ def test_get_tool(self):
27
+ tool = self.__get_tool()
28
+ self.assertIsInstance(tool, Tool, "Expected a tool")
29
+
30
+
31
+ @unittest.skip("Skipped: Validate that when no tool_id is provided, the complete tool list is returned")
32
+ def test_get_tool_no_tool_id(self):
33
+ with self.assertRaises(Exception) as context:
34
+ self.__get_tool(tool_id="")
35
+
36
+
37
+ def test_get_tool_invalid_tool_id(self):
38
+ invalid_id = "0026e53d-ea78-4cac-af9f-12650invalid"
39
+ with self.assertRaises(APIError) as context:
40
+ self.__get_tool(tool_id=invalid_id)
41
+ self.assertIn(
42
+ f"Tool not found [IdOrName= {invalid_id}].",
43
+ str(context.exception),
44
+ "Expected an error for invalid tool id"
45
+ )
46
+
47
+
48
+ def test_get_tool_no_revision(self):
49
+ filter_settings = copy.deepcopy(self.filter_settings)
50
+ filter_settings.revision = None
51
+ tool = self.__get_tool(filter_settings=filter_settings)
52
+
53
+ self.assertIsInstance(tool, Tool, "Expected a tool")
54
+ self.assertGreaterEqual(tool.revision, 1, "Expected tool revision to be the latest")
55
+
56
+
57
+ def test_get_tool_by_revision(self):
58
+ filter_settings = copy.deepcopy(self.filter_settings)
59
+ filter_settings.revision = "6"
60
+ tool = self.__get_tool(filter_settings=filter_settings)
61
+
62
+ self.assertEqual(6, tool.revision, "Expected agent revision to be 6")
63
+
64
+
65
+ def test_get_tool_by_earlier_revision(self):
66
+ filter_settings = copy.deepcopy(self.filter_settings)
67
+ filter_settings.revision = "2"
68
+ with self.assertRaises(APIError) as context:
69
+ self.__get_tool(filter_settings=filter_settings)
70
+ self.assertIn(
71
+ f"Requested revision not found [revision={filter_settings.revision}].",
72
+ str(context.exception),
73
+ "Expected an error for revision not found"
74
+ )
75
+
76
+ #TODO: The API is returning the version of the tool, but the sdk does not
77
+ def test_get_tool_no_version(self):
78
+ filter_settings = copy.deepcopy(self.filter_settings)
79
+ filter_settings.version = None
80
+ tool = self.__get_tool(filter_settings=filter_settings)
81
+
82
+ self.assertIsInstance(tool, Tool, "Expected a tool")
83
+
84
+
85
+ #TODO: The API is returning the version of the tool, but the sdk does not
86
+ def test_get_tool_by_version(self):
87
+ filter_settings = copy.deepcopy(self.filter_settings)
88
+ filter_settings.version = "1"
89
+ tool = self.__get_tool(filter_settings=filter_settings)
90
+
91
+ self.assertIsInstance(tool, Tool, "Expected a tool")
@@ -0,0 +1,48 @@
1
+ from pygeai.lab.managers import AILabManager
2
+ from pygeai.lab.models import Agent, AgentData, Prompt, LlmConfig, Model, Sampling, PromptExample, PromptOutput
3
+
4
+ agent = Agent(
5
+ id="f64ba214-152b-4dd4-be0d-2920da415f5d",
6
+ status="active",
7
+ name="Private Translator V25",
8
+ access_scope="private",
9
+ public_name="com.genexus.geai.private_translator#",
10
+ job_description="Translates",
11
+ avatar_image="https://www.shareicon.net/data/128x128/2016/11/09/851442_logo_512x512.png",
12
+ description="Agent that translates from any language to english.",
13
+ is_draft=False,
14
+ is_readonly=False,
15
+ revision=1,
16
+ version=None,
17
+ agent_data=AgentData(
18
+ prompt=Prompt(
19
+ instructions="the user will provide a text, you must return the same text translated to english",
20
+ inputs=["text", "avoid slang indicator"],
21
+ outputs=[
22
+ PromptOutput(key="translated_text", description="translated text, with slang or not depending on the indication. in plain text."),
23
+ PromptOutput(key="summary", description="a summary in the original language of the text to be translated, also in plain text.")
24
+ ],
25
+ examples=[
26
+ PromptExample(input_data="opitiiiis mundo [no-slang]", output='{"translated_text":"hello world","summary":"saludo"}'),
27
+ PromptExample(input_data="esto es una prueba pincheguey [keep-slang]", output='{"translated_text":"this is a test pal","summary":"prueba"}')
28
+ ]
29
+ ),
30
+ llm_config=LlmConfig(
31
+ max_tokens=5000,
32
+ timeout=0,
33
+ sampling=Sampling(temperature=0.5, top_k=0, top_p=0)
34
+ ),
35
+ models=[Model(name="gpt-4-turbo-preview")]
36
+ )
37
+ )
38
+
39
+
40
+ manager = AILabManager()
41
+ result = manager.create_agent(
42
+ agent=agent,
43
+ automatic_publish=False
44
+ )
45
+
46
+
47
+ print(f"Agent: {agent.to_dict()}")
48
+
@@ -0,0 +1,48 @@
1
+ from pygeai.lab.managers import AILabManager
2
+ from pygeai.lab.models import Agent, AgentData, Prompt, LlmConfig, Model, Sampling, PromptExample, PromptOutput
3
+
4
+ agent = Agent(
5
+ id="f64ba214-152b-4dd4-be0d-2920da415f5d",
6
+ status="active",
7
+ name="Private Translator V25",
8
+ access_scope="private",
9
+ public_name="com.genexus.geai.private_translator_25",
10
+ job_description="Translates",
11
+ avatar_image="https://www.shareicon.net/data/128x128/2016/11/09/851442_logo_512x512.png",
12
+ description="Agent that translates from any language to english.",
13
+ is_draft=False,
14
+ is_readonly=False,
15
+ revision=1,
16
+ version=None,
17
+ agent_data=AgentData(
18
+ prompt=Prompt(
19
+ instructions="the user will provide a text, you must return the same text translated to english",
20
+ inputs=["text", "avoid slang indicator"],
21
+ outputs=[
22
+ PromptOutput(key="translated_text", description="translated text, with slang or not depending on the indication. in plain text."),
23
+ PromptOutput(key="summary", description="a summary in the original language of the text to be translated, also in plain text.")
24
+ ],
25
+ examples=[
26
+ PromptExample(input_data="opitiiiis mundo [no-slang]", output='{"translated_text":"hello world","summary":"saludo"}'),
27
+ PromptExample(input_data="esto es una prueba pincheguey [keep-slang]", output='{"translated_text":"this is a test pal","summary":"prueba"}')
28
+ ]
29
+ ),
30
+ llm_config=LlmConfig(
31
+ max_tokens=5000,
32
+ timeout=0,
33
+ sampling=Sampling(temperature=0.5, top_k=0, top_p=0)
34
+ ),
35
+ models=[Model(name="gpt-4-turbo-preview")]
36
+ )
37
+ )
38
+
39
+
40
+ manager = AILabManager()
41
+ result = manager.create_agent(
42
+ agent=agent,
43
+ automatic_publish=False
44
+ )
45
+
46
+
47
+ print(f"Agent: {agent.to_dict()}")
48
+
@@ -0,0 +1,50 @@
1
+ from pygeai.lab.managers import AILabManager
2
+ from pygeai.lab.models import Tool, ToolParameter
3
+
4
+ parameters = [
5
+ ToolParameter(
6
+ key="input",
7
+ data_type="String",
8
+ description="some input that the tool needs.",
9
+ is_required=True
10
+ ),
11
+ ToolParameter(
12
+ key="some_nonsensitive_id",
13
+ data_type="String",
14
+ description="Configuration that is static, in the sense that whenever the tool is used, the value for this parameter is configured here. The llm will not know about it.",
15
+ is_required=True,
16
+ type="config",
17
+ from_secret=False,
18
+ value="b001e30b4016001f5f76b9ae9215ac40"
19
+ ),
20
+ ToolParameter(
21
+ key="api_token",
22
+ data_type="String",
23
+ description="Configuration that is static, but it is sensitive information . The value is stored in secret-manager",
24
+ is_required=True,
25
+ type="config",
26
+ value="0cd84dc7-f3f5-4a03-9288-cdfd8d72fde1"
27
+ )
28
+ ]
29
+
30
+ tool = Tool(
31
+ name="sample_tool_v5",
32
+ access_scope="private",
33
+ public_name="sample.tool.test#",
34
+ description="a builtin tool that does something but really does nothing cos it does not exist.",
35
+ scope="builtin",
36
+ parameters=parameters
37
+ )
38
+
39
+
40
+ manager = AILabManager()
41
+
42
+
43
+ result = manager.create_tool(
44
+ tool=tool,
45
+ automatic_publish=False
46
+ )
47
+
48
+ print(f"Created tool: {result.name}, ID: {result.id}")
49
+ print(f"Description: {result.description}")
50
+ print(f"Messages: {result.messages}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pygeai
3
- Version: 0.4.0b1
3
+ Version: 0.4.0b3
4
4
  Summary: Software Development Kit to interact with Globant Enterprise AI.
5
5
  Author-email: Globant <geai-sdk@globant.com>
6
6
  License-Expression: MIT
@@ -144,7 +144,7 @@ pygeai/health/endpoints.py,sha256=UAzMcqSXZtMj4r8M8B7a_a5LT6X_jMFNsCTvcsjNTYA,71
144
144
  pygeai/lab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
145
145
  pygeai/lab/constants.py,sha256=ddgDnXP4GD0woi-FUJaJXzaWS3H6zmDN0B-v8utM95Q,170
146
146
  pygeai/lab/managers.py,sha256=9wV6SipzsIwFP9SXsKqZ0X5x6KbUuo6iCxPZF4zNGj4,72714
147
- pygeai/lab/models.py,sha256=uxhmogA0234eXXmqsVRE7EQQsmqx_BBHYXjhWkKso40,71386
147
+ pygeai/lab/models.py,sha256=djbSMdm95kgnqsgohfXTSybylFp_jevMj6SoWuU_P9A,71440
148
148
  pygeai/lab/runners.py,sha256=-uaCPHpFyiKtVOxlEjPjAc9h-onSdGAcYJ5IAZPqlb0,4147
149
149
  pygeai/lab/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
150
150
  pygeai/lab/agents/clients.py,sha256=2SYNjyD9LZaOUxmTcrwzqcHwW7K1wAmYwen_u0G-RfU,22659
@@ -170,7 +170,7 @@ pygeai/man/man1/__init__.py,sha256=CFvES6cP_sbhgpm-I-QSbPC1f7Bw7cFsMW2-sxm4FtM,5
170
170
  pygeai/man/man1/geai-proxy.1,sha256=N5jtjzS5dB3JjAkG0Rw8EBzhC6Jgoy6zbS7XDgcE4EA,6735
171
171
  pygeai/man/man1/geai.1,sha256=dRJjqXLu4PRr5tELX-TveOrvp-J085rTV0NbqL5I30Q,51162
172
172
  pygeai/migration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
173
- pygeai/migration/strategies.py,sha256=fedXqdtnAY57eeMI3RP5KhkjzVtYD654G51pMJb41fw,10041
173
+ pygeai/migration/strategies.py,sha256=fNTPuAPrGPxjbQN6zQn7qaVHksft_rC8doADdUw1LWQ,9785
174
174
  pygeai/migration/tools.py,sha256=DuBWwS72VxXF2b95aw89u0aLBjHP1UhD5GBlUtuG8nA,321
175
175
  pygeai/organization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
176
176
  pygeai/organization/clients.py,sha256=O9RMeFm8gm5e6OoJl2y3JTS_MUZEp2Twc8AOpsUTj4M,10073
@@ -277,6 +277,10 @@ pygeai/tests/integration/lab/agents/test_delete_agent.py,sha256=sb3RfoZJdzQvcVdN
277
277
  pygeai/tests/integration/lab/agents/test_get_agent.py,sha256=oW1F6SENvhL9jZC021Rj-f_Xek2DSTx3SsZBr3YT6Hk,3666
278
278
  pygeai/tests/integration/lab/agents/test_publish_agent_revision.py,sha256=4vpuAVBenLCyWvaKTA2PQVLn_e-abGDscngUzZm3dMs,5284
279
279
  pygeai/tests/integration/lab/agents/test_update_agent.py,sha256=vme9TJij46U55oOvUYGdKRyzZn-UKzXXYGJH0-zCeRs,11959
280
+ pygeai/tests/integration/lab/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
281
+ pygeai/tests/integration/lab/tools/test_create_tool.py,sha256=QjJT_L47wwl8_GcqIRCMgDiF817rADHBgY-xPO3omd0,12519
282
+ pygeai/tests/integration/lab/tools/test_delete_tool.py,sha256=wy979nZh8ERd-k3jhJTjHqG4wxWE4sx-r4yn2nBc7Aw,2913
283
+ pygeai/tests/integration/lab/tools/test_get_tool.py,sha256=3fVDQlklmvOUgYDp0ATv5RqRmApgD4Qw_YGqjBOaOOo,3437
280
284
  pygeai/tests/lab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
281
285
  pygeai/tests/lab/test_managers.py,sha256=AsOAvyCkRpbskEy214aV2TwrqilWH6bxOiTWDOb1twQ,29778
282
286
  pygeai/tests/lab/test_mappers.py,sha256=2cLSggf168XWFpeZeBR7uJ-8C32TKb7qA91i_9fr_b0,11409
@@ -368,6 +372,8 @@ pygeai/tests/snippets/lab/runner_1.py,sha256=QD92MvC22wpWj6YyrSgpp46EcL0ciac2x1z
368
372
  pygeai/tests/snippets/lab/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
369
373
  pygeai/tests/snippets/lab/agents/create_agent.py,sha256=EVyfQzDST9A9KaM0ToZJKlJ7yCbfhpSVkVK_MaUVQPw,1875
370
374
  pygeai/tests/snippets/lab/agents/create_agent_2.py,sha256=jd7HKhle_c0S0vI80AejOyLaNqBWkILlRF_znzyCGcQ,1879
375
+ pygeai/tests/snippets/lab/agents/create_agent_edge_case.py,sha256=8dA9giNdsHjFZsIWTlBFk8e1QS3YtbZxklsVu0ZrDrk,1877
376
+ pygeai/tests/snippets/lab/agents/create_agent_without_instructions.py,sha256=jd7HKhle_c0S0vI80AejOyLaNqBWkILlRF_znzyCGcQ,1879
371
377
  pygeai/tests/snippets/lab/agents/delete_agent.py,sha256=GfDX667_V3tZMz3vjsbrxoFZggzpwjZYH_PVO2Qjw5s,269
372
378
  pygeai/tests/snippets/lab/agents/get_agent.py,sha256=bcqloJHwmNsFjEfri6QIRaTuHzwLtfEqIQPIC5pdkWQ,516
373
379
  pygeai/tests/snippets/lab/agents/get_sharing_link.py,sha256=2mYPwMgFFbqzmWZEBrFYSjdZscVyjJYCs4A3L0x8Sr8,355
@@ -394,6 +400,7 @@ pygeai/tests/snippets/lab/strategies/list_reasoning_strategies.py,sha256=4pqsW16
394
400
  pygeai/tests/snippets/lab/strategies/update_reasoning_strategy.py,sha256=OIoHNkdnXbC9GacPgXUG1jKlVizVtWfRI-E8_3xF5b0,889
395
401
  pygeai/tests/snippets/lab/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
396
402
  pygeai/tests/snippets/lab/tools/create_tool.py,sha256=dreldR8QIu9Q9tjOG2hkD6b8KZa_VrwSfSnCrzPgQLA,1400
403
+ pygeai/tests/snippets/lab/tools/create_tool_edge_case.py,sha256=8w4mvoRTMTyc70yYm2bgV2dr_Rh5QpPJR8VoqX-eY-s,1465
397
404
  pygeai/tests/snippets/lab/tools/delete_tool.py,sha256=pnIkYvdP7X7Gx79AMK5MSVliIXdHSpyVwRhH3kgi7ys,452
398
405
  pygeai/tests/snippets/lab/tools/get_parameter.py,sha256=dXdlHhoWxzZIYdsvHKnLLT5Vff2Tip46XCoOo-B8Gf0,490
399
406
  pygeai/tests/snippets/lab/tools/get_tool.py,sha256=-fkKAE6nflwtLY_Lf6itZJyx_9aanFp-TSDHUzub1AM,477
@@ -482,9 +489,9 @@ pygeai/vendor/a2a/utils/helpers.py,sha256=6Tbd8SVfXvdNEk6WYmLOjrAxkzFf1aIg8dkFfB
482
489
  pygeai/vendor/a2a/utils/message.py,sha256=gc_EKO69CJ4HkR76IFgsy-kENJz1dn7CfSgWJWvt-gs,2197
483
490
  pygeai/vendor/a2a/utils/task.py,sha256=BYRA_L1HpoUGJAVlyHML0lCM9Awhf2Ovjj7oPFXKbh0,1647
484
491
  pygeai/vendor/a2a/utils/telemetry.py,sha256=VvSp1Ztqaobkmq9-3sNhhPEilJS32-JTSfKzegkj6FU,10861
485
- pygeai-0.4.0b1.dist-info/licenses/LICENSE,sha256=eHfqo7-AWS8cMq0cg03lq7owsLeCmZA-xS5L0kuHnl8,1474
486
- pygeai-0.4.0b1.dist-info/METADATA,sha256=7t753dmdmoBFILz_q2iiOFD3VWBzTOfPOXqtyr4HUSA,6882
487
- pygeai-0.4.0b1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
488
- pygeai-0.4.0b1.dist-info/entry_points.txt,sha256=OAmwuXVCQBTCE3HeVegVd37hbhCcp9TPahvdrCuMYWw,178
489
- pygeai-0.4.0b1.dist-info/top_level.txt,sha256=bJFwp2tURmCfB94yXDF7ylvdSJXFDDJsyUOb-7PJgwc,7
490
- pygeai-0.4.0b1.dist-info/RECORD,,
492
+ pygeai-0.4.0b3.dist-info/licenses/LICENSE,sha256=eHfqo7-AWS8cMq0cg03lq7owsLeCmZA-xS5L0kuHnl8,1474
493
+ pygeai-0.4.0b3.dist-info/METADATA,sha256=lq_Zxuj3ryFc5mcZrxNp29ohgxV_qOBtyQJqPWumxWk,6882
494
+ pygeai-0.4.0b3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
495
+ pygeai-0.4.0b3.dist-info/entry_points.txt,sha256=OAmwuXVCQBTCE3HeVegVd37hbhCcp9TPahvdrCuMYWw,178
496
+ pygeai-0.4.0b3.dist-info/top_level.txt,sha256=bJFwp2tURmCfB94yXDF7ylvdSJXFDDJsyUOb-7PJgwc,7
497
+ pygeai-0.4.0b3.dist-info/RECORD,,