pygeai 0.3.1__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 (49) 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/common/config.py +0 -2
  12. pygeai/core/common/exceptions.py +6 -0
  13. pygeai/lab/agents/clients.py +30 -61
  14. pygeai/lab/clients.py +20 -0
  15. pygeai/lab/managers.py +6 -58
  16. pygeai/lab/models.py +7 -3
  17. pygeai/lab/processes/clients.py +81 -129
  18. pygeai/lab/processes/mappers.py +2 -2
  19. pygeai/lab/strategies/clients.py +11 -17
  20. pygeai/lab/tools/clients.py +59 -59
  21. pygeai/lab/tools/mappers.py +5 -5
  22. pygeai/tests/integration/assistants/__init__.py +0 -0
  23. pygeai/tests/integration/assistants/rag/__init__.py +0 -0
  24. pygeai/tests/integration/assistants/rag/test_create_rag.py +72 -0
  25. pygeai/tests/integration/chat/__init__.py +0 -0
  26. pygeai/tests/integration/chat/test_generate_image.py +162 -0
  27. pygeai/tests/integration/lab/agents/test_create_agent.py +9 -13
  28. pygeai/tests/integration/lab/agents/test_publish_agent_revision.py +0 -1
  29. pygeai/tests/integration/lab/agents/test_update_agent.py +6 -15
  30. pygeai/tests/integration/lab/tools/__init__.py +0 -0
  31. pygeai/tests/integration/lab/tools/test_create_tool.py +292 -0
  32. pygeai/tests/integration/lab/tools/test_delete_tool.py +87 -0
  33. pygeai/tests/integration/lab/tools/test_get_parameter.py +98 -0
  34. pygeai/tests/integration/lab/tools/test_get_tool.py +91 -0
  35. pygeai/tests/integration/lab/tools/test_list_tools.py +106 -0
  36. pygeai/tests/integration/lab/tools/test_publish_tool_revision.py +119 -0
  37. pygeai/tests/integration/lab/tools/test_set_parameter.py +114 -0
  38. pygeai/tests/integration/lab/tools/test_update_tool.py +268 -0
  39. pygeai/tests/snippets/lab/agents/create_agent_edge_case.py +48 -0
  40. pygeai/tests/snippets/lab/agents/create_agent_without_instructions.py +48 -0
  41. pygeai/tests/snippets/lab/agents/get_sharing_link.py +1 -2
  42. pygeai/tests/snippets/lab/tools/create_tool.py +1 -1
  43. pygeai/tests/snippets/lab/tools/create_tool_edge_case.py +50 -0
  44. {pygeai-0.3.1.dist-info → pygeai-0.4.0.dist-info}/METADATA +4 -4
  45. {pygeai-0.3.1.dist-info → pygeai-0.4.0.dist-info}/RECORD +49 -29
  46. {pygeai-0.3.1.dist-info → pygeai-0.4.0.dist-info}/WHEEL +0 -0
  47. {pygeai-0.3.1.dist-info → pygeai-0.4.0.dist-info}/entry_points.txt +0 -0
  48. {pygeai-0.3.1.dist-info → pygeai-0.4.0.dist-info}/licenses/LICENSE +0 -0
  49. {pygeai-0.3.1.dist-info → pygeai-0.4.0.dist-info}/top_level.txt +0 -0
pygeai/lab/managers.py CHANGED
@@ -23,20 +23,10 @@ from pygeai.lab.tools.mappers import ToolMapper
23
23
  class AILabManager:
24
24
 
25
25
  def __init__(self, api_key: str = None, base_url: str = None, alias: str = "default", project_id: str = None):
26
- self.__agent_client = AgentClient(api_key=api_key, base_url=base_url, alias=alias)
27
- self.__tool_client = ToolClient(api_key=api_key, base_url=base_url, alias=alias)
28
- self.__reasoning_strategy_client = ReasoningStrategyClient(api_key=api_key, base_url=base_url, alias=alias)
29
- self.__process_client = AgenticProcessClient(api_key=api_key, base_url=base_url, alias=alias)
30
- self.project_id = self.__get_project_id() if not project_id else project_id
31
-
32
- def __get_project_id(self):
33
- response = None
34
- try:
35
- response = AdminClient().validate_api_token()
36
- return response.get("projectId")
37
- except Exception as e:
38
- logger.error(f"Error retrieving project_id from GEAI. Response: {response}: {e}")
39
- raise APIError(f"Error retrieving project_id from GEAI: {e}")
26
+ self.__agent_client = AgentClient(api_key=api_key, base_url=base_url, alias=alias, project_id=project_id)
27
+ self.__tool_client = ToolClient(api_key=api_key, base_url=base_url, alias=alias, project_id=project_id)
28
+ self.__reasoning_strategy_client = ReasoningStrategyClient(api_key=api_key, base_url=base_url, alias=alias, project_id=project_id)
29
+ self.__process_client = AgenticProcessClient(api_key=api_key, base_url=base_url, alias=alias, project_id=project_id)
40
30
 
41
31
  def get_agent_list(
42
32
  self,
@@ -57,7 +47,6 @@ class AILabManager:
57
47
  filter_settings = FilterSettings()
58
48
 
59
49
  response_data = self.__agent_client.list_agents(
60
- project_id=self.project_id,
61
50
  status=filter_settings.status,
62
51
  start=filter_settings.start,
63
52
  count=filter_settings.count,
@@ -93,7 +82,6 @@ class AILabManager:
93
82
  :raises APIError: If the API returns errors.
94
83
  """
95
84
  response_data = self.__agent_client.create_agent(
96
- project_id=self.project_id,
97
85
  name=agent.name,
98
86
  access_scope=agent.access_scope,
99
87
  public_name=agent.public_name,
@@ -140,7 +128,6 @@ class AILabManager:
140
128
  :raises APIError: If the API returns errors.
141
129
  """
142
130
  response_data = self.__agent_client.update_agent(
143
- project_id=self.project_id,
144
131
  agent_id=agent.id,
145
132
  name=agent.name,
146
133
  access_scope=agent.access_scope,
@@ -189,7 +176,6 @@ class AILabManager:
189
176
  )
190
177
 
191
178
  response_data = self.__agent_client.get_agent(
192
- project_id=self.project_id,
193
179
  agent_id=agent_id,
194
180
  revision=filter_settings.revision,
195
181
  version=filter_settings.version,
@@ -218,7 +204,6 @@ class AILabManager:
218
204
  :raises APIError: If the API returns errors.
219
205
  """
220
206
  response_data = self.__agent_client.create_sharing_link(
221
- project_id=self.project_id,
222
207
  agent_id=agent_id
223
208
  )
224
209
  if ErrorHandler.has_errors(response_data):
@@ -246,7 +231,6 @@ class AILabManager:
246
231
  :raises APIError: If the API returns errors.
247
232
  """
248
233
  response_data = self.__agent_client.publish_agent_revision(
249
- project_id=self.project_id,
250
234
  agent_id=agent_id,
251
235
  revision=revision
252
236
  )
@@ -273,7 +257,6 @@ class AILabManager:
273
257
  :raises APIError: If the API returns errors.
274
258
  """
275
259
  response_data = self.__agent_client.delete_agent(
276
- project_id=self.project_id,
277
260
  agent_id=agent_id
278
261
  )
279
262
  if ErrorHandler.has_errors(response_data):
@@ -308,7 +291,6 @@ class AILabManager:
308
291
  parameters = [param.to_dict() for param in tool.parameters] if tool.parameters else []
309
292
 
310
293
  response_data = self.__tool_client.create_tool(
311
- project_id=self.project_id,
312
294
  name=tool.name,
313
295
  description=tool.description,
314
296
  scope=tool.scope,
@@ -356,7 +338,6 @@ class AILabManager:
356
338
  parameters = [param.to_dict() for param in tool.parameters] if tool.parameters else []
357
339
 
358
340
  response_data = self.__tool_client.update_tool(
359
- project_id=self.project_id,
360
341
  tool_id=tool.id,
361
342
  name=tool.name,
362
343
  description=tool.description,
@@ -406,7 +387,6 @@ class AILabManager:
406
387
  )
407
388
 
408
389
  response_data = self.__tool_client.get_tool(
409
- project_id=self.project_id,
410
390
  tool_id=tool_id,
411
391
  revision=filter_settings.revision,
412
392
  version=filter_settings.version,
@@ -442,7 +422,6 @@ class AILabManager:
442
422
  raise MissingRequirementException("Either tool_id or tool_name must be provided.")
443
423
 
444
424
  response_data = self.__tool_client.delete_tool(
445
- project_id=self.project_id,
446
425
  tool_id=tool_id,
447
426
  tool_name=tool_name
448
427
  )
@@ -483,7 +462,6 @@ class AILabManager:
483
462
  )
484
463
 
485
464
  response_data = self.__tool_client.list_tools(
486
- project_id=self.project_id,
487
465
  id=filter_settings.id,
488
466
  count=filter_settings.count,
489
467
  access_scope=filter_settings.access_scope,
@@ -517,7 +495,6 @@ class AILabManager:
517
495
  :raises APIError: If the API returns errors.
518
496
  """
519
497
  response_data = self.__tool_client.publish_tool_revision(
520
- project_id=self.project_id,
521
498
  tool_id=tool_id,
522
499
  revision=revision
523
500
  )
@@ -562,7 +539,6 @@ class AILabManager:
562
539
  )
563
540
 
564
541
  response_data = self.__tool_client.get_parameter(
565
- project_id=self.project_id,
566
542
  tool_id=tool_id,
567
543
  tool_public_name=tool_public_name,
568
544
  revision=filter_settings.revision,
@@ -583,7 +559,7 @@ class AILabManager:
583
559
  tool_id: Optional[str] = None,
584
560
  tool_public_name: Optional[str] = None,
585
561
  parameters: List[ToolParameter] = None
586
- ) -> Tool:
562
+ ) -> EmptyResponse:
587
563
  """
588
564
  Sets or updates parameters for a specific tool in the specified project.
589
565
 
@@ -605,7 +581,6 @@ class AILabManager:
605
581
  params_dict = [param.to_dict() for param in parameters]
606
582
 
607
583
  response_data = self.__tool_client.set_parameter(
608
- project_id=self.project_id,
609
584
  tool_id=tool_id,
610
585
  tool_public_name=tool_public_name,
611
586
  parameters=params_dict
@@ -616,7 +591,7 @@ class AILabManager:
616
591
  logger.error(f"Error received while setting tool parameters: {error}")
617
592
  raise APIError(f"Error received while setting tool parameters: {error}")
618
593
 
619
- result = ToolMapper.map_to_tool(response_data)
594
+ result = ResponseMapper.map_to_empty_response(response_data or "Parameter set successfully")
620
595
  return result
621
596
 
622
597
  def list_reasoning_strategies(
@@ -678,7 +653,6 @@ class AILabManager:
678
653
  :raises APIError: If the API returns errors.
679
654
  """
680
655
  response_data = self.__reasoning_strategy_client.create_reasoning_strategy(
681
- project_id=self.project_id,
682
656
  name=strategy.name,
683
657
  system_prompt=strategy.system_prompt,
684
658
  access_scope=strategy.access_scope,
@@ -717,7 +691,6 @@ class AILabManager:
717
691
  :raises APIError: If the API returns errors.
718
692
  """
719
693
  response_data = self.__reasoning_strategy_client.update_reasoning_strategy(
720
- project_id=self.project_id,
721
694
  reasoning_strategy_id=strategy.id,
722
695
  name=strategy.name,
723
696
  system_prompt=strategy.system_prompt,
@@ -757,7 +730,6 @@ class AILabManager:
757
730
  raise MissingRequirementException("Either reasoning_strategy_id or reasoning_strategy_name must be provided.")
758
731
 
759
732
  response_data = self.__reasoning_strategy_client.get_reasoning_strategy(
760
- project_id=self.project_id,
761
733
  reasoning_strategy_id=reasoning_strategy_id,
762
734
  reasoning_strategy_name=reasoning_strategy_name
763
735
  )
@@ -789,7 +761,6 @@ class AILabManager:
789
761
  :raises APIError: If the API returns errors.
790
762
  """
791
763
  response_data = self.__process_client.create_process(
792
- project_id=self.project_id,
793
764
  key=process.key,
794
765
  name=process.name,
795
766
  description=process.description,
@@ -833,7 +804,6 @@ class AILabManager:
833
804
  :raises APIError: If the API returns errors.
834
805
  """
835
806
  response_data = self.__process_client.update_process(
836
- project_id=self.project_id,
837
807
  process_id=process.id,
838
808
  name=process.name,
839
809
  key=process.key,
@@ -883,7 +853,6 @@ class AILabManager:
883
853
 
884
854
  filter_settings = filter_settings or FilterSettings(revision="0", version="0", allow_drafts=True)
885
855
  response_data = self.__process_client.get_process(
886
- project_id=self.project_id,
887
856
  process_id=process_id,
888
857
  process_name=process_name,
889
858
  revision=filter_settings.revision,
@@ -915,7 +884,6 @@ class AILabManager:
915
884
  """
916
885
  filter_settings = filter_settings or FilterSettings(start="0", count="100", allow_drafts=True)
917
886
  response_data = self.__process_client.list_processes(
918
- project_id=self.project_id,
919
887
  id=filter_settings.id,
920
888
  name=filter_settings.name,
921
889
  status=filter_settings.status,
@@ -950,7 +918,6 @@ class AILabManager:
950
918
  """
951
919
  filter_settings = filter_settings or FilterSettings(start="0", count="10", is_active=True)
952
920
  response_data = self.__process_client.list_process_instances(
953
- project_id=self.project_id,
954
921
  process_id=process_id,
955
922
  is_active=filter_settings.is_active,
956
923
  start=filter_settings.start,
@@ -986,7 +953,6 @@ class AILabManager:
986
953
  raise MissingRequirementException("Either process_id or process_name must be provided.")
987
954
 
988
955
  response_data = self.__process_client.delete_process(
989
- project_id=self.project_id,
990
956
  process_id=process_id,
991
957
  process_name=process_name
992
958
  )
@@ -1022,7 +988,6 @@ class AILabManager:
1022
988
  raise MissingRequirementException("Either process_id or process_name and revision must be provided.")
1023
989
 
1024
990
  response_data = self.__process_client.publish_process_revision(
1025
- project_id=self.project_id,
1026
991
  process_id=process_id,
1027
992
  process_name=process_name,
1028
993
  revision=revision
@@ -1054,7 +1019,6 @@ class AILabManager:
1054
1019
  :raises APIError: If the API returns errors.
1055
1020
  """
1056
1021
  response_data = self.__process_client.create_task(
1057
- project_id=self.project_id,
1058
1022
  name=task.name,
1059
1023
  description=task.description,
1060
1024
  title_template=task.title_template,
@@ -1093,7 +1057,6 @@ class AILabManager:
1093
1057
  raise MissingRequirementException("Either task_id or task_name must be provided.")
1094
1058
 
1095
1059
  response_data = self.__process_client.get_task(
1096
- project_id=self.project_id,
1097
1060
  task_id=task_id,
1098
1061
  task_name=task_name
1099
1062
  )
@@ -1122,7 +1085,6 @@ class AILabManager:
1122
1085
  """
1123
1086
  filter_settings = filter_settings or FilterSettings(start="0", count="100", allow_drafts=True)
1124
1087
  response_data = self.__process_client.list_tasks(
1125
- project_id=self.project_id,
1126
1088
  id=filter_settings.id,
1127
1089
  start=filter_settings.start,
1128
1090
  count=filter_settings.count,
@@ -1161,7 +1123,6 @@ class AILabManager:
1161
1123
  raise MissingRequirementException("Task ID must be provided for update.")
1162
1124
 
1163
1125
  response_data = self.__process_client.update_task(
1164
- project_id=self.project_id,
1165
1126
  task_id=task.id,
1166
1127
  name=task.name,
1167
1128
  description=task.description,
@@ -1202,7 +1163,6 @@ class AILabManager:
1202
1163
  raise MissingRequirementException("Either task_id or task_name must be provided.")
1203
1164
 
1204
1165
  response_data = self.__process_client.delete_task(
1205
- project_id=self.project_id,
1206
1166
  task_id=task_id,
1207
1167
  task_name=task_name
1208
1168
  )
@@ -1238,7 +1198,6 @@ class AILabManager:
1238
1198
  raise MissingRequirementException("Either task_id or task_name and revision must be provided.")
1239
1199
 
1240
1200
  response_data = self.__process_client.publish_task_revision(
1241
- project_id=self.project_id,
1242
1201
  task_id=task_id,
1243
1202
  task_name=task_name,
1244
1203
  revision=revision
@@ -1274,7 +1233,6 @@ class AILabManager:
1274
1233
  variables = VariableList(variables=variables)
1275
1234
 
1276
1235
  response_data = self.__process_client.start_instance(
1277
- project_id=self.project_id,
1278
1236
  process_name=process_name,
1279
1237
  subject=subject,
1280
1238
  variables=variables.to_dict()
@@ -1307,7 +1265,6 @@ class AILabManager:
1307
1265
  raise MissingRequirementException("Instance ID must be provided.")
1308
1266
 
1309
1267
  response_data = self.__process_client.abort_instance(
1310
- project_id=self.project_id,
1311
1268
  instance_id=instance_id
1312
1269
  )
1313
1270
 
@@ -1338,7 +1295,6 @@ class AILabManager:
1338
1295
  raise MissingRequirementException("Instance ID must be provided.")
1339
1296
 
1340
1297
  response_data = self.__process_client.get_instance(
1341
- project_id=self.project_id,
1342
1298
  instance_id=instance_id
1343
1299
  )
1344
1300
  if ErrorHandler.has_errors(response_data):
@@ -1368,7 +1324,6 @@ class AILabManager:
1368
1324
  raise MissingRequirementException("Instance ID must be provided.")
1369
1325
 
1370
1326
  response_data = self.__process_client.get_instance_history(
1371
- project_id=self.project_id,
1372
1327
  instance_id=instance_id
1373
1328
  )
1374
1329
 
@@ -1399,7 +1354,6 @@ class AILabManager:
1399
1354
  raise MissingRequirementException("Thread ID must be provided.")
1400
1355
 
1401
1356
  response_data = self.__process_client.get_thread_information(
1402
- project_id=self.project_id,
1403
1357
  thread_id=thread_id
1404
1358
  )
1405
1359
 
@@ -1432,7 +1386,6 @@ class AILabManager:
1432
1386
  raise MissingRequirementException("Instance ID and signal name must be provided.")
1433
1387
 
1434
1388
  response_data = self.__process_client.send_user_signal(
1435
- project_id=self.project_id,
1436
1389
  instance_id=instance_id,
1437
1390
  signal_name=signal_name
1438
1391
  )
@@ -1461,7 +1414,6 @@ class AILabManager:
1461
1414
  :raises APIError: If the API returns errors.
1462
1415
  """
1463
1416
  response_data = self.__process_client.create_kb(
1464
- project_id=self.project_id,
1465
1417
  name=knowledge_base.name,
1466
1418
  artifacts=knowledge_base.artifacts if knowledge_base.artifacts else None,
1467
1419
  metadata=knowledge_base.metadata if knowledge_base.metadata else None
@@ -1493,7 +1445,6 @@ class AILabManager:
1493
1445
  :raises APIError: If the API returns errors.
1494
1446
  """
1495
1447
  response_data = self.__process_client.list_kbs(
1496
- project_id=self.project_id,
1497
1448
  name=name,
1498
1449
  start=start,
1499
1450
  count=count
@@ -1527,7 +1478,6 @@ class AILabManager:
1527
1478
  raise MissingRequirementException("Either kb_name or kb_id must be provided.")
1528
1479
 
1529
1480
  response_data = self.__process_client.get_kb(
1530
- project_id=self.project_id,
1531
1481
  kb_name=kb_name,
1532
1482
  kb_id=kb_id
1533
1483
  )
@@ -1560,7 +1510,6 @@ class AILabManager:
1560
1510
  raise MissingRequirementException("Either kb_name or kb_id must be provided.")
1561
1511
 
1562
1512
  response_data = self.__process_client.delete_kb(
1563
- project_id=self.project_id,
1564
1513
  kb_name=kb_name,
1565
1514
  kb_id=kb_id
1566
1515
  )
@@ -1595,7 +1544,6 @@ class AILabManager:
1595
1544
 
1596
1545
  filter_settings = filter_settings or FilterSettings(start="0", count="100")
1597
1546
  response_data = self.__process_client.list_jobs(
1598
- project_id=self.project_id,
1599
1547
  start=filter_settings.start,
1600
1548
  count=filter_settings.count,
1601
1549
  topic=topic,
pygeai/lab/models.py CHANGED
@@ -94,7 +94,7 @@ class Model(CustomBaseModel):
94
94
  :param llm_config: Optional[LlmConfig] - Overrides default agent LLM settings.
95
95
  :param prompt: Optional[dict] - A tailored prompt specific to this model.
96
96
  """
97
- name: str = Field(..., alias="name")
97
+ name: Optional[str] = Field(None, alias="name")
98
98
  llm_config: Optional[LlmConfig] = Field(None, alias="llmConfig")
99
99
  prompt: Optional[Dict[str, Any]] = Field(None, alias="prompt")
100
100
 
@@ -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