pygeai 0.3.2__py3-none-any.whl → 0.4.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 (45) hide show
  1. pygeai/__init__.py +1 -1
  2. pygeai/chat/ui.py +0 -1
  3. pygeai/cli/__init__.py +1 -1
  4. pygeai/cli/commands/chat.py +54 -56
  5. pygeai/cli/commands/lab/ai_lab.py +129 -466
  6. pygeai/cli/commands/lab/options.py +8 -0
  7. pygeai/cli/commands/lab/utils.py +13 -0
  8. pygeai/cli/geai.py +5 -2
  9. pygeai/cli/texts/help.py +12 -0
  10. pygeai/core/common/config.py +0 -2
  11. pygeai/core/common/exceptions.py +6 -0
  12. pygeai/lab/agents/clients.py +30 -61
  13. pygeai/lab/clients.py +20 -0
  14. pygeai/lab/managers.py +6 -58
  15. pygeai/lab/processes/clients.py +81 -129
  16. pygeai/lab/strategies/clients.py +11 -17
  17. pygeai/lab/tools/clients.py +59 -59
  18. pygeai/tests/integration/assistants/__init__.py +0 -0
  19. pygeai/tests/integration/assistants/rag/__init__.py +0 -0
  20. pygeai/tests/integration/assistants/rag/test_create_rag.py +72 -0
  21. pygeai/tests/integration/chat/__init__.py +0 -0
  22. pygeai/tests/integration/chat/test_generate_image.py +162 -0
  23. pygeai/tests/integration/lab/agents/test_create_agent.py +9 -13
  24. pygeai/tests/integration/lab/agents/test_publish_agent_revision.py +0 -1
  25. pygeai/tests/integration/lab/agents/test_update_agent.py +6 -15
  26. pygeai/tests/integration/lab/tools/__init__.py +0 -0
  27. pygeai/tests/integration/lab/tools/test_create_tool.py +292 -0
  28. pygeai/tests/integration/lab/tools/test_delete_tool.py +87 -0
  29. pygeai/tests/integration/lab/tools/test_get_parameter.py +98 -0
  30. pygeai/tests/integration/lab/tools/test_get_tool.py +91 -0
  31. pygeai/tests/integration/lab/tools/test_list_tools.py +106 -0
  32. pygeai/tests/integration/lab/tools/test_publish_tool_revision.py +119 -0
  33. pygeai/tests/integration/lab/tools/test_set_parameter.py +114 -0
  34. pygeai/tests/integration/lab/tools/test_update_tool.py +268 -0
  35. pygeai/tests/snippets/lab/agents/create_agent_edge_case.py +48 -0
  36. pygeai/tests/snippets/lab/agents/create_agent_without_instructions.py +48 -0
  37. pygeai/tests/snippets/lab/agents/get_sharing_link.py +1 -2
  38. pygeai/tests/snippets/lab/tools/create_tool.py +1 -1
  39. pygeai/tests/snippets/lab/tools/create_tool_edge_case.py +50 -0
  40. {pygeai-0.3.2.dist-info → pygeai-0.4.0.dist-info}/METADATA +1 -1
  41. {pygeai-0.3.2.dist-info → pygeai-0.4.0.dist-info}/RECORD +45 -25
  42. {pygeai-0.3.2.dist-info → pygeai-0.4.0.dist-info}/WHEEL +0 -0
  43. {pygeai-0.3.2.dist-info → pygeai-0.4.0.dist-info}/entry_points.txt +0 -0
  44. {pygeai-0.3.2.dist-info → pygeai-0.4.0.dist-info}/licenses/LICENSE +0 -0
  45. {pygeai-0.3.2.dist-info → pygeai-0.4.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,8 @@
1
+ from pygeai.cli.commands import Option
2
+
3
+ PROJECT_ID_OPTION = Option(
4
+ "project_id",
5
+ ["--project-id", "--pid"],
6
+ "GUID of the project (optional)",
7
+ True
8
+ )
@@ -0,0 +1,13 @@
1
+ from pygeai import logger
2
+ from pygeai.admin.clients import AdminClient
3
+ from pygeai.core.common.exceptions import APIError
4
+
5
+
6
+ def get_project_id():
7
+ response = None
8
+ try:
9
+ response = AdminClient().validate_api_token()
10
+ return response.get("projectId")
11
+ except Exception as e:
12
+ logger.error(f"Error retrieving project_id from GEAI. Response: {response}: {e}")
13
+ raise APIError(f"Error retrieving project_id from GEAI: {e}")
pygeai/cli/geai.py CHANGED
@@ -6,7 +6,8 @@ from pygeai.cli.commands import ArgumentsEnum, Command
6
6
  from pygeai.cli.parsers import CommandParser
7
7
  from pygeai.cli.texts.help import CLI_USAGE
8
8
  from pygeai.core.base.session import get_session
9
- from pygeai.core.common.exceptions import UnknownArgumentError, MissingRequirementException, WrongArgumentError
9
+ from pygeai.core.common.exceptions import UnknownArgumentError, MissingRequirementException, WrongArgumentError, \
10
+ InvalidAgentException
10
11
  from pygeai.core.utils.console import Console
11
12
 
12
13
 
@@ -69,10 +70,12 @@ class CLIDriver:
69
70
  Console.write_stderr()
70
71
  except MissingRequirementException as e:
71
72
  Console.write_stderr(f"ERROR: Something is missing! \nDetail: {e}")
73
+ except InvalidAgentException as e:
74
+ Console.write_stderr(f"ERROR: There was an error retrieving the agent. \nDetail: {e}")
72
75
  except KeyboardInterrupt:
73
76
  Console.write_stdout()
74
77
  except Exception as e:
75
- Console.write_stderr(f"Unexpected error. Please report this bug to the developers. Error: {e}")
78
+ Console.write_stderr(f"CRITICAL: There has ben an unexpected error. Please report this bug to geai-sdk@globant.com. Error: {e}")
76
79
  return 255
77
80
 
78
81
  def process_command(self, command: Command, arguments: list[str]):
pygeai/cli/texts/help.py CHANGED
@@ -214,6 +214,18 @@ SYNOPSIS
214
214
  DESCRIPTION
215
215
  geai chat is a command from geai cli utility, developed to chat with assistant in GEAI.
216
216
 
217
+ The model needs to specify an assistant_type and a specific_parameter whose format depends on that type. Its format is as follows:
218
+
219
+ "model": "saia:<assistant_type>:<specific_parameter>"
220
+
221
+ assistant_type can be:
222
+ - agent: Identifies a Agent.
223
+ - flow: Identifies a Flow.
224
+ - assistant: Identifies an Assistant API, Data Analyst Assistant, Chat with Data Assistant and API Assistant.
225
+ - search: Identifies a RAG Assistant.
226
+
227
+ For more information, refer to the GEAI Wiki: https://wiki.genexus.com/enterprise-ai/wiki?34,Chat+API
228
+
217
229
  The options are as follows:
218
230
  {{available_commands}}
219
231
 
@@ -114,9 +114,7 @@ def get_settings():
114
114
 
115
115
  if __name__ == "__main__":
116
116
  settings = get_settings()
117
- geai_api_key = settings.get_api_key()
118
117
  geai_base_url = settings.get_base_url()
119
118
  geai_eval_url = settings.get_eval_url()
120
- print(f"api_key: {geai_api_key}")
121
119
  print(f"base_url: {geai_base_url}")
122
120
  print(f"eval_url: {geai_eval_url}")
@@ -50,5 +50,11 @@ class InvalidResponseException(GEAIException):
50
50
  pass
51
51
 
52
52
 
53
+ class InvalidAgentException(GEAIException):
54
+ """There was an error getting a response from the server"""
55
+ pass
53
56
 
54
57
 
58
+ class APIResponseError(GEAIException):
59
+ pass
60
+
@@ -2,18 +2,17 @@ from json import JSONDecodeError
2
2
  from typing import Optional, List, Dict
3
3
 
4
4
  from pygeai import logger
5
- from pygeai.core.base.clients import BaseClient
6
5
  from pygeai.core.common.exceptions import MissingRequirementException, InvalidAPIResponseException
7
6
  from pygeai.lab.agents.endpoints import CREATE_AGENT_V2, LIST_AGENTS_V2, GET_AGENT_V2, CREATE_SHARING_LINK_V2, \
8
7
  PUBLISH_AGENT_REVISION_V2, DELETE_AGENT_V2, UPDATE_AGENT_V2, UPSERT_AGENT_V2, EXPORT_AGENT_V2, IMPORT_AGENT_V2
9
8
  from pygeai.lab.constants import VALID_ACCESS_SCOPES
9
+ from pygeai.lab.clients import AILabClient
10
10
 
11
11
 
12
- class AgentClient(BaseClient):
12
+ class AgentClient(AILabClient):
13
13
 
14
14
  def list_agents(
15
15
  self,
16
- project_id: str,
17
16
  status: str = "",
18
17
  start: int = "",
19
18
  count: int = "",
@@ -24,7 +23,6 @@ class AgentClient(BaseClient):
24
23
  """
25
24
  Retrieves a list of agents associated with the specified project.
26
25
 
27
- :param project_id: str - Unique identifier of the project to query agents from.
28
26
  :param status: str, optional - Filter agents by status (e.g., "active", "draft"). Defaults to "" (no filtering).
29
27
  :param start: int, optional - Starting index for pagination. Defaults to "" (no offset).
30
28
  :param count: int, optional - Maximum number of agents to retrieve. Defaults to "" (no limit).
@@ -37,10 +35,10 @@ class AgentClient(BaseClient):
37
35
  endpoint = LIST_AGENTS_V2
38
36
  headers = {
39
37
  "Authorization": self.api_service.token,
40
- "ProjectId": project_id
38
+ "ProjectId": self.project_id
41
39
  }
42
40
 
43
- logger.debug(f"Listing agents for project with ID {project_id}")
41
+ logger.debug(f"Listing agents for project with ID {self.project_id}")
44
42
 
45
43
  response = self.api_service.get(
46
44
  endpoint=endpoint,
@@ -57,14 +55,13 @@ class AgentClient(BaseClient):
57
55
  try:
58
56
  result = response.json()
59
57
  except JSONDecodeError as e:
60
- logger.error(f"Unable to list agents for project {project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
61
- raise InvalidAPIResponseException(f"Unable to list agents for project {project_id}: {response.text}")
58
+ logger.error(f"Unable to list agents for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
59
+ raise InvalidAPIResponseException(f"Unable to list agents for project {self.project_id}: {response.text}")
62
60
 
63
61
  return result
64
62
 
65
63
  def create_agent(
66
64
  self,
67
- project_id: str,
68
65
  name: str,
69
66
  access_scope: str,
70
67
  public_name: str,
@@ -81,7 +78,6 @@ class AgentClient(BaseClient):
81
78
  """
82
79
  Creates a new agent in the specified project.
83
80
 
84
- :param project_id: str - Unique identifier of the project where the agent will be created.
85
81
  :param name: str - Name of the agent (must be unique within the project, non-empty, and exclude ':' or '/').
86
82
  :param access_scope: str - Access scope of the agent ("public" or "private").
87
83
  :param public_name: str - Public name for the agent, required if access_scope is "public" (must follow domain/library convention, e.g., 'com.example.my-agent').
@@ -134,7 +130,7 @@ class AgentClient(BaseClient):
134
130
 
135
131
  headers = {
136
132
  "Authorization": self.api_service.token,
137
- "ProjectId": project_id
133
+ "ProjectId": self.project_id
138
134
  }
139
135
 
140
136
  response = self.api_service.post(
@@ -146,14 +142,13 @@ class AgentClient(BaseClient):
146
142
  try:
147
143
  result = response.json()
148
144
  except JSONDecodeError as e:
149
- logger.error(f"Unable to create agent for project {project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
150
- raise InvalidAPIResponseException(f"Unable to create agent for project {project_id}: {response.text}")
145
+ logger.error(f"Unable to create agent for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
146
+ raise InvalidAPIResponseException(f"Unable to create agent for project {self.project_id}: {response.text}")
151
147
 
152
148
  return result
153
149
 
154
150
  def get_agent(
155
151
  self,
156
- project_id: str,
157
152
  agent_id: str,
158
153
  revision: str = 0,
159
154
  version: int = 0,
@@ -162,7 +157,6 @@ class AgentClient(BaseClient):
162
157
  """
163
158
  Retrieves details of a specific agent from the specified project.
164
159
 
165
- :param project_id: str - Unique identifier of the project containing the agent.
166
160
  :param agent_id: str - Unique identifier of the agent to retrieve.
167
161
  :param revision: str, optional - Specific revision of the agent to retrieve (default: 0, latest revision).
168
162
  :param version: int, optional - Specific version of the agent to retrieve (default: 0, latest version).
@@ -171,16 +165,13 @@ class AgentClient(BaseClient):
171
165
  :raises InvalidAPIResponseException: If the response cannot be parsed as JSON or an error occurs.
172
166
  :raises MissingRequirementException: If project_id or agent_id is not provided.
173
167
  """
174
- if not project_id:
175
- raise MissingRequirementException("Cannot retrieve agent without specifying project_id")
176
-
177
168
  if not agent_id:
178
169
  raise MissingRequirementException("agent_id must be specified in order to retrieve the agent")
179
170
 
180
171
  endpoint = GET_AGENT_V2.format(agentId=agent_id)
181
172
  headers = {
182
173
  "Authorization": self.api_service.token,
183
- "ProjectId": project_id
174
+ "ProjectId": self.project_id
184
175
  }
185
176
 
186
177
  logger.debug(f"Retrieving agent detail with ID {agent_id}")
@@ -197,36 +188,30 @@ class AgentClient(BaseClient):
197
188
  try:
198
189
  result = response.json()
199
190
  except JSONDecodeError as e:
200
- logger.error(f"Unable to retrieve agent {agent_id} for project {project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
201
- raise InvalidAPIResponseException(f"Unable to retrieve agent {agent_id} for project {project_id}: {response.text}")
191
+ logger.error(f"Unable to retrieve agent {agent_id} for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
192
+ raise InvalidAPIResponseException(f"Unable to retrieve agent {agent_id} for project {self.project_id}: {response.text}")
202
193
 
203
194
  return result
204
195
 
205
196
  def create_sharing_link(
206
197
  self,
207
- project_id: str,
208
198
  agent_id: str,
209
199
  ) -> dict:
210
200
  """
211
201
  Creates a sharing link for a specific agent in the specified project.
212
202
 
213
- :param project_id: str - Unique identifier of the project containing the agent.
214
203
  :param agent_id: str - Unique identifier of the agent for which to create a sharing link.
215
204
  :return: dict - JSON response containing the sharing link details.
216
205
  :raises InvalidAPIResponseException: If the response cannot be parsed as JSON or an error occurs.
217
206
  :raises MissingRequirementException: If project_id or agent_id is not provided.
218
207
  """
219
- if not project_id:
220
- raise MissingRequirementException("Cannot create sharing link without specifying project_id")
221
-
222
208
  if not agent_id:
223
209
  raise MissingRequirementException("agent_id must be specified in order to create sharing link")
224
210
 
225
-
226
211
  endpoint = CREATE_SHARING_LINK_V2.format(agentId=agent_id)
227
212
  headers = {
228
213
  "Authorization": self.api_service.token,
229
- "ProjectId": project_id
214
+ "ProjectId": self.project_id
230
215
  }
231
216
 
232
217
  logger.debug(f"Creating sharing link for agent with ID {agent_id}")
@@ -239,21 +224,19 @@ class AgentClient(BaseClient):
239
224
  try:
240
225
  result = response.json()
241
226
  except JSONDecodeError as e:
242
- logger.error(f"Unable to create sharing link for agent {agent_id} in project {project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
243
- raise InvalidAPIResponseException(f"Unable to create sharing link for agent {agent_id} in project {project_id}: {response.text}")
227
+ logger.error(f"Unable to create sharing link for agent {agent_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
228
+ raise InvalidAPIResponseException(f"Unable to create sharing link for agent {agent_id} in project {self.project_id}: {response.text}")
244
229
 
245
230
  return result
246
231
 
247
232
  def publish_agent_revision(
248
233
  self,
249
- project_id: str,
250
234
  agent_id: str,
251
235
  revision: str
252
236
  ) -> dict:
253
237
  """
254
238
  Publishes a specific revision of an agent in the specified project.
255
239
 
256
- :param project_id: str - Unique identifier of the project containing the agent.
257
240
  :param agent_id: str - Unique identifier of the agent to publish.
258
241
  :param revision: str - Revision of the agent to publish.
259
242
  :return: dict - JSON response containing the result of the publish operation.
@@ -262,7 +245,7 @@ class AgentClient(BaseClient):
262
245
  endpoint = PUBLISH_AGENT_REVISION_V2.format(agentId=agent_id)
263
246
  headers = {
264
247
  "Authorization": self.api_service.token,
265
- "ProjectId": project_id
248
+ "ProjectId": self.project_id
266
249
  }
267
250
 
268
251
  logger.debug(f"Publishing revision {revision} for agent with ID {agent_id}")
@@ -277,20 +260,18 @@ class AgentClient(BaseClient):
277
260
  try:
278
261
  result = response.json()
279
262
  except JSONDecodeError as e:
280
- logger.error(f"Unable to publish revision {revision} for agent {agent_id} in project {project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
281
- raise InvalidAPIResponseException(f"Unable to publish revision {revision} for agent {agent_id} in project {project_id}: {response.text}")
263
+ logger.error(f"Unable to publish revision {revision} for agent {agent_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
264
+ raise InvalidAPIResponseException(f"Unable to publish revision {revision} for agent {agent_id} in project {self.project_id}: {response.text}")
282
265
 
283
266
  return result
284
267
 
285
268
  def delete_agent(
286
269
  self,
287
- project_id: str,
288
270
  agent_id: str,
289
271
  ) -> dict:
290
272
  """
291
273
  Deletes a specific agent from the specified project.
292
274
 
293
- :param project_id: str - Unique identifier of the project containing the agent.
294
275
  :param agent_id: str - Unique identifier of the agent to delete.
295
276
  :return: dict - JSON response confirming the deletion.
296
277
  :raises InvalidAPIResponseException: If the response cannot be parsed as JSON or an error occurs.
@@ -298,7 +279,7 @@ class AgentClient(BaseClient):
298
279
  endpoint = DELETE_AGENT_V2.format(agentId=agent_id)
299
280
  headers = {
300
281
  "Authorization": self.api_service.token,
301
- "ProjectId": project_id
282
+ "ProjectId": self.project_id
302
283
  }
303
284
 
304
285
  logger.debug(f"Deleting agent with ID {agent_id}")
@@ -309,14 +290,13 @@ class AgentClient(BaseClient):
309
290
  data={}
310
291
  )
311
292
  if response.status_code != 204:
312
- logger.error(f"Unable to delete agent {agent_id} from project {project_id}: JSON parsing error (status {response.status_code}). Response: {response.text}")
313
- raise InvalidAPIResponseException(f"Unable to delete agent {agent_id} from project {project_id}: {response.text}")
293
+ logger.error(f"Unable to delete agent {agent_id} from project {self.project_id}: JSON parsing error (status {response.status_code}). Response: {response.text}")
294
+ raise InvalidAPIResponseException(f"Unable to delete agent {agent_id} from project {self.project_id}: {response.text}")
314
295
  else:
315
296
  return {}
316
297
 
317
298
  def update_agent(
318
299
  self,
319
- project_id: str,
320
300
  agent_id: str,
321
301
  name: str,
322
302
  access_scope: str,
@@ -335,7 +315,6 @@ class AgentClient(BaseClient):
335
315
  """
336
316
  Updates an existing agent in the specified project or upserts it if specified.
337
317
 
338
- :param project_id: str - Unique identifier of the project containing the agent.
339
318
  :param agent_id: str - Unique identifier of the agent to update (required for updates).
340
319
  :param name: str - Updated name of the agent (must be unique, non-empty, exclude ':' or '/'; optional).
341
320
  :param access_scope: str - Updated access scope ("public" or "private").
@@ -393,7 +372,7 @@ class AgentClient(BaseClient):
393
372
 
394
373
  headers = {
395
374
  "Authorization": self.api_service.token,
396
- "ProjectId": project_id
375
+ "ProjectId": self.project_id
397
376
  }
398
377
 
399
378
  response = self.api_service.put(
@@ -405,35 +384,30 @@ class AgentClient(BaseClient):
405
384
  try:
406
385
  result = response.json()
407
386
  except JSONDecodeError as e:
408
- logger.error(f"Unable to update agent {agent_id} in project {project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
409
- raise InvalidAPIResponseException(f"Unable to update agent {agent_id} in project {project_id}: {response.text}")
387
+ logger.error(f"Unable to update agent {agent_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
388
+ raise InvalidAPIResponseException(f"Unable to update agent {agent_id} in project {self.project_id}: {response.text}")
410
389
 
411
390
  return result
412
391
 
413
392
  def export_agent(
414
393
  self,
415
- project_id: str,
416
394
  agent_id: str,
417
395
  ) -> dict:
418
396
  """
419
397
  Retrieves details of a specific agent from the specified project.
420
398
 
421
- :param project_id: str - Unique identifier of the project containing the agent.
422
399
  :param agent_id: str - Unique identifier of the agent to retrieve.
423
400
  :return: dict - JSON response containing the agent details.
424
401
  :raises InvalidAPIResponseException: If the response cannot be parsed as JSON or an error occurs.
425
402
  :raises MissingRequirementException: If project_id or agent_id is not provided.
426
403
  """
427
- if not project_id:
428
- raise MissingRequirementException("Cannot export agent without specifying project_id")
429
-
430
404
  if not agent_id:
431
405
  raise MissingRequirementException("agent_id must be specified in order to export the agent")
432
406
 
433
407
  endpoint = EXPORT_AGENT_V2.format(agentId=agent_id)
434
408
  headers = {
435
409
  "Authorization": self.api_service.token,
436
- "ProjectId": project_id
410
+ "ProjectId": self.project_id
437
411
  }
438
412
 
439
413
  logger.debug(f"Exporting agent with ID {agent_id}")
@@ -445,35 +419,30 @@ class AgentClient(BaseClient):
445
419
  try:
446
420
  result = response.json()
447
421
  except JSONDecodeError as e:
448
- logger.error(f"Unable to export agent {agent_id} for project {project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
449
- raise InvalidAPIResponseException(f"Unable to export agent {agent_id} for project {project_id}: {response.text}")
422
+ logger.error(f"Unable to export agent {agent_id} for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
423
+ raise InvalidAPIResponseException(f"Unable to export agent {agent_id} for project {self.project_id}: {response.text}")
450
424
 
451
425
  return result
452
426
 
453
427
  def import_agent(
454
428
  self,
455
- project_id: str,
456
429
  data: dict,
457
430
  ) -> dict:
458
431
  """
459
432
  Retrieves details of a specific agent from the specified project.
460
433
 
461
- :param project_id: str - Unique identifier of the project containing the agent.
462
434
  :param data: dict - Agent specification to import
463
435
  :return: dict - JSON response containing the agent details.
464
436
  :raises InvalidAPIResponseException: If the response cannot be parsed as JSON or an error occurs.
465
437
  :raises MissingRequirementException: If project_id or agent_id is not provided.
466
438
  """
467
- if not project_id:
468
- raise MissingRequirementException("Cannot import agent without specifying project_id")
469
-
470
439
  if not data:
471
440
  raise MissingRequirementException("data for spec must be specified in order to import the agent")
472
441
 
473
442
  endpoint = IMPORT_AGENT_V2
474
443
  headers = {
475
444
  "Authorization": self.api_service.token,
476
- "ProjectId": project_id
445
+ "ProjectId": self.project_id
477
446
  }
478
447
 
479
448
  response = self.api_service.post(
@@ -484,7 +453,7 @@ class AgentClient(BaseClient):
484
453
  try:
485
454
  result = response.json()
486
455
  except JSONDecodeError as e:
487
- logger.error(f"Unable to import agent for project {project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
488
- raise InvalidAPIResponseException(f"Unable to import agent for project {project_id}: {response.text}")
456
+ logger.error(f"Unable to import agent for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
457
+ raise InvalidAPIResponseException(f"Unable to import agent for project {self.project_id}: {response.text}")
489
458
 
490
459
  return result
pygeai/lab/clients.py ADDED
@@ -0,0 +1,20 @@
1
+ from pygeai import logger
2
+ from pygeai.admin.clients import AdminClient
3
+ from pygeai.core.base.clients import BaseClient
4
+ from pygeai.core.common.exceptions import APIError
5
+
6
+
7
+ class AILabClient(BaseClient):
8
+
9
+ def __init__(self, api_key: str = None, base_url: str = None, alias: str = None, project_id: str = None):
10
+ super().__init__(api_key, base_url, alias)
11
+ self.project_id = project_id if project_id else self.__get_project_id()
12
+
13
+ def __get_project_id(self):
14
+ response = None
15
+ try:
16
+ response = AdminClient().validate_api_token()
17
+ return response.get("projectId")
18
+ except Exception as e:
19
+ logger.error(f"Error retrieving project_id from GEAI. Response: {response}: {e}")
20
+ raise APIError(f"Error retrieving project_id from GEAI: {e}")