pygeai 0.6.0b6__py3-none-any.whl → 0.6.0b10__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 (227) hide show
  1. pygeai/_docs/source/conf.py +78 -6
  2. pygeai/_docs/source/content/api_reference/admin.rst +161 -0
  3. pygeai/_docs/source/content/api_reference/assistant.rst +326 -0
  4. pygeai/_docs/source/content/api_reference/auth.rst +379 -0
  5. pygeai/_docs/source/content/api_reference/embeddings.rst +31 -1
  6. pygeai/_docs/source/content/api_reference/evaluation.rst +590 -0
  7. pygeai/_docs/source/content/api_reference/feedback.rst +237 -0
  8. pygeai/_docs/source/content/api_reference/files.rst +592 -0
  9. pygeai/_docs/source/content/api_reference/gam.rst +401 -0
  10. pygeai/_docs/source/content/api_reference/health.rst +58 -0
  11. pygeai/_docs/source/content/api_reference/project.rst +20 -18
  12. pygeai/_docs/source/content/api_reference/proxy.rst +318 -0
  13. pygeai/_docs/source/content/api_reference/rerank.rst +94 -0
  14. pygeai/_docs/source/content/api_reference/secrets.rst +495 -0
  15. pygeai/_docs/source/content/api_reference/usage_limits.rst +390 -0
  16. pygeai/_docs/source/content/api_reference.rst +13 -1
  17. pygeai/_docs/source/content/debugger.rst +376 -83
  18. pygeai/_docs/source/content/migration.rst +528 -0
  19. pygeai/_docs/source/content/modules.rst +1 -1
  20. pygeai/_docs/source/index.rst +59 -7
  21. pygeai/_docs/source/pygeai.auth.rst +29 -0
  22. pygeai/_docs/source/pygeai.cli.commands.rst +16 -0
  23. pygeai/_docs/source/pygeai.cli.rst +8 -0
  24. pygeai/_docs/source/pygeai.core.utils.rst +16 -0
  25. pygeai/_docs/source/pygeai.rst +1 -0
  26. pygeai/_docs/source/pygeai.tests.auth.rst +21 -0
  27. pygeai/_docs/source/pygeai.tests.cli.commands.rst +16 -0
  28. pygeai/_docs/source/pygeai.tests.cli.rst +16 -0
  29. pygeai/_docs/source/pygeai.tests.core.base.rst +8 -0
  30. pygeai/_docs/source/pygeai.tests.core.embeddings.rst +16 -0
  31. pygeai/_docs/source/pygeai.tests.core.files.rst +8 -0
  32. pygeai/_docs/source/pygeai.tests.core.plugins.rst +21 -0
  33. pygeai/_docs/source/pygeai.tests.core.rst +1 -0
  34. pygeai/_docs/source/pygeai.tests.evaluation.dataset.rst +21 -0
  35. pygeai/_docs/source/pygeai.tests.evaluation.plan.rst +21 -0
  36. pygeai/_docs/source/pygeai.tests.evaluation.result.rst +21 -0
  37. pygeai/_docs/source/pygeai.tests.evaluation.rst +20 -0
  38. pygeai/_docs/source/pygeai.tests.integration.lab.processes.rst +8 -0
  39. pygeai/_docs/source/pygeai.tests.organization.rst +8 -0
  40. pygeai/_docs/source/pygeai.tests.rst +2 -0
  41. pygeai/_docs/source/pygeai.tests.snippets.auth.rst +10 -0
  42. pygeai/_docs/source/pygeai.tests.snippets.chat.rst +40 -0
  43. pygeai/_docs/source/pygeai.tests.snippets.dbg.rst +45 -0
  44. pygeai/_docs/source/pygeai.tests.snippets.embeddings.rst +40 -0
  45. pygeai/_docs/source/pygeai.tests.snippets.evaluation.dataset.rst +197 -0
  46. pygeai/_docs/source/pygeai.tests.snippets.evaluation.plan.rst +133 -0
  47. pygeai/_docs/source/pygeai.tests.snippets.evaluation.result.rst +37 -0
  48. pygeai/_docs/source/pygeai.tests.snippets.evaluation.rst +10 -0
  49. pygeai/_docs/source/pygeai.tests.snippets.organization.rst +40 -0
  50. pygeai/_docs/source/pygeai.tests.snippets.rst +2 -0
  51. pygeai/admin/clients.py +12 -32
  52. pygeai/assistant/clients.py +16 -44
  53. pygeai/assistant/data/clients.py +1 -0
  54. pygeai/assistant/data_analyst/clients.py +6 -13
  55. pygeai/assistant/rag/clients.py +24 -67
  56. pygeai/auth/clients.py +88 -14
  57. pygeai/auth/endpoints.py +4 -0
  58. pygeai/chat/clients.py +192 -25
  59. pygeai/chat/endpoints.py +2 -1
  60. pygeai/cli/commands/auth.py +178 -2
  61. pygeai/cli/commands/chat.py +227 -1
  62. pygeai/cli/commands/embeddings.py +56 -8
  63. pygeai/cli/commands/lab/ai_lab.py +0 -2
  64. pygeai/cli/commands/migrate.py +994 -434
  65. pygeai/cli/commands/organization.py +241 -0
  66. pygeai/cli/error_handler.py +116 -0
  67. pygeai/cli/geai.py +28 -10
  68. pygeai/cli/parsers.py +8 -2
  69. pygeai/core/base/clients.py +4 -1
  70. pygeai/core/common/exceptions.py +11 -10
  71. pygeai/core/embeddings/__init__.py +19 -0
  72. pygeai/core/embeddings/clients.py +20 -9
  73. pygeai/core/embeddings/mappers.py +16 -2
  74. pygeai/core/embeddings/responses.py +9 -2
  75. pygeai/core/feedback/clients.py +4 -8
  76. pygeai/core/files/clients.py +10 -25
  77. pygeai/core/files/managers.py +42 -0
  78. pygeai/core/llm/clients.py +11 -26
  79. pygeai/core/models.py +107 -0
  80. pygeai/core/plugins/clients.py +4 -7
  81. pygeai/core/rerank/clients.py +4 -8
  82. pygeai/core/secrets/clients.py +14 -37
  83. pygeai/core/services/rest.py +1 -1
  84. pygeai/core/utils/parsers.py +32 -0
  85. pygeai/core/utils/validators.py +10 -0
  86. pygeai/dbg/__init__.py +3 -0
  87. pygeai/dbg/debugger.py +565 -70
  88. pygeai/evaluation/clients.py +2 -1
  89. pygeai/evaluation/dataset/clients.py +46 -44
  90. pygeai/evaluation/plan/clients.py +28 -26
  91. pygeai/evaluation/result/clients.py +38 -5
  92. pygeai/gam/clients.py +10 -25
  93. pygeai/health/clients.py +4 -7
  94. pygeai/lab/agents/clients.py +21 -54
  95. pygeai/lab/agents/endpoints.py +2 -0
  96. pygeai/lab/clients.py +1 -0
  97. pygeai/lab/models.py +3 -3
  98. pygeai/lab/processes/clients.py +45 -127
  99. pygeai/lab/strategies/clients.py +11 -25
  100. pygeai/lab/tools/clients.py +23 -67
  101. pygeai/lab/tools/endpoints.py +3 -0
  102. pygeai/migration/__init__.py +31 -0
  103. pygeai/migration/strategies.py +404 -155
  104. pygeai/migration/tools.py +170 -3
  105. pygeai/organization/clients.py +135 -51
  106. pygeai/organization/endpoints.py +6 -1
  107. pygeai/organization/limits/clients.py +32 -91
  108. pygeai/organization/managers.py +157 -1
  109. pygeai/organization/mappers.py +76 -2
  110. pygeai/organization/responses.py +25 -1
  111. pygeai/proxy/clients.py +4 -1
  112. pygeai/tests/admin/test_clients.py +16 -11
  113. pygeai/tests/assistants/rag/test_clients.py +35 -23
  114. pygeai/tests/assistants/test_clients.py +22 -15
  115. pygeai/tests/auth/test_clients.py +191 -7
  116. pygeai/tests/chat/test_clients.py +211 -1
  117. pygeai/tests/cli/commands/test_embeddings.py +32 -9
  118. pygeai/tests/cli/commands/test_evaluation.py +7 -0
  119. pygeai/tests/cli/commands/test_migrate.py +112 -243
  120. pygeai/tests/cli/test_error_handler.py +225 -0
  121. pygeai/tests/cli/test_geai_driver.py +154 -0
  122. pygeai/tests/cli/test_parsers.py +5 -5
  123. pygeai/tests/core/embeddings/test_clients.py +144 -0
  124. pygeai/tests/core/embeddings/test_managers.py +171 -0
  125. pygeai/tests/core/embeddings/test_mappers.py +142 -0
  126. pygeai/tests/core/feedback/test_clients.py +2 -0
  127. pygeai/tests/core/files/test_clients.py +1 -0
  128. pygeai/tests/core/llm/test_clients.py +14 -9
  129. pygeai/tests/core/plugins/test_clients.py +5 -3
  130. pygeai/tests/core/rerank/test_clients.py +1 -0
  131. pygeai/tests/core/secrets/test_clients.py +19 -13
  132. pygeai/tests/dbg/test_debugger.py +453 -75
  133. pygeai/tests/evaluation/dataset/test_clients.py +3 -1
  134. pygeai/tests/evaluation/plan/test_clients.py +4 -2
  135. pygeai/tests/evaluation/result/test_clients.py +7 -5
  136. pygeai/tests/gam/test_clients.py +1 -1
  137. pygeai/tests/health/test_clients.py +1 -0
  138. pygeai/tests/lab/agents/test_clients.py +9 -0
  139. pygeai/tests/lab/processes/test_clients.py +36 -0
  140. pygeai/tests/lab/processes/test_mappers.py +3 -0
  141. pygeai/tests/lab/strategies/test_clients.py +14 -9
  142. pygeai/tests/migration/test_strategies.py +45 -218
  143. pygeai/tests/migration/test_tools.py +133 -9
  144. pygeai/tests/organization/limits/test_clients.py +17 -0
  145. pygeai/tests/organization/test_clients.py +206 -1
  146. pygeai/tests/organization/test_managers.py +122 -1
  147. pygeai/tests/proxy/test_clients.py +2 -0
  148. pygeai/tests/proxy/test_integration.py +1 -0
  149. pygeai/tests/snippets/auth/__init__.py +0 -0
  150. pygeai/tests/snippets/chat/chat_completion_with_reasoning_effort.py +18 -0
  151. pygeai/tests/snippets/chat/get_response.py +15 -0
  152. pygeai/tests/snippets/chat/get_response_streaming.py +20 -0
  153. pygeai/tests/snippets/chat/get_response_with_files.py +16 -0
  154. pygeai/tests/snippets/chat/get_response_with_tools.py +36 -0
  155. pygeai/tests/snippets/dbg/__init__.py +0 -0
  156. pygeai/tests/snippets/dbg/basic_debugging.py +32 -0
  157. pygeai/tests/snippets/dbg/breakpoint_management.py +48 -0
  158. pygeai/tests/snippets/dbg/stack_navigation.py +45 -0
  159. pygeai/tests/snippets/dbg/stepping_example.py +40 -0
  160. pygeai/tests/snippets/embeddings/cache_example.py +31 -0
  161. pygeai/tests/snippets/embeddings/cohere_example.py +41 -0
  162. pygeai/tests/snippets/embeddings/openai_base64_example.py +27 -0
  163. pygeai/tests/snippets/embeddings/openai_example.py +30 -0
  164. pygeai/tests/snippets/embeddings/similarity_example.py +42 -0
  165. pygeai/tests/snippets/evaluation/dataset/__init__.py +0 -0
  166. pygeai/tests/snippets/evaluation/dataset/complete_workflow_example.py +195 -0
  167. pygeai/tests/snippets/evaluation/dataset/create_dataset.py +26 -0
  168. pygeai/tests/snippets/evaluation/dataset/create_dataset_from_file.py +11 -0
  169. pygeai/tests/snippets/evaluation/dataset/create_dataset_row.py +17 -0
  170. pygeai/tests/snippets/evaluation/dataset/create_expected_source.py +18 -0
  171. pygeai/tests/snippets/evaluation/dataset/create_filter_variable.py +19 -0
  172. pygeai/tests/snippets/evaluation/dataset/delete_dataset.py +9 -0
  173. pygeai/tests/snippets/evaluation/dataset/delete_dataset_row.py +10 -0
  174. pygeai/tests/snippets/evaluation/dataset/delete_expected_source.py +15 -0
  175. pygeai/tests/snippets/evaluation/dataset/delete_filter_variable.py +15 -0
  176. pygeai/tests/snippets/evaluation/dataset/get_dataset.py +9 -0
  177. pygeai/tests/snippets/evaluation/dataset/get_dataset_row.py +10 -0
  178. pygeai/tests/snippets/evaluation/dataset/get_expected_source.py +15 -0
  179. pygeai/tests/snippets/evaluation/dataset/get_filter_variable.py +15 -0
  180. pygeai/tests/snippets/evaluation/dataset/list_dataset_rows.py +9 -0
  181. pygeai/tests/snippets/evaluation/dataset/list_datasets.py +6 -0
  182. pygeai/tests/snippets/evaluation/dataset/list_expected_sources.py +10 -0
  183. pygeai/tests/snippets/evaluation/dataset/list_filter_variables.py +10 -0
  184. pygeai/tests/snippets/evaluation/dataset/update_dataset.py +15 -0
  185. pygeai/tests/snippets/evaluation/dataset/update_dataset_row.py +20 -0
  186. pygeai/tests/snippets/evaluation/dataset/update_expected_source.py +18 -0
  187. pygeai/tests/snippets/evaluation/dataset/update_filter_variable.py +19 -0
  188. pygeai/tests/snippets/evaluation/dataset/upload_dataset_rows_file.py +10 -0
  189. pygeai/tests/snippets/evaluation/plan/__init__.py +0 -0
  190. pygeai/tests/snippets/evaluation/plan/add_plan_system_metric.py +13 -0
  191. pygeai/tests/snippets/evaluation/plan/complete_workflow_example.py +136 -0
  192. pygeai/tests/snippets/evaluation/plan/create_evaluation_plan.py +24 -0
  193. pygeai/tests/snippets/evaluation/plan/create_rag_evaluation_plan.py +22 -0
  194. pygeai/tests/snippets/evaluation/plan/delete_evaluation_plan.py +9 -0
  195. pygeai/tests/snippets/evaluation/plan/delete_plan_system_metric.py +13 -0
  196. pygeai/tests/snippets/evaluation/plan/execute_evaluation_plan.py +11 -0
  197. pygeai/tests/snippets/evaluation/plan/get_evaluation_plan.py +9 -0
  198. pygeai/tests/snippets/evaluation/plan/get_plan_system_metric.py +13 -0
  199. pygeai/tests/snippets/evaluation/plan/get_system_metric.py +9 -0
  200. pygeai/tests/snippets/evaluation/plan/list_evaluation_plans.py +7 -0
  201. pygeai/tests/snippets/evaluation/plan/list_plan_system_metrics.py +9 -0
  202. pygeai/tests/snippets/evaluation/plan/list_system_metrics.py +7 -0
  203. pygeai/tests/snippets/evaluation/plan/update_evaluation_plan.py +22 -0
  204. pygeai/tests/snippets/evaluation/plan/update_plan_system_metric.py +14 -0
  205. pygeai/tests/snippets/evaluation/result/__init__.py +0 -0
  206. pygeai/tests/snippets/evaluation/result/complete_workflow_example.py +150 -0
  207. pygeai/tests/snippets/evaluation/result/get_evaluation_result.py +26 -0
  208. pygeai/tests/snippets/evaluation/result/list_evaluation_results.py +17 -0
  209. pygeai/tests/snippets/migrate/__init__.py +45 -0
  210. pygeai/tests/snippets/migrate/agent_migration.py +110 -0
  211. pygeai/tests/snippets/migrate/assistant_migration.py +64 -0
  212. pygeai/tests/snippets/migrate/orchestrator_examples.py +179 -0
  213. pygeai/tests/snippets/migrate/process_migration.py +64 -0
  214. pygeai/tests/snippets/migrate/project_migration.py +42 -0
  215. pygeai/tests/snippets/migrate/tool_migration.py +64 -0
  216. pygeai/tests/snippets/organization/create_project.py +2 -2
  217. pygeai/tests/snippets/organization/get_memberships.py +12 -0
  218. pygeai/tests/snippets/organization/get_organization_members.py +6 -0
  219. pygeai/tests/snippets/organization/get_project_members.py +6 -0
  220. pygeai/tests/snippets/organization/get_project_memberships.py +12 -0
  221. pygeai/tests/snippets/organization/get_project_roles.py +6 -0
  222. {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b10.dist-info}/METADATA +1 -1
  223. {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b10.dist-info}/RECORD +227 -124
  224. {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b10.dist-info}/WHEEL +0 -0
  225. {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b10.dist-info}/entry_points.txt +0 -0
  226. {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b10.dist-info}/licenses/LICENSE +0 -0
  227. {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b10.dist-info}/top_level.txt +0 -0
@@ -1,10 +1,11 @@
1
- from json import JSONDecodeError
2
1
  from typing import Optional, List, Dict
3
2
 
4
3
  from pygeai import logger
5
4
  from pygeai.core.common.exceptions import MissingRequirementException, InvalidAPIResponseException
5
+ from pygeai.core.utils.validators import validate_status_code
6
+ from pygeai.core.utils.parsers import parse_json_response
6
7
  from pygeai.lab.agents.endpoints import CREATE_AGENT_V2, LIST_AGENTS_V2, GET_AGENT_V2, CREATE_SHARING_LINK_V2, \
7
- PUBLISH_AGENT_REVISION_V2, DELETE_AGENT_V2, UPDATE_AGENT_V2, UPSERT_AGENT_V2, EXPORT_AGENT_V2, IMPORT_AGENT_V2
8
+ PUBLISH_AGENT_REVISION_V2, DELETE_AGENT_V2, UPDATE_AGENT_V2, UPSERT_AGENT_V2, EXPORT_AGENT_V4, IMPORT_AGENT_V4
8
9
  from pygeai.lab.constants import VALID_ACCESS_SCOPES
9
10
  from pygeai.lab.clients import AILabClient
10
11
 
@@ -52,13 +53,8 @@ class AgentClient(AILabClient):
52
53
  "allowExternal": allow_external
53
54
  }
54
55
  )
55
- try:
56
- result = response.json()
57
- except JSONDecodeError as e:
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}")
60
-
61
- return result
56
+ validate_status_code(response)
57
+ return parse_json_response(response, f"list agents for project {self.project_id}")
62
58
 
63
59
  def create_agent(
64
60
  self,
@@ -139,13 +135,9 @@ class AgentClient(AILabClient):
139
135
  data=data
140
136
  )
141
137
 
142
- try:
143
- result = response.json()
144
- except JSONDecodeError as e:
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}")
138
+ validate_status_code(response)
139
+ return parse_json_response(response, f"create agent for project {self.project_id}")
147
140
 
148
- return result
149
141
 
150
142
  def get_agent(
151
143
  self,
@@ -185,13 +177,9 @@ class AgentClient(AILabClient):
185
177
  "allowDrafts": allow_drafts,
186
178
  }
187
179
  )
188
- try:
189
- result = response.json()
190
- except JSONDecodeError as e:
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}")
180
+ validate_status_code(response)
181
+ return parse_json_response(response, f"retrieve agent {agent_id} for project {self.project_id}")
193
182
 
194
- return result
195
183
 
196
184
  def create_sharing_link(
197
185
  self,
@@ -221,13 +209,9 @@ class AgentClient(AILabClient):
221
209
  headers=headers,
222
210
  params={}
223
211
  )
224
- try:
225
- result = response.json()
226
- except JSONDecodeError as e:
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}")
212
+ validate_status_code(response)
213
+ return parse_json_response(response, f"create sharing link for agent {agent_id} in project {self.project_id}")
229
214
 
230
- return result
231
215
 
232
216
  def publish_agent_revision(
233
217
  self,
@@ -257,13 +241,9 @@ class AgentClient(AILabClient):
257
241
  "revision": revision,
258
242
  }
259
243
  )
260
- try:
261
- result = response.json()
262
- except JSONDecodeError as e:
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}")
244
+ validate_status_code(response)
245
+ return parse_json_response(response, f"publish revision {revision} for agent {agent_id} in project {self.project_id}")
265
246
 
266
- return result
267
247
 
268
248
  def delete_agent(
269
249
  self,
@@ -381,13 +361,9 @@ class AgentClient(AILabClient):
381
361
  data=data
382
362
  )
383
363
 
384
- try:
385
- result = response.json()
386
- except JSONDecodeError as e:
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}")
364
+ validate_status_code(response)
365
+ return parse_json_response(response, f"update agent {agent_id} in project {self.project_id}")
389
366
 
390
- return result
391
367
 
392
368
  def export_agent(
393
369
  self,
@@ -404,7 +380,7 @@ class AgentClient(AILabClient):
404
380
  if not agent_id:
405
381
  raise MissingRequirementException("agent_id must be specified in order to export the agent")
406
382
 
407
- endpoint = EXPORT_AGENT_V2.format(agentId=agent_id)
383
+ endpoint = EXPORT_AGENT_V4.format(agentId=agent_id)
408
384
  headers = {
409
385
  "Authorization": self.api_service.token,
410
386
  "ProjectId": self.project_id
@@ -416,13 +392,8 @@ class AgentClient(AILabClient):
416
392
  endpoint=endpoint,
417
393
  headers=headers,
418
394
  )
419
- try:
420
- result = response.json()
421
- except JSONDecodeError as e:
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}")
424
-
425
- return result
395
+ validate_status_code(response)
396
+ return parse_json_response(response, f"export agent {agent_id} for project {self.project_id}")
426
397
 
427
398
  def import_agent(
428
399
  self,
@@ -439,7 +410,7 @@ class AgentClient(AILabClient):
439
410
  if not data:
440
411
  raise MissingRequirementException("data for spec must be specified in order to import the agent")
441
412
 
442
- endpoint = IMPORT_AGENT_V2
413
+ endpoint = IMPORT_AGENT_V4
443
414
  headers = {
444
415
  "Authorization": self.api_service.token,
445
416
  "ProjectId": self.project_id
@@ -450,10 +421,6 @@ class AgentClient(AILabClient):
450
421
  headers=headers,
451
422
  data=data
452
423
  )
453
- try:
454
- result = response.json()
455
- except JSONDecodeError as e:
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}")
424
+ validate_status_code(response)
425
+ return parse_json_response(response, f"import agent for project {self.project_id}")
458
426
 
459
- return result
@@ -8,3 +8,5 @@ UPDATE_AGENT_V2 = "v2/agents/{agentId}" # PUT -> Update agent
8
8
  UPSERT_AGENT_V2 = "v2/agents/{agentId}/upsert" # PUT -> Update or Insert agent
9
9
  EXPORT_AGENT_V2 = "v2/agents/{agentId}/export" # GET -> Export agent
10
10
  IMPORT_AGENT_V2 = "v2/agents/import" # POST -> Import agent
11
+ EXPORT_AGENT_V4 = "v4/agents/{agentId}/export" # GET -> Export agent
12
+ IMPORT_AGENT_V4 = "v4/agents/import" # POST -> Import agent
pygeai/lab/clients.py CHANGED
@@ -2,6 +2,7 @@ from pygeai import logger
2
2
  from pygeai.admin.clients import AdminClient
3
3
  from pygeai.core.base.clients import BaseClient
4
4
  from pygeai.core.common.exceptions import APIError
5
+ from pygeai.core.utils.validators import validate_status_code
5
6
 
6
7
 
7
8
  class AILabClient(BaseClient):
pygeai/lab/models.py CHANGED
@@ -711,9 +711,9 @@ class Tool(CustomBaseModel):
711
711
  raise ValueError("name cannot be blank")
712
712
  if ":" in value or "/" in value:
713
713
  raise ValueError("name cannot contain ':' or '/'")
714
- if not re.match(r'^[A-Za-z0-9_-]{1,64}$', value):
715
- raise ValueError(
716
- "name must contain only letters, numbers, underscores, or hyphens, and be 1-64 characters long")
714
+ # if not re.match(r'^[A-Za-z0-9_-]{1,64}$', value):
715
+ # raise ValueError(
716
+ # "name must contain only letters, numbers, underscores, or hyphens, and be 1-64 characters long")
717
717
  return value
718
718
 
719
719
  @field_validator("public_name")
@@ -1,8 +1,9 @@
1
- from json import JSONDecodeError
2
1
  from typing import List
3
2
 
4
3
  from pygeai import logger
5
4
  from pygeai.core.common.exceptions import InvalidAPIResponseException
5
+ from pygeai.core.utils.validators import validate_status_code
6
+ from pygeai.core.utils.parsers import parse_json_response
6
7
  from pygeai.lab.processes.endpoints import CREATE_PROCESS_V2, UPDATE_PROCESS_V2, UPSERT_PROCESS_V2, GET_PROCESS_V2, \
7
8
  LIST_PROCESSES_V2, LIST_PROCESS_INSTANCES_V2, DELETE_PROCESS_V2, PUBLISH_PROCESS_REVISION_V2, CREATE_TASK_V2, \
8
9
  UPDATE_TASK_V2, UPSERT_TASK_V2, GET_TASK_V2, LIST_TASKS_V2, DELETE_TASK_V2, PUBLISH_TASK_REVISION_V2, \
@@ -84,13 +85,9 @@ class AgenticProcessClient(AILabClient):
84
85
  logger.debug(f"Creating agentic process with data: {data}")
85
86
 
86
87
  response = self.api_service.post(endpoint=endpoint, headers=headers, data=data)
87
- try:
88
- result = response.json()
89
- except JSONDecodeError as e:
90
- logger.error(f"Unable to create process for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
91
- raise InvalidAPIResponseException(f"Unable to create process for project {self.project_id}: {response.text}")
88
+ validate_status_code(response)
89
+ return parse_json_response(response, f"create process for project {self.project_id}")
92
90
 
93
- return result
94
91
 
95
92
  def update_process(
96
93
  self,
@@ -194,13 +191,9 @@ class AgenticProcessClient(AILabClient):
194
191
  headers=headers,
195
192
  data=data
196
193
  )
197
- try:
198
- result = response.json()
199
- except JSONDecodeError as e:
200
- logger.error(f"Unable to update process {process_id or name} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
201
- raise InvalidAPIResponseException(f"Unable to update process {process_id or name} in project {self.project_id}: {response.text}")
194
+ validate_status_code(response)
195
+ return parse_json_response(response, f"update process {process_id or name} in project {self.project_id}")
202
196
 
203
- return result
204
197
 
205
198
  def get_process(
206
199
  self,
@@ -248,13 +241,9 @@ class AgenticProcessClient(AILabClient):
248
241
  headers=headers,
249
242
  params=params
250
243
  )
251
- try:
252
- result = response.json()
253
- except JSONDecodeError as e:
254
- logger.error(f"Unable to retrieve process {process_id or process_name} for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
255
- raise InvalidAPIResponseException(f"Unable to retrieve process {process_id or process_name} for project {self.project_id}: {response.text}")
244
+ validate_status_code(response)
245
+ return parse_json_response(response, f"retrieve process {process_id or process_name} for project {self.project_id}")
256
246
 
257
- return result
258
247
 
259
248
  def list_processes(
260
249
  self,
@@ -301,13 +290,9 @@ class AgenticProcessClient(AILabClient):
301
290
  headers=headers,
302
291
  params=params
303
292
  )
304
- try:
305
- result = response.json()
306
- except JSONDecodeError as e:
307
- logger.error(f"Unable to list processes for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
308
- raise InvalidAPIResponseException(f"Unable to list processes for project {self.project_id}: {response.text}")
293
+ validate_status_code(response)
294
+ return parse_json_response(response, f"list processes for project {self.project_id}")
309
295
 
310
- return result
311
296
 
312
297
  def list_process_instances(
313
298
  self,
@@ -348,13 +333,9 @@ class AgenticProcessClient(AILabClient):
348
333
  headers=headers,
349
334
  params=params
350
335
  )
351
- try:
352
- result = response.json()
353
- except JSONDecodeError as e:
354
- logger.error(f"Unable to list process instances for process {process_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
355
- raise InvalidAPIResponseException(f"Unable to list process instances for process {process_id} in project {self.project_id}: {response.text}")
336
+ validate_status_code(response)
337
+ return parse_json_response(response, f"list process instances for process {process_id} in project {self.project_id}")
356
338
 
357
- return result
358
339
 
359
340
  def delete_process(
360
341
  self,
@@ -435,13 +416,9 @@ class AgenticProcessClient(AILabClient):
435
416
  "revision": revision
436
417
  }
437
418
  )
438
- try:
439
- result = response.json()
440
- except JSONDecodeError as e:
441
- logger.error(f"Unable to publish revision {revision} for process {process_id or process_name} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
442
- raise InvalidAPIResponseException(f"Unable to publish revision {revision} for process {process_id or process_name} in project {self.project_id}: {response.text}")
419
+ validate_status_code(response)
420
+ return parse_json_response(response, f"publish revision {revision} for process {process_id or process_name} in project {self.project_id}")
443
421
 
444
- return result
445
422
 
446
423
  def create_task(
447
424
  self,
@@ -495,12 +472,8 @@ class AgenticProcessClient(AILabClient):
495
472
  logger.debug(f"Creating task with data: {data}")
496
473
 
497
474
  response = self.api_service.post(endpoint=endpoint, headers=headers, data=data)
498
- try:
499
- return response.json()
500
- except JSONDecodeError as e:
501
- logger.error(f"Unable to create task for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
502
- raise InvalidAPIResponseException(f"Unable to create task for project {self.project_id}: {response.text}")
503
-
475
+ validate_status_code(response)
476
+ return parse_json_response(response, f"create task for project {self.project_id}")
504
477
  def get_task(
505
478
  self,
506
479
  task_id: str,
@@ -531,12 +504,8 @@ class AgenticProcessClient(AILabClient):
531
504
  logger.debug(f"Retrieving task detail with name {task_name}")
532
505
 
533
506
  response = self.api_service.get(endpoint=endpoint, headers=headers)
534
- try:
535
- return response.json()
536
- except JSONDecodeError as e:
537
- logger.error(f"Unable to retrieve task {task_id or task_name} for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
538
- raise InvalidAPIResponseException(f"Unable to retrieve task {task_id or task_name} for project {self.project_id}: {response.text}")
539
-
507
+ validate_status_code(response)
508
+ return parse_json_response(response, f"retrieve task {task_id or task_name} for project {self.project_id}")
540
509
  def list_tasks(
541
510
  self,
542
511
  id: str = None,
@@ -570,12 +539,8 @@ class AgenticProcessClient(AILabClient):
570
539
  logger.debug(f"Listing tasks for project with ID {self.project_id}")
571
540
 
572
541
  response = self.api_service.get(endpoint=endpoint, headers=headers, params=params)
573
- try:
574
- return response.json()
575
- except JSONDecodeError as e:
576
- logger.error(f"Unable to list tasks for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
577
- raise InvalidAPIResponseException(f"Unable to list tasks for project {self.project_id}: {response.text}")
578
-
542
+ validate_status_code(response)
543
+ return parse_json_response(response, f"list tasks for project {self.project_id}")
579
544
  def update_task(
580
545
  self,
581
546
  task_id: str,
@@ -638,12 +603,8 @@ class AgenticProcessClient(AILabClient):
638
603
  logger.debug(f"Updating task with ID {task_id} with data: {data}")
639
604
 
640
605
  response = self.api_service.put(endpoint=endpoint, headers=headers, data=data)
641
- try:
642
- return response.json()
643
- except JSONDecodeError as e:
644
- logger.error(f"Unable to update task {task_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
645
- raise InvalidAPIResponseException(f"Unable to update task {task_id} in project {self.project_id}: {response.text}")
646
-
606
+ validate_status_code(response)
607
+ return parse_json_response(response, f"update task {task_id} in project {self.project_id}")
647
608
  def delete_task(
648
609
  self,
649
610
  task_id: str,
@@ -720,12 +681,8 @@ class AgenticProcessClient(AILabClient):
720
681
  logger.debug(f"Publishing revision {revision} for task with name {task_name}")
721
682
 
722
683
  response = self.api_service.post(endpoint=endpoint, headers=headers, data=data)
723
- try:
724
- return response.json()
725
- except JSONDecodeError as e:
726
- logger.error(f"Unable to publish revision {revision} for task {task_id or task_name} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
727
- raise InvalidAPIResponseException(f"Unable to publish revision {revision} for task {task_id or task_name} in project {self.project_id}: {response.text}")
728
-
684
+ validate_status_code(response)
685
+ return parse_json_response(response, f"publish revision {revision} for task {task_id or task_name} in project {self.project_id}")
729
686
  def start_instance(
730
687
  self,
731
688
  process_name: str,
@@ -761,12 +718,8 @@ class AgenticProcessClient(AILabClient):
761
718
  logger.info(f"Starting instance for process with name '{process_name}'")
762
719
 
763
720
  response = self.api_service.post(endpoint=endpoint, headers=headers, data=data)
764
- try:
765
- return response.json()
766
- except JSONDecodeError as e:
767
- logger.error(f"Unable to start instance for process {process_name} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
768
- raise InvalidAPIResponseException(f"Unable to start instance for process {process_name} in project {self.project_id}: {response.text}")
769
-
721
+ validate_status_code(response)
722
+ return parse_json_response(response, f"start instance for process {process_name} in project {self.project_id}")
770
723
  def abort_instance(
771
724
  self,
772
725
  instance_id: str
@@ -793,12 +746,8 @@ class AgenticProcessClient(AILabClient):
793
746
  logger.info(f"Aborting instance with ID '{instance_id}'")
794
747
 
795
748
  response = self.api_service.post(endpoint=endpoint, headers=headers, data={})
796
- try:
797
- return response.json()
798
- except JSONDecodeError as e:
799
- logger.error(f"Unable to abort instance {instance_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
800
- raise InvalidAPIResponseException(f"Unable to abort instance {instance_id} in project {self.project_id}: {response.text}")
801
-
749
+ validate_status_code(response)
750
+ return parse_json_response(response, f"abort instance {instance_id} in project {self.project_id}")
802
751
  def get_instance(
803
752
  self,
804
753
  instance_id: str
@@ -823,12 +772,8 @@ class AgenticProcessClient(AILabClient):
823
772
  logger.info(f"Retrieving instance detail with ID '{instance_id}'")
824
773
 
825
774
  response = self.api_service.get(endpoint=endpoint, headers=headers)
826
- try:
827
- return response.json()
828
- except JSONDecodeError as e:
829
- logger.error(f"Unable to retrieve instance {instance_id} for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
830
- raise InvalidAPIResponseException(f"Unable to retrieve instance {instance_id} for project {self.project_id}: {response.text}")
831
-
775
+ validate_status_code(response)
776
+ return parse_json_response(response, f"retrieve instance {instance_id} for project {self.project_id}")
832
777
  def get_instance_history(
833
778
  self,
834
779
  instance_id: str
@@ -853,12 +798,8 @@ class AgenticProcessClient(AILabClient):
853
798
  logger.info(f"Retrieving instance history with ID '{instance_id}'")
854
799
 
855
800
  response = self.api_service.get(endpoint=endpoint, headers=headers)
856
- try:
857
- return response.json()
858
- except JSONDecodeError as e:
859
- logger.error(f"Unable to retrieve history for instance {instance_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
860
- raise InvalidAPIResponseException(f"Unable to retrieve history for instance {instance_id} in project {self.project_id}: {response.text}")
861
-
801
+ validate_status_code(response)
802
+ return parse_json_response(response, f"retrieve history for instance {instance_id} in project {self.project_id}")
862
803
  def get_thread_information(
863
804
  self,
864
805
  thread_id: str
@@ -883,12 +824,8 @@ class AgenticProcessClient(AILabClient):
883
824
  logger.debug(f"Retrieving information about thread with ID {thread_id}")
884
825
 
885
826
  response = self.api_service.get(endpoint=endpoint, headers=headers)
886
- try:
887
- return response.json()
888
- except JSONDecodeError as e:
889
- logger.error(f"Unable to retrieve thread information for thread {thread_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
890
- raise InvalidAPIResponseException(f"Unable to retrieve thread information for thread {thread_id} in project {self.project_id}: {response.text}")
891
-
827
+ validate_status_code(response)
828
+ return parse_json_response(response, f"retrieve thread information for thread {thread_id} in project {self.project_id}")
892
829
  def send_user_signal(
893
830
  self,
894
831
  instance_id: str,
@@ -922,12 +859,8 @@ class AgenticProcessClient(AILabClient):
922
859
  logger.debug(f"Sending user signal to process instance with ID {instance_id} with data: {data}")
923
860
 
924
861
  response = self.api_service.post(endpoint=endpoint, headers=headers, data=data)
925
- try:
926
- return response.json()
927
- except JSONDecodeError as e:
928
- logger.error(f"Unable to send user signal {signal_name} to instance {instance_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
929
- raise InvalidAPIResponseException(f"Unable to send user signal {signal_name} to instance {instance_id} in project {self.project_id}: {response.text}")
930
-
862
+ validate_status_code(response)
863
+ return parse_json_response(response, f"send user signal {signal_name} to instance {instance_id} in project {self.project_id}")
931
864
  def create_kb(
932
865
  self,
933
866
  name: str,
@@ -967,12 +900,8 @@ class AgenticProcessClient(AILabClient):
967
900
  headers=headers,
968
901
  data=data
969
902
  )
970
- try:
971
- return response.json()
972
- except JSONDecodeError as e:
973
- logger.error(f"Unable to create knowledge base for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
974
- raise InvalidAPIResponseException(f"Unable to create knowledge base for project {self.project_id}: {response.text}")
975
-
903
+ validate_status_code(response)
904
+ return parse_json_response(response, f"create knowledge base for project {self.project_id}")
976
905
  def get_kb(
977
906
  self,
978
907
  kb_id: str = None,
@@ -1003,12 +932,9 @@ class AgenticProcessClient(AILabClient):
1003
932
  logger.debug(f"Retrieving KB detail with name {kb_name}")
1004
933
 
1005
934
  response = self.api_service.get(endpoint=endpoint, headers=headers)
1006
- try:
1007
- return response.json()
1008
- except JSONDecodeError as e:
1009
- logger.error(f"Unable to retrieve knowledge base {kb_id or kb_name} for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
1010
- raise InvalidAPIResponseException(f"Unable to retrieve knowledge base {kb_id or kb_name} for project {self.project_id}: {response.text}")
1011
-
935
+ kb_identifier = kb_id or kb_name
936
+ validate_status_code(response)
937
+ return parse_json_response(response, f"retrieve knowledge base {kb_identifier} for project {self.project_id}")
1012
938
  def list_kbs(
1013
939
  self,
1014
940
  name: str = None,
@@ -1039,12 +965,8 @@ class AgenticProcessClient(AILabClient):
1039
965
  logger.debug(f"Listing tasks in project with ID {self.project_id}")
1040
966
 
1041
967
  response = self.api_service.get(endpoint=endpoint, headers=headers, params=params)
1042
- try:
1043
- return response.json()
1044
- except JSONDecodeError as e:
1045
- logger.error(f"Unable to list knowledge bases for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
1046
- raise InvalidAPIResponseException(f"Unable to list knowledge bases for project {self.project_id}: {response.text}")
1047
-
968
+ validate_status_code(response)
969
+ return parse_json_response(response, f"list knowledge bases for project {self.project_id}")
1048
970
  def delete_kb(
1049
971
  self,
1050
972
  kb_id: str = None,
@@ -1124,10 +1046,6 @@ class AgenticProcessClient(AILabClient):
1124
1046
  headers=headers,
1125
1047
  params=params
1126
1048
  )
1127
- try:
1128
- result = response.json()
1129
- except JSONDecodeError as e:
1130
- logger.error(f"Unable to list jobs for project {self.project_id}: JSONDecodeError parsing error (status {response.status_code}): {e}. Response: {response.text}")
1131
- raise InvalidAPIResponseException(f"Unable to list jobs for project {self.project_id}: {response.text}")
1049
+ validate_status_code(response)
1050
+ return parse_json_response(response, f"list jobs for project {self.project_id}")
1132
1051
 
1133
- return result
@@ -1,7 +1,8 @@
1
- from json import JSONDecodeError
2
1
 
3
2
  from pygeai import logger
4
3
  from pygeai.core.common.exceptions import InvalidAPIResponseException
4
+ from pygeai.core.utils.validators import validate_status_code
5
+ from pygeai.core.utils.parsers import parse_json_response
5
6
  from pygeai.lab.clients import AILabClient
6
7
  from pygeai.lab.strategies.endpoints import LIST_REASONING_STRATEGIES_V2, CREATE_REASONING_STRATEGY_V2, \
7
8
  UPDATE_REASONING_STRATEGY_V2, UPSERT_REASONING_STRATEGY_V2, GET_REASONING_STRATEGY_V2
@@ -46,13 +47,9 @@ class ReasoningStrategyClient(AILabClient):
46
47
  logger.debug("Listing reasoning strategies")
47
48
 
48
49
  response = self.api_service.get(endpoint=endpoint, headers=headers, params=params)
49
- try:
50
- result = response.json()
51
- except JSONDecodeError as e:
52
- logger.error(f"Unable to list reasoning strategies: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
53
- raise InvalidAPIResponseException(f"Unable to list reasoning strategies: {response.text}")
50
+ validate_status_code(response)
51
+ return parse_json_response(response, "list reasoning strategies")
54
52
 
55
- return result
56
53
 
57
54
  def create_reasoning_strategy(
58
55
  self,
@@ -98,13 +95,9 @@ class ReasoningStrategyClient(AILabClient):
98
95
  logger.debug(f"Creating reasoning strategy with data: {data}")
99
96
 
100
97
  response = self.api_service.post(endpoint=endpoint, headers=headers, data=data)
101
- try:
102
- result = response.json()
103
- except JSONDecodeError as e:
104
- logger.error(f"Unable to create reasoning strategy for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
105
- raise InvalidAPIResponseException(f"Unable to create reasoning strategy for project {self.project_id}: {response.text}")
98
+ validate_status_code(response)
99
+ return parse_json_response(response, f"create reasoning strategy for project {self.project_id}")
106
100
 
107
- return result
108
101
 
109
102
  def update_reasoning_strategy(
110
103
  self,
@@ -174,13 +167,9 @@ class ReasoningStrategyClient(AILabClient):
174
167
  headers=headers,
175
168
  data=data
176
169
  )
177
- try:
178
- result = response.json()
179
- except JSONDecodeError as e:
180
- logger.error(f"Unable to update reasoning strategy {reasoning_strategy_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
181
- raise InvalidAPIResponseException(f"Unable to update reasoning strategy {reasoning_strategy_id} in project {self.project_id}: {response.text}")
170
+ validate_status_code(response)
171
+ return parse_json_response(response, f"update reasoning strategy {reasoning_strategy_id} in project {self.project_id}")
182
172
 
183
- return result
184
173
 
185
174
  def get_reasoning_strategy(
186
175
  self,
@@ -216,11 +205,8 @@ class ReasoningStrategyClient(AILabClient):
216
205
  endpoint=endpoint,
217
206
  headers=headers
218
207
  )
219
- try:
220
- result = response.json()
221
- except JSONDecodeError as e:
222
- logger.error(f"Unable to retrieve reasoning strategy {reasoning_strategy_id or reasoning_strategy_name} for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
223
- raise InvalidAPIResponseException(f"Unable to retrieve reasoning strategy {reasoning_strategy_id or reasoning_strategy_name} for project {self.project_id}: {response.text}")
208
+ strategy_identifier = reasoning_strategy_id or reasoning_strategy_name
209
+ validate_status_code(response)
210
+ return parse_json_response(response, f"retrieve reasoning strategy {strategy_identifier} for project {self.project_id}")
224
211
 
225
- return result
226
212