pygeai 0.1.6__py3-none-any.whl → 0.6.0b15__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.

Potentially problematic release.


This version of pygeai might be problematic. Click here for more details.

Files changed (788) hide show
  1. pygeai/__init__.py +11 -2
  2. pygeai/_docs/Makefile +20 -0
  3. pygeai/_docs/make.bat +35 -0
  4. pygeai/_docs/source/conf.py +117 -0
  5. pygeai/_docs/source/content/ai_lab/cli.rst +747 -0
  6. pygeai/_docs/source/content/ai_lab/models.rst +1734 -0
  7. pygeai/_docs/source/content/ai_lab/runner.rst +253 -0
  8. pygeai/_docs/source/content/ai_lab/spec.rst +431 -0
  9. pygeai/_docs/source/content/ai_lab/usage.rst +1011 -0
  10. pygeai/_docs/source/content/ai_lab.rst +102 -0
  11. pygeai/_docs/source/content/analytics.rst +598 -0
  12. pygeai/_docs/source/content/api_reference/admin.rst +161 -0
  13. pygeai/_docs/source/content/api_reference/assistant.rst +326 -0
  14. pygeai/_docs/source/content/api_reference/auth.rst +379 -0
  15. pygeai/_docs/source/content/api_reference/chat.rst +754 -0
  16. pygeai/_docs/source/content/api_reference/embeddings.rst +154 -0
  17. pygeai/_docs/source/content/api_reference/evaluation.rst +590 -0
  18. pygeai/_docs/source/content/api_reference/feedback.rst +237 -0
  19. pygeai/_docs/source/content/api_reference/files.rst +592 -0
  20. pygeai/_docs/source/content/api_reference/gam.rst +401 -0
  21. pygeai/_docs/source/content/api_reference/health.rst +58 -0
  22. pygeai/_docs/source/content/api_reference/project.rst +738 -0
  23. pygeai/_docs/source/content/api_reference/proxy.rst +318 -0
  24. pygeai/_docs/source/content/api_reference/rag.rst +710 -0
  25. pygeai/_docs/source/content/api_reference/rerank.rst +94 -0
  26. pygeai/_docs/source/content/api_reference/secrets.rst +495 -0
  27. pygeai/_docs/source/content/api_reference/usage_limits.rst +390 -0
  28. pygeai/_docs/source/content/api_reference.rst +58 -0
  29. pygeai/_docs/source/content/authentication.rst +295 -0
  30. pygeai/_docs/source/content/chat_gui.rst +121 -0
  31. pygeai/_docs/source/content/cli.rst +203 -0
  32. pygeai/_docs/source/content/debugger.rst +651 -0
  33. pygeai/_docs/source/content/intro.rst +67 -0
  34. pygeai/_docs/source/content/migration.rst +929 -0
  35. pygeai/_docs/source/content/modules.rst +7 -0
  36. pygeai/_docs/source/content/quickstart.rst +143 -0
  37. pygeai/_docs/source/content/samples.rst +394 -0
  38. pygeai/_docs/source/index.rst +75 -0
  39. pygeai/_docs/source/modules.rst +7 -0
  40. pygeai/_docs/source/pygeai.admin.rst +29 -0
  41. pygeai/_docs/source/pygeai.analytics.rst +53 -0
  42. pygeai/_docs/source/pygeai.assistant.data.rst +21 -0
  43. pygeai/_docs/source/pygeai.assistant.data_analyst.rst +29 -0
  44. pygeai/_docs/source/pygeai.assistant.rag.rst +53 -0
  45. pygeai/_docs/source/pygeai.assistant.rst +55 -0
  46. pygeai/_docs/source/pygeai.auth.rst +29 -0
  47. pygeai/_docs/source/pygeai.chat.rst +69 -0
  48. pygeai/_docs/source/pygeai.cli.commands.flows.rst +10 -0
  49. pygeai/_docs/source/pygeai.cli.commands.lab.rst +53 -0
  50. pygeai/_docs/source/pygeai.cli.commands.rst +222 -0
  51. pygeai/_docs/source/pygeai.cli.rst +62 -0
  52. pygeai/_docs/source/pygeai.cli.texts.rst +21 -0
  53. pygeai/_docs/source/pygeai.core.base.rst +53 -0
  54. pygeai/_docs/source/pygeai.core.common.rst +37 -0
  55. pygeai/_docs/source/pygeai.core.embeddings.rst +61 -0
  56. pygeai/_docs/source/pygeai.core.feedback.rst +37 -0
  57. pygeai/_docs/source/pygeai.core.files.rst +61 -0
  58. pygeai/_docs/source/pygeai.core.llm.rst +29 -0
  59. pygeai/_docs/source/pygeai.core.plugins.rst +37 -0
  60. pygeai/_docs/source/pygeai.core.rerank.rst +53 -0
  61. pygeai/_docs/source/pygeai.core.rst +63 -0
  62. pygeai/_docs/source/pygeai.core.secrets.rst +29 -0
  63. pygeai/_docs/source/pygeai.core.services.llm.rst +29 -0
  64. pygeai/_docs/source/pygeai.core.services.rst +37 -0
  65. pygeai/_docs/source/pygeai.core.utils.rst +37 -0
  66. pygeai/_docs/source/pygeai.dbg.rst +21 -0
  67. pygeai/_docs/source/pygeai.evaluation.dataset.rst +29 -0
  68. pygeai/_docs/source/pygeai.evaluation.plan.rst +29 -0
  69. pygeai/_docs/source/pygeai.evaluation.result.rst +29 -0
  70. pygeai/_docs/source/pygeai.evaluation.rst +31 -0
  71. pygeai/_docs/source/pygeai.flows.rst +29 -0
  72. pygeai/_docs/source/pygeai.gam.rst +29 -0
  73. pygeai/_docs/source/pygeai.health.rst +29 -0
  74. pygeai/_docs/source/pygeai.lab.agents.rst +37 -0
  75. pygeai/_docs/source/pygeai.lab.processes.rst +37 -0
  76. pygeai/_docs/source/pygeai.lab.rst +65 -0
  77. pygeai/_docs/source/pygeai.lab.spec.rst +29 -0
  78. pygeai/_docs/source/pygeai.lab.strategies.rst +37 -0
  79. pygeai/_docs/source/pygeai.lab.tools.rst +37 -0
  80. pygeai/_docs/source/pygeai.man.man1.rst +10 -0
  81. pygeai/_docs/source/pygeai.man.rst +18 -0
  82. pygeai/_docs/source/pygeai.migration.rst +29 -0
  83. pygeai/_docs/source/pygeai.organization.limits.rst +45 -0
  84. pygeai/_docs/source/pygeai.organization.rst +61 -0
  85. pygeai/_docs/source/pygeai.proxy.rst +53 -0
  86. pygeai/_docs/source/pygeai.rst +35 -0
  87. pygeai/_docs/source/pygeai.tests.admin.rst +21 -0
  88. pygeai/_docs/source/pygeai.tests.analytics.rst +45 -0
  89. pygeai/_docs/source/pygeai.tests.assistants.rag.rst +37 -0
  90. pygeai/_docs/source/pygeai.tests.assistants.rst +45 -0
  91. pygeai/_docs/source/pygeai.tests.auth.rst +29 -0
  92. pygeai/_docs/source/pygeai.tests.chat.rst +45 -0
  93. pygeai/_docs/source/pygeai.tests.cli.commands.lab.rst +37 -0
  94. pygeai/_docs/source/pygeai.tests.cli.commands.rst +165 -0
  95. pygeai/_docs/source/pygeai.tests.cli.docker.rst +10 -0
  96. pygeai/_docs/source/pygeai.tests.cli.rst +46 -0
  97. pygeai/_docs/source/pygeai.tests.core.base.data.rst +29 -0
  98. pygeai/_docs/source/pygeai.tests.core.base.rst +45 -0
  99. pygeai/_docs/source/pygeai.tests.core.common.data.rst +10 -0
  100. pygeai/_docs/source/pygeai.tests.core.common.rst +37 -0
  101. pygeai/_docs/source/pygeai.tests.core.embeddings.rst +37 -0
  102. pygeai/_docs/source/pygeai.tests.core.feedback.rst +21 -0
  103. pygeai/_docs/source/pygeai.tests.core.files.rst +53 -0
  104. pygeai/_docs/source/pygeai.tests.core.llm.rst +21 -0
  105. pygeai/_docs/source/pygeai.tests.core.plugins.rst +21 -0
  106. pygeai/_docs/source/pygeai.tests.core.rerank.rst +37 -0
  107. pygeai/_docs/source/pygeai.tests.core.rst +39 -0
  108. pygeai/_docs/source/pygeai.tests.core.secrets.rst +21 -0
  109. pygeai/_docs/source/pygeai.tests.core.services.rst +21 -0
  110. pygeai/_docs/source/pygeai.tests.core.utils.rst +21 -0
  111. pygeai/_docs/source/pygeai.tests.dbg.rst +21 -0
  112. pygeai/_docs/source/pygeai.tests.evaluation.dataset.rst +21 -0
  113. pygeai/_docs/source/pygeai.tests.evaluation.plan.rst +21 -0
  114. pygeai/_docs/source/pygeai.tests.evaluation.result.rst +21 -0
  115. pygeai/_docs/source/pygeai.tests.evaluation.rst +20 -0
  116. pygeai/_docs/source/pygeai.tests.gam.rst +21 -0
  117. pygeai/_docs/source/pygeai.tests.health.rst +21 -0
  118. pygeai/_docs/source/pygeai.tests.integration.assistants.rag.rst +21 -0
  119. pygeai/_docs/source/pygeai.tests.integration.assistants.rst +18 -0
  120. pygeai/_docs/source/pygeai.tests.integration.chat.rst +21 -0
  121. pygeai/_docs/source/pygeai.tests.integration.lab.agents.rst +69 -0
  122. pygeai/_docs/source/pygeai.tests.integration.lab.processes.rst +77 -0
  123. pygeai/_docs/source/pygeai.tests.integration.lab.reasoning_strategies.rst +37 -0
  124. pygeai/_docs/source/pygeai.tests.integration.lab.rst +21 -0
  125. pygeai/_docs/source/pygeai.tests.integration.lab.tools.rst +77 -0
  126. pygeai/_docs/source/pygeai.tests.integration.rst +20 -0
  127. pygeai/_docs/source/pygeai.tests.lab.agents.rst +29 -0
  128. pygeai/_docs/source/pygeai.tests.lab.processes.rst +29 -0
  129. pygeai/_docs/source/pygeai.tests.lab.rst +49 -0
  130. pygeai/_docs/source/pygeai.tests.lab.spec.rst +29 -0
  131. pygeai/_docs/source/pygeai.tests.lab.strategies.rst +29 -0
  132. pygeai/_docs/source/pygeai.tests.lab.tools.rst +29 -0
  133. pygeai/_docs/source/pygeai.tests.migration.rst +29 -0
  134. pygeai/_docs/source/pygeai.tests.organization.limits.rst +29 -0
  135. pygeai/_docs/source/pygeai.tests.organization.rst +53 -0
  136. pygeai/_docs/source/pygeai.tests.proxy.rst +61 -0
  137. pygeai/_docs/source/pygeai.tests.rst +33 -0
  138. pygeai/admin/clients.py +14 -11
  139. pygeai/admin/endpoints.py +2 -2
  140. pygeai/analytics/clients.py +505 -0
  141. pygeai/analytics/endpoints.py +35 -0
  142. pygeai/analytics/managers.py +606 -0
  143. pygeai/analytics/mappers.py +207 -0
  144. pygeai/analytics/responses.py +240 -0
  145. pygeai/assistant/clients.py +48 -57
  146. pygeai/assistant/data/__init__.py +0 -0
  147. pygeai/assistant/data/clients.py +15 -0
  148. pygeai/assistant/data_analyst/__init__.py +0 -0
  149. pygeai/assistant/data_analyst/clients.py +75 -0
  150. pygeai/assistant/data_analyst/endpoints.py +2 -0
  151. pygeai/assistant/endpoints.py +0 -2
  152. pygeai/assistant/managers.py +738 -0
  153. pygeai/assistant/mappers.py +153 -0
  154. pygeai/assistant/rag/clients.py +132 -21
  155. pygeai/assistant/rag/mappers.py +228 -0
  156. pygeai/assistant/rag/models.py +396 -0
  157. pygeai/assistant/rag/responses.py +10 -0
  158. pygeai/auth/__init__.py +0 -0
  159. pygeai/auth/clients.py +129 -0
  160. pygeai/auth/endpoints.py +6 -0
  161. pygeai/chat/clients.py +406 -31
  162. pygeai/chat/endpoints.py +3 -0
  163. pygeai/chat/iris.py +17 -0
  164. pygeai/chat/managers.py +64 -0
  165. pygeai/chat/session.py +38 -0
  166. pygeai/chat/settings.py +6 -0
  167. pygeai/chat/ui.py +678 -0
  168. pygeai/cli/__init__.py +0 -1
  169. pygeai/cli/commands/admin.py +9 -12
  170. pygeai/cli/commands/analytics.py +533 -0
  171. pygeai/cli/commands/assistant.py +11 -11
  172. pygeai/cli/commands/auth.py +299 -0
  173. pygeai/cli/commands/base.py +201 -7
  174. pygeai/cli/commands/chat.py +875 -14
  175. pygeai/cli/commands/common.py +30 -26
  176. pygeai/cli/commands/configuration.py +84 -9
  177. pygeai/cli/commands/docs.py +105 -0
  178. pygeai/cli/commands/embeddings.py +187 -0
  179. pygeai/cli/commands/evaluation.py +2069 -0
  180. pygeai/cli/commands/feedback.py +93 -0
  181. pygeai/cli/commands/files.py +312 -0
  182. pygeai/cli/commands/flows/__init__.py +0 -0
  183. pygeai/cli/commands/gam.py +349 -0
  184. pygeai/cli/commands/lab/__init__.py +0 -0
  185. pygeai/cli/commands/lab/ai_lab.py +4110 -0
  186. pygeai/cli/commands/lab/common.py +135 -0
  187. pygeai/cli/commands/lab/options.py +8 -0
  188. pygeai/cli/commands/lab/spec.py +273 -0
  189. pygeai/cli/commands/lab/utils.py +13 -0
  190. pygeai/cli/commands/llm.py +164 -0
  191. pygeai/cli/commands/migrate.py +1198 -0
  192. pygeai/cli/commands/options.py +86 -0
  193. pygeai/cli/commands/organization.py +560 -98
  194. pygeai/cli/commands/rag.py +306 -10
  195. pygeai/cli/commands/rerank.py +108 -0
  196. pygeai/cli/commands/secrets.py +357 -0
  197. pygeai/cli/commands/usage_limits.py +583 -0
  198. pygeai/cli/commands/validators.py +209 -0
  199. pygeai/cli/commands/version.py +44 -0
  200. pygeai/cli/error_handler.py +151 -0
  201. pygeai/cli/geai.py +171 -30
  202. pygeai/cli/geai_proxy.py +318 -0
  203. pygeai/cli/install_man.py +107 -0
  204. pygeai/cli/parsers.py +78 -25
  205. pygeai/cli/texts/help.py +712 -55
  206. pygeai/core/__init__.py +9 -1
  207. pygeai/core/base/clients.py +61 -10
  208. pygeai/core/base/mappers.py +208 -30
  209. pygeai/core/base/models.py +8 -308
  210. pygeai/core/base/responses.py +18 -1
  211. pygeai/core/base/session.py +110 -17
  212. pygeai/core/common/config.py +98 -16
  213. pygeai/core/common/decorators.py +44 -0
  214. pygeai/core/common/exceptions.py +104 -4
  215. pygeai/core/embeddings/__init__.py +19 -0
  216. pygeai/core/embeddings/clients.py +93 -0
  217. pygeai/core/embeddings/endpoints.py +1 -0
  218. pygeai/core/embeddings/managers.py +62 -0
  219. pygeai/core/embeddings/mappers.py +52 -0
  220. pygeai/core/embeddings/models.py +14 -0
  221. pygeai/core/embeddings/responses.py +31 -0
  222. pygeai/core/feedback/__init__.py +0 -0
  223. pygeai/core/feedback/clients.py +50 -0
  224. pygeai/core/feedback/endpoints.py +1 -0
  225. pygeai/core/feedback/models.py +10 -0
  226. pygeai/core/files/__init__.py +0 -0
  227. pygeai/core/files/clients.py +156 -0
  228. pygeai/core/files/endpoints.py +5 -0
  229. pygeai/core/files/managers.py +224 -0
  230. pygeai/core/files/mappers.py +44 -0
  231. pygeai/core/files/models.py +24 -0
  232. pygeai/core/files/responses.py +19 -0
  233. pygeai/core/handlers.py +32 -0
  234. pygeai/core/llm/__init__.py +0 -0
  235. pygeai/core/llm/clients.py +53 -0
  236. pygeai/core/llm/endpoints.py +4 -0
  237. pygeai/core/models.py +799 -0
  238. pygeai/core/plugins/__init__.py +0 -0
  239. pygeai/core/plugins/clients.py +32 -0
  240. pygeai/core/plugins/endpoints.py +1 -0
  241. pygeai/core/plugins/models.py +86 -0
  242. pygeai/core/rerank/__init__.py +0 -0
  243. pygeai/core/rerank/clients.py +35 -0
  244. pygeai/core/rerank/endpoints.py +1 -0
  245. pygeai/core/rerank/managers.py +47 -0
  246. pygeai/core/rerank/mappers.py +23 -0
  247. pygeai/core/rerank/models.py +27 -0
  248. pygeai/core/responses.py +104 -0
  249. pygeai/core/secrets/__init__.py +0 -0
  250. pygeai/core/secrets/clients.py +212 -0
  251. pygeai/core/secrets/endpoints.py +7 -0
  252. pygeai/core/services/llm/__init__.py +0 -0
  253. pygeai/core/services/llm/model.py +186 -0
  254. pygeai/core/services/llm/providers.py +15 -0
  255. pygeai/core/services/response.py +18 -0
  256. pygeai/core/services/rest.py +311 -89
  257. pygeai/core/utils/__init__.py +0 -0
  258. pygeai/core/utils/console.py +83 -0
  259. pygeai/core/utils/parsers.py +32 -0
  260. pygeai/core/utils/validators.py +10 -0
  261. pygeai/dbg/__init__.py +3 -0
  262. pygeai/dbg/debugger.py +870 -0
  263. pygeai/evaluation/__init__.py +0 -0
  264. pygeai/evaluation/clients.py +19 -0
  265. pygeai/evaluation/dataset/__init__.py +0 -0
  266. pygeai/evaluation/dataset/clients.py +514 -0
  267. pygeai/evaluation/dataset/endpoints.py +26 -0
  268. pygeai/evaluation/plan/__init__.py +0 -0
  269. pygeai/evaluation/plan/clients.py +302 -0
  270. pygeai/evaluation/plan/endpoints.py +16 -0
  271. pygeai/evaluation/result/__init__.py +0 -0
  272. pygeai/evaluation/result/clients.py +70 -0
  273. pygeai/evaluation/result/endpoints.py +2 -0
  274. pygeai/flows/__init__.py +0 -0
  275. pygeai/flows/endpoints.py +362 -0
  276. pygeai/flows/models.py +1304 -0
  277. pygeai/gam/__init__.py +0 -0
  278. pygeai/gam/clients.py +178 -0
  279. pygeai/gam/endpoints.py +4 -0
  280. pygeai/health/__init__.py +0 -0
  281. pygeai/health/clients.py +24 -0
  282. pygeai/health/endpoints.py +1 -0
  283. pygeai/lab/__init__.py +0 -0
  284. pygeai/lab/agents/__init__.py +0 -0
  285. pygeai/lab/agents/clients.py +426 -0
  286. pygeai/lab/agents/endpoints.py +12 -0
  287. pygeai/lab/agents/mappers.py +319 -0
  288. pygeai/lab/clients.py +24 -0
  289. pygeai/lab/constants.py +3 -0
  290. pygeai/lab/managers.py +1558 -0
  291. pygeai/lab/models.py +1719 -0
  292. pygeai/lab/processes/__init__.py +0 -0
  293. pygeai/lab/processes/clients.py +1051 -0
  294. pygeai/lab/processes/endpoints.py +26 -0
  295. pygeai/lab/processes/mappers.py +395 -0
  296. pygeai/lab/runners.py +90 -0
  297. pygeai/lab/spec/__init__.py +0 -0
  298. pygeai/lab/spec/loader.py +24 -0
  299. pygeai/lab/spec/parsers.py +39 -0
  300. pygeai/lab/strategies/__init__.py +0 -0
  301. pygeai/lab/strategies/clients.py +212 -0
  302. pygeai/lab/strategies/endpoints.py +5 -0
  303. pygeai/lab/strategies/mappers.py +58 -0
  304. pygeai/lab/tools/__init__.py +0 -0
  305. pygeai/lab/tools/clients.py +465 -0
  306. pygeai/lab/tools/endpoints.py +13 -0
  307. pygeai/lab/tools/mappers.py +131 -0
  308. pygeai/man/__init__.py +1 -0
  309. pygeai/man/man1/__init__.py +1 -0
  310. pygeai/man/man1/geai-proxy.1 +246 -0
  311. pygeai/man/man1/geai.1 +2615 -0
  312. pygeai/migration/__init__.py +33 -0
  313. pygeai/migration/strategies.py +603 -0
  314. pygeai/migration/tools.py +180 -0
  315. pygeai/organization/clients.py +246 -18
  316. pygeai/organization/endpoints.py +17 -8
  317. pygeai/organization/limits/__init__.py +0 -0
  318. pygeai/organization/limits/clients.py +281 -0
  319. pygeai/organization/limits/endpoints.py +15 -0
  320. pygeai/organization/limits/managers.py +331 -0
  321. pygeai/organization/limits/mappers.py +21 -0
  322. pygeai/organization/managers.py +537 -0
  323. pygeai/organization/mappers.py +111 -46
  324. pygeai/organization/responses.py +61 -11
  325. pygeai/proxy/__init__.py +0 -0
  326. pygeai/proxy/clients.py +216 -0
  327. pygeai/proxy/config.py +128 -0
  328. pygeai/proxy/managers.py +232 -0
  329. pygeai/proxy/servers.py +304 -0
  330. pygeai/proxy/tool.py +69 -0
  331. pygeai/tests/admin/__init__.py +0 -0
  332. pygeai/tests/admin/test_clients.py +148 -0
  333. pygeai/tests/analytics/__init__.py +0 -0
  334. pygeai/tests/analytics/test_clients.py +86 -0
  335. pygeai/tests/analytics/test_managers.py +94 -0
  336. pygeai/tests/analytics/test_mappers.py +84 -0
  337. pygeai/tests/analytics/test_responses.py +73 -0
  338. pygeai/tests/assistants/rag/__init__.py +0 -0
  339. pygeai/tests/assistants/rag/test_clients.py +346 -0
  340. pygeai/tests/assistants/rag/test_mappers.py +189 -0
  341. pygeai/tests/assistants/rag/test_models.py +292 -0
  342. pygeai/tests/assistants/test_clients.py +176 -80
  343. pygeai/tests/assistants/test_managers.py +198 -0
  344. pygeai/tests/assistants/test_mappers.py +111 -0
  345. pygeai/tests/auth/__init__.py +0 -0
  346. pygeai/tests/auth/test_clients.py +289 -0
  347. pygeai/tests/auth/test_oauth.py +172 -0
  348. pygeai/tests/auth/test_session_logging.py +150 -0
  349. pygeai/tests/chat/__init__.py +0 -0
  350. pygeai/tests/chat/test_clients.py +393 -0
  351. pygeai/tests/chat/test_iris.py +38 -0
  352. pygeai/tests/chat/test_session.py +62 -0
  353. pygeai/tests/chat/test_ui.py +224 -0
  354. pygeai/tests/cli/__init__.py +0 -0
  355. pygeai/tests/cli/commands/__init__.py +0 -0
  356. pygeai/tests/cli/commands/lab/__init__.py +0 -0
  357. pygeai/tests/cli/commands/lab/test_ai_lab.py +786 -0
  358. pygeai/tests/cli/commands/lab/test_common.py +208 -0
  359. pygeai/tests/cli/commands/lab/test_spec.py +246 -0
  360. pygeai/tests/cli/commands/test_assistant.py +202 -0
  361. pygeai/tests/cli/commands/test_chat.py +130 -0
  362. pygeai/tests/cli/commands/test_common.py +350 -0
  363. pygeai/tests/cli/commands/test_embeddings.py +132 -0
  364. pygeai/tests/cli/commands/test_evaluation.py +656 -0
  365. pygeai/tests/cli/commands/test_feedback.py +65 -0
  366. pygeai/tests/cli/commands/test_files.py +161 -0
  367. pygeai/tests/cli/commands/test_gam.py +201 -0
  368. pygeai/tests/cli/commands/test_llm.py +114 -0
  369. pygeai/tests/cli/commands/test_migrate.py +176 -0
  370. pygeai/tests/cli/commands/test_organization.py +276 -0
  371. pygeai/tests/cli/commands/test_rag.py +266 -0
  372. pygeai/tests/cli/commands/test_rerank.py +110 -0
  373. pygeai/tests/cli/commands/test_secrets.py +171 -0
  374. pygeai/tests/cli/commands/test_show_help.py +41 -0
  375. pygeai/tests/cli/commands/test_usage_limits.py +412 -0
  376. pygeai/tests/cli/commands/test_validators.py +160 -0
  377. pygeai/tests/cli/commands/test_version.py +81 -0
  378. pygeai/tests/cli/docker/__init__.py +0 -0
  379. pygeai/tests/cli/test_credentials_flag.py +316 -0
  380. pygeai/tests/cli/test_error_handler.py +225 -0
  381. pygeai/tests/cli/test_geai_driver.py +154 -0
  382. pygeai/tests/cli/test_parsers.py +154 -0
  383. pygeai/tests/core/base/__init__.py +0 -0
  384. pygeai/tests/core/base/data/__init__.py +0 -0
  385. pygeai/tests/core/base/data/mappers.py +117 -0
  386. pygeai/tests/core/base/data/models.py +312 -0
  387. pygeai/tests/core/base/test_mappers.py +569 -0
  388. pygeai/tests/core/base/test_models.py +261 -0
  389. pygeai/tests/core/base/test_responses.py +53 -0
  390. pygeai/tests/core/common/__init__.py +0 -0
  391. pygeai/tests/core/common/data/__init__.py +0 -0
  392. pygeai/tests/core/common/test_config.py +186 -0
  393. pygeai/tests/core/common/test_decorators.py +69 -0
  394. pygeai/tests/core/embeddings/__init__.py +0 -0
  395. pygeai/tests/core/embeddings/test_clients.py +225 -0
  396. pygeai/tests/core/embeddings/test_managers.py +171 -0
  397. pygeai/tests/core/embeddings/test_mappers.py +142 -0
  398. pygeai/tests/core/feedback/__init__.py +0 -0
  399. pygeai/tests/core/feedback/test_clients.py +64 -0
  400. pygeai/tests/core/files/__init__.py +0 -0
  401. pygeai/tests/core/files/test_clients.py +128 -0
  402. pygeai/tests/core/files/test_managers.py +219 -0
  403. pygeai/tests/core/files/test_mappers.py +137 -0
  404. pygeai/tests/core/files/test_models.py +103 -0
  405. pygeai/tests/core/files/test_responses.py +122 -0
  406. pygeai/tests/core/llm/__init__.py +0 -0
  407. pygeai/tests/core/llm/test_clients.py +142 -0
  408. pygeai/tests/core/plugins/__init__.py +0 -0
  409. pygeai/tests/core/plugins/test_clients.py +66 -0
  410. pygeai/tests/core/rerank/__init__.py +0 -0
  411. pygeai/tests/core/rerank/test_clients.py +76 -0
  412. pygeai/tests/core/rerank/test_managers.py +99 -0
  413. pygeai/tests/core/rerank/test_mappers.py +54 -0
  414. pygeai/tests/core/secrets/__init__.py +0 -0
  415. pygeai/tests/core/secrets/test_clients.py +264 -0
  416. pygeai/tests/core/services/__init__.py +0 -0
  417. pygeai/tests/core/services/test_rest.py +273 -0
  418. pygeai/tests/core/test_handlers.py +66 -0
  419. pygeai/tests/core/utils/__init__.py +0 -0
  420. pygeai/tests/core/utils/test_console.py +80 -0
  421. pygeai/tests/dbg/__init__.py +0 -0
  422. pygeai/tests/dbg/test_debugger.py +591 -0
  423. pygeai/tests/evaluation/__init__.py +0 -0
  424. pygeai/tests/evaluation/dataset/__init__.py +0 -0
  425. pygeai/tests/evaluation/dataset/test_clients.py +265 -0
  426. pygeai/tests/evaluation/plan/__init__.py +0 -0
  427. pygeai/tests/evaluation/plan/test_clients.py +195 -0
  428. pygeai/tests/evaluation/result/__init__.py +0 -0
  429. pygeai/tests/evaluation/result/test_clients.py +66 -0
  430. pygeai/tests/gam/__init__.py +0 -0
  431. pygeai/tests/gam/test_clients.py +195 -0
  432. pygeai/tests/health/__init__.py +0 -0
  433. pygeai/tests/health/test_clients.py +41 -0
  434. pygeai/tests/integration/__init__.py +0 -0
  435. pygeai/tests/integration/assistants/__init__.py +0 -0
  436. pygeai/tests/integration/assistants/rag/__init__.py +0 -0
  437. pygeai/tests/integration/assistants/rag/test_create_rag.py +91 -0
  438. pygeai/tests/integration/chat/__init__.py +0 -0
  439. pygeai/tests/integration/chat/test_generate_image.py +158 -0
  440. pygeai/tests/integration/lab/__init__.py +0 -0
  441. pygeai/tests/integration/lab/agents/__init__.py +0 -0
  442. pygeai/tests/integration/lab/agents/test_agents_list.py +106 -0
  443. pygeai/tests/integration/lab/agents/test_create_agent.py +319 -0
  444. pygeai/tests/integration/lab/agents/test_create_sharing_link.py +70 -0
  445. pygeai/tests/integration/lab/agents/test_delete_agent.py +75 -0
  446. pygeai/tests/integration/lab/agents/test_get_agent.py +94 -0
  447. pygeai/tests/integration/lab/agents/test_publish_agent_revision.py +127 -0
  448. pygeai/tests/integration/lab/agents/test_update_agent.py +250 -0
  449. pygeai/tests/integration/lab/processes/__init__.py +0 -0
  450. pygeai/tests/integration/lab/processes/test_create_process.py +345 -0
  451. pygeai/tests/integration/lab/processes/test_create_task.py +211 -0
  452. pygeai/tests/integration/lab/processes/test_delete_process.py +111 -0
  453. pygeai/tests/integration/lab/processes/test_get_process.py +201 -0
  454. pygeai/tests/integration/lab/processes/test_list_process_instances.py +91 -0
  455. pygeai/tests/integration/lab/processes/test_list_processes.py +138 -0
  456. pygeai/tests/integration/lab/processes/test_publish_process_revision.py +232 -0
  457. pygeai/tests/integration/lab/processes/test_update_process.py +289 -0
  458. pygeai/tests/integration/lab/reasoning_strategies/__init__.py +0 -0
  459. pygeai/tests/integration/lab/reasoning_strategies/test_get_reasoning_strategy.py +70 -0
  460. pygeai/tests/integration/lab/reasoning_strategies/test_list_reasoning_strategies.py +93 -0
  461. pygeai/tests/integration/lab/reasoning_strategies/test_update_reasoning_strategy.py +149 -0
  462. pygeai/tests/integration/lab/tools/__init__.py +0 -0
  463. pygeai/tests/integration/lab/tools/test_create_tool.py +288 -0
  464. pygeai/tests/integration/lab/tools/test_delete_tool.py +87 -0
  465. pygeai/tests/integration/lab/tools/test_get_parameter.py +98 -0
  466. pygeai/tests/integration/lab/tools/test_get_tool.py +91 -0
  467. pygeai/tests/integration/lab/tools/test_list_tools.py +106 -0
  468. pygeai/tests/integration/lab/tools/test_publish_tool_revision.py +119 -0
  469. pygeai/tests/integration/lab/tools/test_set_parameter.py +114 -0
  470. pygeai/tests/integration/lab/tools/test_update_tool.py +267 -0
  471. pygeai/tests/lab/__init__.py +0 -0
  472. pygeai/tests/lab/agents/__init__.py +0 -0
  473. pygeai/tests/lab/agents/test_clients.py +481 -0
  474. pygeai/tests/lab/agents/test_mappers.py +440 -0
  475. pygeai/tests/lab/processes/__init__.py +0 -0
  476. pygeai/tests/lab/processes/test_clients.py +1416 -0
  477. pygeai/tests/lab/processes/test_mappers.py +1092 -0
  478. pygeai/tests/lab/spec/__init__.py +0 -0
  479. pygeai/tests/lab/spec/test_loader.py +59 -0
  480. pygeai/tests/lab/spec/test_parsers.py +182 -0
  481. pygeai/tests/lab/strategies/__init__.py +0 -0
  482. pygeai/tests/lab/strategies/test_clients.py +241 -0
  483. pygeai/tests/lab/strategies/test_mappers.py +132 -0
  484. pygeai/tests/lab/test_managers.py +553 -0
  485. pygeai/tests/lab/test_mappers.py +245 -0
  486. pygeai/tests/lab/test_models.py +1154 -0
  487. pygeai/tests/lab/tools/__init__.py +0 -0
  488. pygeai/tests/lab/tools/test_clients.py +521 -0
  489. pygeai/tests/lab/tools/test_mappers.py +198 -0
  490. pygeai/tests/migration/__init__.py +0 -0
  491. pygeai/tests/migration/test_strategies.py +405 -0
  492. pygeai/tests/migration/test_tools.py +159 -0
  493. pygeai/tests/organization/limits/__init__.py +0 -0
  494. pygeai/tests/organization/limits/test_clients.py +567 -0
  495. pygeai/tests/organization/limits/test_managers.py +402 -0
  496. pygeai/tests/organization/test_clients.py +615 -64
  497. pygeai/tests/organization/test_managers.py +424 -0
  498. pygeai/tests/organization/test_mappers.py +153 -0
  499. pygeai/tests/organization/test_responses.py +137 -0
  500. pygeai/tests/proxy/__init__.py +1 -0
  501. pygeai/tests/proxy/test_clients.py +397 -0
  502. pygeai/tests/proxy/test_config.py +171 -0
  503. pygeai/tests/proxy/test_integration.py +305 -0
  504. pygeai/tests/proxy/test_managers.py +312 -0
  505. pygeai/tests/proxy/test_servers.py +387 -0
  506. pygeai/tests/proxy/test_tool.py +176 -0
  507. pygeai/tests/snippets/__init__.py +0 -0
  508. pygeai/tests/snippets/analytics/__init__.py +0 -0
  509. pygeai/tests/snippets/analytics/get_agent_usage_per_user.py +16 -0
  510. pygeai/tests/snippets/analytics/get_agents_created_and_modified.py +11 -0
  511. pygeai/tests/snippets/analytics/get_average_cost_per_request.py +10 -0
  512. pygeai/tests/snippets/analytics/get_overall_error_rate.py +10 -0
  513. pygeai/tests/snippets/analytics/get_top_10_agents_by_requests.py +12 -0
  514. pygeai/tests/snippets/analytics/get_total_active_users.py +10 -0
  515. pygeai/tests/snippets/analytics/get_total_cost.py +10 -0
  516. pygeai/tests/snippets/analytics/get_total_requests_per_day.py +12 -0
  517. pygeai/tests/snippets/analytics/get_total_tokens.py +12 -0
  518. pygeai/tests/snippets/assistants/__init__.py +0 -0
  519. pygeai/tests/snippets/assistants/create_chat_assistant.py +54 -0
  520. pygeai/tests/snippets/assistants/create_text_assistant.py +51 -0
  521. pygeai/tests/snippets/assistants/data_analyst/__init__.py +0 -0
  522. pygeai/tests/snippets/assistants/data_analyst/extend_and_check.py +100 -0
  523. pygeai/tests/snippets/assistants/data_analyst/extend_dataset.py +9 -0
  524. pygeai/tests/snippets/assistants/data_analyst/get_status.py +9 -0
  525. pygeai/tests/snippets/assistants/file_summarizer_assistant.py +149 -0
  526. pygeai/tests/snippets/assistants/get_assistant_data.py +8 -0
  527. pygeai/tests/snippets/assistants/get_assistant_list.py +7 -0
  528. pygeai/tests/snippets/assistants/rag/__init__.py +0 -0
  529. pygeai/tests/snippets/assistants/rag/create_rag_assistant.py +65 -0
  530. pygeai/tests/snippets/assistants/rag/delete_al_documents.py +7 -0
  531. pygeai/tests/snippets/assistants/rag/delete_document.py +10 -0
  532. pygeai/tests/snippets/assistants/rag/delete_rag_assistant.py +8 -0
  533. pygeai/tests/snippets/assistants/rag/get_document.py +10 -0
  534. pygeai/tests/snippets/assistants/rag/get_documents.py +7 -0
  535. pygeai/tests/snippets/assistants/rag/get_rag_assistant_data.py +8 -0
  536. pygeai/tests/snippets/assistants/rag/update_rag_assistant.py +48 -0
  537. pygeai/tests/snippets/assistants/rag/upload_document.py +19 -0
  538. pygeai/tests/snippets/assistants/send_feedback.py +14 -0
  539. pygeai/tests/snippets/assistants/update_chat_assistant.py +63 -0
  540. pygeai/tests/snippets/auth/__init__.py +0 -0
  541. pygeai/tests/snippets/chat/__init__.py +0 -0
  542. pygeai/tests/snippets/chat/cancel_request.py +7 -0
  543. pygeai/tests/snippets/chat/chat_completion.py +28 -0
  544. pygeai/tests/snippets/chat/chat_completion_1.py +40 -0
  545. pygeai/tests/snippets/chat/chat_completion_2.py +60 -0
  546. pygeai/tests/snippets/chat/chat_completion_3.py +27 -0
  547. pygeai/tests/snippets/chat/chat_completion_4.py +67 -0
  548. pygeai/tests/snippets/chat/chat_completion_streaming.py +63 -0
  549. pygeai/tests/snippets/chat/chat_completion_with_reasoning_effort.py +18 -0
  550. pygeai/tests/snippets/chat/get_request_status.py +7 -0
  551. pygeai/tests/snippets/chat/get_response.py +15 -0
  552. pygeai/tests/snippets/chat/get_response_complete_example.py +67 -0
  553. pygeai/tests/snippets/chat/get_response_streaming.py +20 -0
  554. pygeai/tests/snippets/chat/get_response_with_files.py +16 -0
  555. pygeai/tests/snippets/chat/get_response_with_instructions.py +19 -0
  556. pygeai/tests/snippets/chat/get_response_with_metadata.py +24 -0
  557. pygeai/tests/snippets/chat/get_response_with_parallel_tools.py +58 -0
  558. pygeai/tests/snippets/chat/get_response_with_reasoning.py +21 -0
  559. pygeai/tests/snippets/chat/get_response_with_store.py +38 -0
  560. pygeai/tests/snippets/chat/get_response_with_tools.py +36 -0
  561. pygeai/tests/snippets/chat/get_response_with_truncation.py +24 -0
  562. pygeai/tests/snippets/chat/send_chat_request.py +33 -0
  563. pygeai/tests/snippets/dbg/__init__.py +0 -0
  564. pygeai/tests/snippets/dbg/basic_debugging.py +32 -0
  565. pygeai/tests/snippets/dbg/breakpoint_management.py +48 -0
  566. pygeai/tests/snippets/dbg/file_debugging.py +72 -0
  567. pygeai/tests/snippets/dbg/module_debugging.py +61 -0
  568. pygeai/tests/snippets/dbg/stack_navigation.py +45 -0
  569. pygeai/tests/snippets/dbg/stepping_example.py +40 -0
  570. pygeai/tests/snippets/embeddings/__init__.py +0 -0
  571. pygeai/tests/snippets/embeddings/cache_example.py +31 -0
  572. pygeai/tests/snippets/embeddings/cohere_example.py +41 -0
  573. pygeai/tests/snippets/embeddings/generate_embeddings.py +26 -0
  574. pygeai/tests/snippets/embeddings/openai_base64_example.py +27 -0
  575. pygeai/tests/snippets/embeddings/openai_example.py +30 -0
  576. pygeai/tests/snippets/embeddings/similarity_example.py +42 -0
  577. pygeai/tests/snippets/evaluation/__init__.py +0 -0
  578. pygeai/tests/snippets/evaluation/dataset/__init__.py +0 -0
  579. pygeai/tests/snippets/evaluation/dataset/complete_workflow_example.py +195 -0
  580. pygeai/tests/snippets/evaluation/dataset/create_dataset.py +26 -0
  581. pygeai/tests/snippets/evaluation/dataset/create_dataset_from_file.py +11 -0
  582. pygeai/tests/snippets/evaluation/dataset/create_dataset_row.py +17 -0
  583. pygeai/tests/snippets/evaluation/dataset/create_expected_source.py +18 -0
  584. pygeai/tests/snippets/evaluation/dataset/create_filter_variable.py +19 -0
  585. pygeai/tests/snippets/evaluation/dataset/delete_dataset.py +9 -0
  586. pygeai/tests/snippets/evaluation/dataset/delete_dataset_row.py +10 -0
  587. pygeai/tests/snippets/evaluation/dataset/delete_expected_source.py +15 -0
  588. pygeai/tests/snippets/evaluation/dataset/delete_filter_variable.py +15 -0
  589. pygeai/tests/snippets/evaluation/dataset/get_dataset.py +9 -0
  590. pygeai/tests/snippets/evaluation/dataset/get_dataset_row.py +10 -0
  591. pygeai/tests/snippets/evaluation/dataset/get_expected_source.py +15 -0
  592. pygeai/tests/snippets/evaluation/dataset/get_filter_variable.py +15 -0
  593. pygeai/tests/snippets/evaluation/dataset/list_dataset_rows.py +9 -0
  594. pygeai/tests/snippets/evaluation/dataset/list_datasets.py +6 -0
  595. pygeai/tests/snippets/evaluation/dataset/list_expected_sources.py +10 -0
  596. pygeai/tests/snippets/evaluation/dataset/list_filter_variables.py +10 -0
  597. pygeai/tests/snippets/evaluation/dataset/update_dataset.py +15 -0
  598. pygeai/tests/snippets/evaluation/dataset/update_dataset_row.py +20 -0
  599. pygeai/tests/snippets/evaluation/dataset/update_expected_source.py +18 -0
  600. pygeai/tests/snippets/evaluation/dataset/update_filter_variable.py +19 -0
  601. pygeai/tests/snippets/evaluation/dataset/upload_dataset_rows_file.py +10 -0
  602. pygeai/tests/snippets/evaluation/plan/__init__.py +0 -0
  603. pygeai/tests/snippets/evaluation/plan/add_plan_system_metric.py +13 -0
  604. pygeai/tests/snippets/evaluation/plan/complete_workflow_example.py +136 -0
  605. pygeai/tests/snippets/evaluation/plan/create_evaluation_plan.py +24 -0
  606. pygeai/tests/snippets/evaluation/plan/create_rag_evaluation_plan.py +22 -0
  607. pygeai/tests/snippets/evaluation/plan/delete_evaluation_plan.py +9 -0
  608. pygeai/tests/snippets/evaluation/plan/delete_plan_system_metric.py +13 -0
  609. pygeai/tests/snippets/evaluation/plan/execute_evaluation_plan.py +11 -0
  610. pygeai/tests/snippets/evaluation/plan/get_evaluation_plan.py +9 -0
  611. pygeai/tests/snippets/evaluation/plan/get_plan_system_metric.py +13 -0
  612. pygeai/tests/snippets/evaluation/plan/get_system_metric.py +9 -0
  613. pygeai/tests/snippets/evaluation/plan/list_evaluation_plans.py +7 -0
  614. pygeai/tests/snippets/evaluation/plan/list_plan_system_metrics.py +9 -0
  615. pygeai/tests/snippets/evaluation/plan/list_system_metrics.py +7 -0
  616. pygeai/tests/snippets/evaluation/plan/update_evaluation_plan.py +22 -0
  617. pygeai/tests/snippets/evaluation/plan/update_plan_system_metric.py +14 -0
  618. pygeai/tests/snippets/evaluation/result/__init__.py +0 -0
  619. pygeai/tests/snippets/evaluation/result/complete_workflow_example.py +150 -0
  620. pygeai/tests/snippets/evaluation/result/get_evaluation_result.py +26 -0
  621. pygeai/tests/snippets/evaluation/result/list_evaluation_results.py +17 -0
  622. pygeai/tests/snippets/files/__init__.py +0 -0
  623. pygeai/tests/snippets/files/delete_file.py +9 -0
  624. pygeai/tests/snippets/files/get_file_content.py +10 -0
  625. pygeai/tests/snippets/files/get_file_data.py +9 -0
  626. pygeai/tests/snippets/files/get_file_list.py +6 -0
  627. pygeai/tests/snippets/files/upload_file.py +13 -0
  628. pygeai/tests/snippets/gam/__init__.py +0 -0
  629. pygeai/tests/snippets/gam/gam_access_token.py +87 -0
  630. pygeai/tests/snippets/lab/__init__.py +0 -0
  631. pygeai/tests/snippets/lab/agentic_flow_example_1.py +326 -0
  632. pygeai/tests/snippets/lab/agentic_flow_example_2.py +206 -0
  633. pygeai/tests/snippets/lab/agentic_flow_example_3.py +486 -0
  634. pygeai/tests/snippets/lab/agentic_flow_example_4.py +446 -0
  635. pygeai/tests/snippets/lab/agents/__init__.py +0 -0
  636. pygeai/tests/snippets/lab/agents/create_agent.py +48 -0
  637. pygeai/tests/snippets/lab/agents/create_agent_2.py +48 -0
  638. pygeai/tests/snippets/lab/agents/create_agent_edge_case.py +48 -0
  639. pygeai/tests/snippets/lab/agents/create_agent_with_permissions.py +39 -0
  640. pygeai/tests/snippets/lab/agents/create_agent_with_properties.py +46 -0
  641. pygeai/tests/snippets/lab/agents/create_agent_without_instructions.py +48 -0
  642. pygeai/tests/snippets/lab/agents/delete_agent.py +12 -0
  643. pygeai/tests/snippets/lab/agents/get_agent.py +24 -0
  644. pygeai/tests/snippets/lab/agents/get_agent_with_new_fields.py +62 -0
  645. pygeai/tests/snippets/lab/agents/get_sharing_link.py +13 -0
  646. pygeai/tests/snippets/lab/agents/list_agents.py +18 -0
  647. pygeai/tests/snippets/lab/agents/publish_agent_revision.py +12 -0
  648. pygeai/tests/snippets/lab/agents/update_agent.py +50 -0
  649. pygeai/tests/snippets/lab/agents/update_agent_properties.py +50 -0
  650. pygeai/tests/snippets/lab/assistant_to_agent.py +191 -0
  651. pygeai/tests/snippets/lab/crud_ui.py +462 -0
  652. pygeai/tests/snippets/lab/processes/__init__.py +0 -0
  653. pygeai/tests/snippets/lab/processes/create_process.py +24 -0
  654. pygeai/tests/snippets/lab/processes/create_task.py +8 -0
  655. pygeai/tests/snippets/lab/processes/jobs/__init__.py +0 -0
  656. pygeai/tests/snippets/lab/processes/jobs/list_jobs.py +21 -0
  657. pygeai/tests/snippets/lab/processes/kbs/__init__.py +0 -0
  658. pygeai/tests/snippets/lab/processes/kbs/create_kb.py +18 -0
  659. pygeai/tests/snippets/lab/processes/kbs/get_kb.py +26 -0
  660. pygeai/tests/snippets/lab/processes/kbs/list_kbs.py +30 -0
  661. pygeai/tests/snippets/lab/processes/kbs/try_all.py +73 -0
  662. pygeai/tests/snippets/lab/processes/list_processes.py +10 -0
  663. pygeai/tests/snippets/lab/runner_1.py +212 -0
  664. pygeai/tests/snippets/lab/samples/__init__.py +0 -0
  665. pygeai/tests/snippets/lab/samples/summarize_files.py +162 -0
  666. pygeai/tests/snippets/lab/strategies/__init__.py +0 -0
  667. pygeai/tests/snippets/lab/strategies/create_reasoning_strategy.py +22 -0
  668. pygeai/tests/snippets/lab/strategies/get_reasoning_strategy.py +10 -0
  669. pygeai/tests/snippets/lab/strategies/list_reasoning_strategies.py +16 -0
  670. pygeai/tests/snippets/lab/strategies/update_reasoning_strategy.py +26 -0
  671. pygeai/tests/snippets/lab/tools/__init__.py +0 -0
  672. pygeai/tests/snippets/lab/tools/create_tool.py +48 -0
  673. pygeai/tests/snippets/lab/tools/create_tool_edge_case.py +50 -0
  674. pygeai/tests/snippets/lab/tools/delete_tool.py +21 -0
  675. pygeai/tests/snippets/lab/tools/get_parameter.py +21 -0
  676. pygeai/tests/snippets/lab/tools/get_tool.py +22 -0
  677. pygeai/tests/snippets/lab/tools/list_tools.py +23 -0
  678. pygeai/tests/snippets/lab/tools/publish_tool_revision.py +13 -0
  679. pygeai/tests/snippets/lab/tools/set_parameters.py +33 -0
  680. pygeai/tests/snippets/lab/tools/update_tool.py +52 -0
  681. pygeai/tests/snippets/lab/use_cases/__init__.py +0 -0
  682. pygeai/tests/snippets/lab/use_cases/c_code_fixer_agent_flow.py +238 -0
  683. pygeai/tests/snippets/lab/use_cases/create_cli_expert.py +1640 -0
  684. pygeai/tests/snippets/lab/use_cases/create_lab_expert.py +4541 -0
  685. pygeai/tests/snippets/lab/use_cases/create_tool_headless_web_browser.py +133 -0
  686. pygeai/tests/snippets/lab/use_cases/create_web_designer.py +189 -0
  687. pygeai/tests/snippets/lab/use_cases/create_web_reader.py +185 -0
  688. pygeai/tests/snippets/lab/use_cases/file_summarizer_example.py +157 -0
  689. pygeai/tests/snippets/lab/use_cases/file_summarizer_example_2.py +157 -0
  690. pygeai/tests/snippets/lab/use_cases/update_cli_expert.py +1773 -0
  691. pygeai/tests/snippets/lab/use_cases/update_lab_expert.py +4541 -0
  692. pygeai/tests/snippets/lab/use_cases/update_web_designer.py +188 -0
  693. pygeai/tests/snippets/lab/use_cases/update_web_reader.py +195 -0
  694. pygeai/tests/snippets/lab/use_cases/update_web_reader_with_tool.py +210 -0
  695. pygeai/tests/snippets/migrate/__init__.py +45 -0
  696. pygeai/tests/snippets/migrate/agent_migration.py +110 -0
  697. pygeai/tests/snippets/migrate/assistant_migration.py +64 -0
  698. pygeai/tests/snippets/migrate/orchestrator_examples.py +179 -0
  699. pygeai/tests/snippets/migrate/process_migration.py +64 -0
  700. pygeai/tests/snippets/migrate/project_migration.py +42 -0
  701. pygeai/tests/snippets/migrate/tool_migration.py +64 -0
  702. pygeai/tests/snippets/organization/__init__.py +0 -0
  703. pygeai/tests/snippets/organization/add_project_member.py +10 -0
  704. pygeai/tests/snippets/organization/add_project_member_batch.py +44 -0
  705. pygeai/tests/snippets/organization/create_project.py +23 -0
  706. pygeai/tests/snippets/organization/delete_project.py +7 -0
  707. pygeai/tests/snippets/organization/export_request_data.py +7 -0
  708. pygeai/tests/snippets/organization/get_memberships.py +12 -0
  709. pygeai/tests/snippets/organization/get_organization_members.py +6 -0
  710. pygeai/tests/snippets/organization/get_project_data.py +7 -0
  711. pygeai/tests/snippets/organization/get_project_list.py +8 -0
  712. pygeai/tests/snippets/organization/get_project_members.py +6 -0
  713. pygeai/tests/snippets/organization/get_project_memberships.py +12 -0
  714. pygeai/tests/snippets/organization/get_project_roles.py +6 -0
  715. pygeai/tests/snippets/organization/get_project_tokens.py +7 -0
  716. pygeai/tests/snippets/organization/update_project.py +14 -0
  717. pygeai/tests/snippets/rerank/__init__.py +0 -0
  718. pygeai/tests/snippets/rerank/rerank_chunks.py +19 -0
  719. pygeai/tests/snippets/secrets/__init__.py +0 -0
  720. pygeai/tests/snippets/usage_limit/__init__.py +0 -0
  721. pygeai/tests/snippets/usage_limit/delete_usage_limit.py +16 -0
  722. pygeai/tests/snippets/usage_limit/get_all_usage_limit_from_organization.py +12 -0
  723. pygeai/tests/snippets/usage_limit/get_usage_limit_from_organization.py +11 -0
  724. pygeai/tests/snippets/usage_limit/get_usage_limit_from_project.py +13 -0
  725. pygeai/tests/snippets/usage_limit/set_usage_limit_organization.py +22 -0
  726. pygeai/tests/snippets/usage_limit/set_usage_limit_project.py +23 -0
  727. pygeai/tests/snippets/usage_limit/update_usage_limit_organization.py +23 -0
  728. pygeai/tests/snippets/usage_limit/update_usage_limit_project.py +24 -0
  729. pygeai/vendor/a2a/__init__.py +1 -0
  730. pygeai/vendor/a2a/auth/__init__.py +0 -0
  731. pygeai/vendor/a2a/auth/user.py +31 -0
  732. pygeai/vendor/a2a/client/__init__.py +19 -0
  733. pygeai/vendor/a2a/client/client.py +425 -0
  734. pygeai/vendor/a2a/client/errors.py +33 -0
  735. pygeai/vendor/a2a/client/helpers.py +22 -0
  736. pygeai/vendor/a2a/py.typed +0 -0
  737. pygeai/vendor/a2a/server/__init__.py +1 -0
  738. pygeai/vendor/a2a/server/agent_execution/__init__.py +18 -0
  739. pygeai/vendor/a2a/server/agent_execution/agent_executor.py +44 -0
  740. pygeai/vendor/a2a/server/agent_execution/context.py +155 -0
  741. pygeai/vendor/a2a/server/agent_execution/request_context_builder.py +20 -0
  742. pygeai/vendor/a2a/server/agent_execution/simple_request_context_builder.py +77 -0
  743. pygeai/vendor/a2a/server/apps/__init__.py +16 -0
  744. pygeai/vendor/a2a/server/apps/jsonrpc/__init__.py +16 -0
  745. pygeai/vendor/a2a/server/apps/jsonrpc/fastapi_app.py +88 -0
  746. pygeai/vendor/a2a/server/apps/jsonrpc/jsonrpc_app.py +426 -0
  747. pygeai/vendor/a2a/server/apps/jsonrpc/starlette_app.py +123 -0
  748. pygeai/vendor/a2a/server/context.py +23 -0
  749. pygeai/vendor/a2a/server/events/__init__.py +21 -0
  750. pygeai/vendor/a2a/server/events/event_consumer.py +149 -0
  751. pygeai/vendor/a2a/server/events/event_queue.py +156 -0
  752. pygeai/vendor/a2a/server/events/in_memory_queue_manager.py +85 -0
  753. pygeai/vendor/a2a/server/events/queue_manager.py +35 -0
  754. pygeai/vendor/a2a/server/request_handlers/__init__.py +20 -0
  755. pygeai/vendor/a2a/server/request_handlers/default_request_handler.py +435 -0
  756. pygeai/vendor/a2a/server/request_handlers/jsonrpc_handler.py +327 -0
  757. pygeai/vendor/a2a/server/request_handlers/request_handler.py +161 -0
  758. pygeai/vendor/a2a/server/request_handlers/response_helpers.py +133 -0
  759. pygeai/vendor/a2a/server/tasks/__init__.py +20 -0
  760. pygeai/vendor/a2a/server/tasks/inmemory_push_notifier.py +62 -0
  761. pygeai/vendor/a2a/server/tasks/inmemory_task_store.py +51 -0
  762. pygeai/vendor/a2a/server/tasks/push_notifier.py +25 -0
  763. pygeai/vendor/a2a/server/tasks/result_aggregator.py +151 -0
  764. pygeai/vendor/a2a/server/tasks/task_manager.py +253 -0
  765. pygeai/vendor/a2a/server/tasks/task_store.py +22 -0
  766. pygeai/vendor/a2a/server/tasks/task_updater.py +155 -0
  767. pygeai/vendor/a2a/types.py +1624 -0
  768. pygeai/vendor/a2a/utils/__init__.py +40 -0
  769. pygeai/vendor/a2a/utils/artifact.py +72 -0
  770. pygeai/vendor/a2a/utils/errors.py +69 -0
  771. pygeai/vendor/a2a/utils/helpers.py +176 -0
  772. pygeai/vendor/a2a/utils/message.py +83 -0
  773. pygeai/vendor/a2a/utils/task.py +57 -0
  774. pygeai/vendor/a2a/utils/telemetry.py +299 -0
  775. pygeai-0.6.0b15.dist-info/METADATA +205 -0
  776. pygeai-0.6.0b15.dist-info/RECORD +799 -0
  777. {pygeai-0.1.6.dist-info → pygeai-0.6.0b15.dist-info}/WHEEL +1 -1
  778. pygeai-0.6.0b15.dist-info/entry_points.txt +5 -0
  779. {pygeai-0.1.6.dist-info → pygeai-0.6.0b15.dist-info/licenses}/LICENSE +13 -1
  780. {pygeai-0.1.6.dist-info → pygeai-0.6.0b15.dist-info}/top_level.txt +0 -1
  781. docs/source/conf.py +0 -45
  782. pygeai/core/clients.py +0 -240
  783. pygeai/tests/core/test_clients.py +0 -49
  784. pygeai-0.1.6.dist-info/METADATA +0 -92
  785. pygeai-0.1.6.dist-info/RECORD +0 -65
  786. pygeai-0.1.6.dist-info/SOURCES.sync-conflict-20241223-145950-3QD4F42.txt +0 -41
  787. pygeai-0.1.6.dist-info/entry_points.txt +0 -2
  788. /pygeai/{agent → analytics}/__init__.py +0 -0
@@ -0,0 +1,209 @@
1
+ from pathlib import Path
2
+ from typing import Any, Dict, List, Optional, Union
3
+ import json
4
+
5
+ from pygeai.core.common.exceptions import WrongArgumentError, ValidationError
6
+
7
+
8
+ def validate_dataset_file(dataset_file: str):
9
+ path = Path(dataset_file)
10
+ if not path.exists():
11
+ raise FileNotFoundError(f"Dataset file not found: {dataset_file}")
12
+ if not path.is_file():
13
+ raise ValueError(f"Dataset path is not a file: {dataset_file}")
14
+
15
+
16
+ def validate_row_structure(row: dict):
17
+ required_fields = ["dataSetRowExpectedAnswer", "dataSetRowContextDocument", "dataSetRowInput"]
18
+ for field in required_fields:
19
+ if not isinstance(row.get(field), str):
20
+ raise WrongArgumentError(f'Missing or invalid value for required field "{field}". It must be a non-empty string.')
21
+
22
+ expected_sources = row.get("expectedSources", [])
23
+ if not isinstance(expected_sources, list):
24
+ raise WrongArgumentError('"expectedSources" must be a list of objects, even if empty.')
25
+ for source in expected_sources:
26
+ if not isinstance(source, dict) or not all(
27
+ key in source and isinstance(source[key], str) for key in [
28
+ "dataSetExpectedSourceId", "dataSetExpectedSourceName",
29
+ "dataSetExpectedSourceValue", "dataSetExpectedSourceExtension"
30
+ ]
31
+ ):
32
+ raise WrongArgumentError(
33
+ 'Each item in "expectedSources" must be a dictionary containing the following string fields: '
34
+ '"dataSetExpectedSourceId", "dataSetExpectedSourceName", "dataSetExpectedSourceValue", and "dataSetExpectedSourceExtension".'
35
+ )
36
+
37
+ filter_variables = row.get("filterVariables", [])
38
+ if not isinstance(filter_variables, list):
39
+ raise WrongArgumentError('"filterVariables" must be a list of objects, even if empty.')
40
+ for variable in filter_variables:
41
+ if not isinstance(variable, dict) or not all(
42
+ key in variable and isinstance(variable[key], str) for key in [
43
+ "dataSetMetadataType", "dataSetRowFilterKey",
44
+ "dataSetRowFilterOperator", "dataSetRowFilterValue", "dataSetRowFilterVarId"
45
+ ]
46
+ ):
47
+ raise WrongArgumentError(
48
+ 'Each item in "filterVariables" must be a dictionary containing the following string fields: '
49
+ '"dataSetMetadataType", "dataSetRowFilterKey", "dataSetRowFilterOperator", '
50
+ '"dataSetRowFilterValue", and "dataSetRowFilterVarId".'
51
+ )
52
+
53
+
54
+ def validate_system_metric(metric: dict):
55
+ required_fields = ["systemMetricId", "systemMetricWeight"]
56
+
57
+ if not isinstance(metric, dict):
58
+ raise WrongArgumentError("Each system metric must be a dictionary.")
59
+
60
+ for field in required_fields:
61
+ if field not in metric:
62
+ raise WrongArgumentError(f'Missing required field "{field}" in system metric.')
63
+
64
+ if not isinstance(metric["systemMetricId"], str) or not metric["systemMetricId"].strip():
65
+ raise WrongArgumentError('"systemMetricId" must be a non-empty string.')
66
+
67
+ if not isinstance(metric["systemMetricWeight"], (int, float)) or not (0 <= metric["systemMetricWeight"] <= 1):
68
+ raise WrongArgumentError('"systemMetricWeight" must be a number between 0 and 1 (inclusive).')
69
+
70
+
71
+ def validate_json_input(
72
+ value: str,
73
+ expected_type: type,
74
+ field_name: str,
75
+ example: Optional[str] = None
76
+ ) -> Union[Dict, List]:
77
+ """
78
+ Validates and parses JSON input with detailed error messages.
79
+
80
+ :param value: str - The JSON string to parse.
81
+ :param expected_type: type - Expected type (dict or list).
82
+ :param field_name: str - Name of the field being validated.
83
+ :param example: Optional[str] - Example of valid input.
84
+ :return: Union[Dict, List] - Parsed JSON object.
85
+ :raises ValidationError: If JSON is invalid or doesn't match expected type.
86
+ """
87
+ try:
88
+ parsed = json.loads(value)
89
+ except json.JSONDecodeError as e:
90
+ raise ValidationError(
91
+ f"Invalid JSON for '{field_name}'",
92
+ field=field_name,
93
+ expected="Valid JSON string",
94
+ received=value[:100] + "..." if len(value) > 100 else value,
95
+ example=example or '{"key": "value"}'
96
+ ) from e
97
+
98
+ if not isinstance(parsed, expected_type):
99
+ raise ValidationError(
100
+ f"Wrong type for '{field_name}'",
101
+ field=field_name,
102
+ expected=expected_type.__name__,
103
+ received=type(parsed).__name__,
104
+ example=example
105
+ )
106
+
107
+ return parsed
108
+
109
+
110
+ def validate_numeric_range(
111
+ value: str,
112
+ field_name: str,
113
+ min_value: Optional[float] = None,
114
+ max_value: Optional[float] = None,
115
+ value_type: type = float
116
+ ) -> Union[int, float]:
117
+ """
118
+ Validates numeric input within a specified range.
119
+
120
+ :param value: str - The numeric string to validate.
121
+ :param field_name: str - Name of the field being validated.
122
+ :param min_value: Optional[float] - Minimum allowed value.
123
+ :param max_value: Optional[float] - Maximum allowed value.
124
+ :param value_type: type - Expected numeric type (int or float).
125
+ :return: Union[int, float] - Validated numeric value.
126
+ :raises ValidationError: If value is not numeric or out of range.
127
+ """
128
+ try:
129
+ numeric_value = value_type(value)
130
+ except ValueError as e:
131
+ raise ValidationError(
132
+ f"Invalid {value_type.__name__} for '{field_name}'",
133
+ field=field_name,
134
+ expected=f"{value_type.__name__}",
135
+ received=value
136
+ ) from e
137
+
138
+ if min_value is not None and numeric_value < min_value:
139
+ raise ValidationError(
140
+ f"Value too low for '{field_name}'",
141
+ field=field_name,
142
+ expected=f">= {min_value}",
143
+ received=str(numeric_value)
144
+ )
145
+
146
+ if max_value is not None and numeric_value > max_value:
147
+ raise ValidationError(
148
+ f"Value too high for '{field_name}'",
149
+ field=field_name,
150
+ expected=f"<= {max_value}",
151
+ received=str(numeric_value)
152
+ )
153
+
154
+ return numeric_value
155
+
156
+
157
+ def validate_choice(
158
+ value: str,
159
+ field_name: str,
160
+ choices: List[str],
161
+ case_sensitive: bool = True
162
+ ) -> str:
163
+ """
164
+ Validates that input is one of the allowed choices.
165
+
166
+ :param value: str - The value to validate.
167
+ :param field_name: str - Name of the field being validated.
168
+ :param choices: List[str] - List of allowed values.
169
+ :param case_sensitive: bool - Whether comparison is case-sensitive.
170
+ :return: str - Validated value.
171
+ :raises ValidationError: If value is not in choices.
172
+ """
173
+ compare_value = value if case_sensitive else value.lower()
174
+ compare_choices = choices if case_sensitive else [c.lower() for c in choices]
175
+
176
+ if compare_value not in compare_choices:
177
+ raise ValidationError(
178
+ f"Invalid value for '{field_name}'",
179
+ field=field_name,
180
+ expected=f"One of: {', '.join(choices)}",
181
+ received=value
182
+ )
183
+
184
+ return value
185
+
186
+
187
+ def validate_boolean_value(value: str, field_name: str = "boolean option") -> bool:
188
+ """
189
+ Converts a string argument into a boolean value with flexible input formats.
190
+
191
+ :param value: str - A string representation of a boolean.
192
+ :param field_name: str - Name of the field being validated.
193
+ :return: bool - The boolean value corresponding to the input.
194
+ :raises ValidationError: If the input is not a valid boolean representation.
195
+ """
196
+ normalized = value.lower().strip()
197
+
198
+ if normalized in ("0", "false", "no", "off"):
199
+ return False
200
+ elif normalized in ("1", "true", "yes", "on"):
201
+ return True
202
+ else:
203
+ raise ValidationError(
204
+ f"Invalid boolean value for '{field_name}'",
205
+ field=field_name,
206
+ expected="0/1, true/false, yes/no, on/off",
207
+ received=value,
208
+ example="1 or true"
209
+ )
@@ -0,0 +1,44 @@
1
+ import requests
2
+ import json
3
+ from packaging.version import Version as LooseVersion
4
+
5
+ from pygeai.core.utils.console import Console
6
+
7
+
8
+ def get_latest_version(package_name):
9
+ url = f"https://pypi.org/pypi/{package_name}/json"
10
+ try:
11
+ response = requests.get(url)
12
+ response.raise_for_status()
13
+ data = json.loads(response.text)
14
+ return data['info']['version']
15
+ except requests.RequestException as e:
16
+ Console.write_stderr(f"An error occurred while fetching the latest version: {e}")
17
+
18
+
19
+ def get_installed_version(package_name):
20
+ try:
21
+ import importlib.metadata
22
+ installed_version = importlib.metadata.version(package_name)
23
+ return installed_version
24
+ except importlib.metadata.PackageNotFoundError:
25
+ return "Not installed"
26
+ except ModuleNotFoundError:
27
+ Console.write_stderr("This Python installation does not support importlib.metadata. Use Python 3.8+ or install importlib_metadata manually.")
28
+ return "Unknown"
29
+
30
+
31
+ def check_new_version(package_name):
32
+ latest_version = get_latest_version(package_name)
33
+ installed_version = get_installed_version(package_name)
34
+
35
+ if latest_version is None or installed_version == "Unknown":
36
+ return "Could not determine version information."
37
+
38
+ if installed_version == "Not installed":
39
+ return f"{package_name} is not installed, but the latest version available is {latest_version}."
40
+
41
+ if LooseVersion(latest_version) > LooseVersion(installed_version):
42
+ return f"There's a new version available: {latest_version}. You have {installed_version} installed."
43
+ else:
44
+ return f"You have the latest version {installed_version} of {package_name}."
@@ -0,0 +1,151 @@
1
+ import traceback
2
+ from difflib import SequenceMatcher
3
+ from typing import List, Optional, Tuple
4
+
5
+ from pygeai import logger
6
+ from pygeai.cli.commands import Command, Option
7
+ from pygeai.core.utils.console import Console
8
+
9
+
10
+ FUZZY_MATCH_THRESHOLD = 0.6
11
+ MAX_FUZZY_SUGGESTIONS = 3
12
+
13
+
14
+ class ExitCode:
15
+ SUCCESS = 0
16
+ USER_INPUT_ERROR = 1
17
+ MISSING_REQUIREMENT = 2
18
+ SERVICE_ERROR = 3
19
+ KEYBOARD_INTERRUPT = 130
20
+ UNEXPECTED_ERROR = 255
21
+
22
+
23
+ class ErrorHandler:
24
+
25
+ @staticmethod
26
+ def format_error(
27
+ error_type: str,
28
+ message: str,
29
+ suggestion: Optional[str] = None,
30
+ show_help: bool = True,
31
+ example: Optional[str] = None
32
+ ) -> str:
33
+ """
34
+ Formats an error message with optional suggestion and example.
35
+
36
+ :param error_type: str - Type of error (e.g., "Unknown Command").
37
+ :param message: str - The error message.
38
+ :param suggestion: Optional[str] - Suggested fix or next steps.
39
+ :param show_help: bool - Whether to show help command hint.
40
+ :param example: Optional[str] - Example of correct usage.
41
+ :return: str - Formatted error message.
42
+ """
43
+ output = f"ERROR [{error_type}]: {message}"
44
+
45
+ if suggestion:
46
+ output += f"\n → {suggestion}"
47
+
48
+ if example:
49
+ output += f"\n\n Example:\n {example}"
50
+
51
+ if show_help:
52
+ output += "\n\nRun 'geai help' for usage information."
53
+
54
+ return output
55
+
56
+ @staticmethod
57
+ def find_similar_items(
58
+ item: str,
59
+ available_items: List[str],
60
+ threshold: float = FUZZY_MATCH_THRESHOLD
61
+ ) -> List[str]:
62
+ """
63
+ Finds similar items using fuzzy string matching.
64
+
65
+ :param item: str - The item to match against.
66
+ :param available_items: List[str] - List of available items.
67
+ :param threshold: float - Minimum similarity ratio (0.0 to 1.0).
68
+ :return: List[str] - List of similar items, up to MAX_FUZZY_SUGGESTIONS.
69
+ """
70
+ similarities: List[Tuple[str, float]] = []
71
+ for available in available_items:
72
+ ratio = SequenceMatcher(None, item.lower(), available.lower()).ratio()
73
+ if ratio >= threshold:
74
+ similarities.append((available, ratio))
75
+
76
+ similarities.sort(key=lambda x: x[1], reverse=True)
77
+ return [item[0] for item in similarities[:MAX_FUZZY_SUGGESTIONS]]
78
+
79
+ @staticmethod
80
+ def get_available_commands(commands: List[Command]) -> List[str]:
81
+ all_identifiers = []
82
+ for cmd in commands:
83
+ all_identifiers.extend(cmd.identifiers)
84
+ return all_identifiers
85
+
86
+ @staticmethod
87
+ def get_available_options(options: List[Option]) -> List[str]:
88
+ all_identifiers = []
89
+ for opt in options:
90
+ all_identifiers.extend(opt.identifiers)
91
+ return all_identifiers
92
+
93
+ @staticmethod
94
+ def handle_unknown_command(command: str, available_commands: List[Command]) -> str:
95
+ cmd_identifiers = ErrorHandler.get_available_commands(available_commands)
96
+ similar = ErrorHandler.find_similar_items(command, cmd_identifiers)
97
+
98
+ message = f"'{command}' is not a valid command."
99
+
100
+ if similar:
101
+ suggestion = f"Did you mean: {', '.join(similar)}?"
102
+ else:
103
+ suggestion = f"Available commands: {', '.join(sorted(set([cmd.identifiers[0] for cmd in available_commands])))}"
104
+
105
+ return ErrorHandler.format_error("Unknown Command", message, suggestion)
106
+
107
+ @staticmethod
108
+ def handle_unknown_option(option: str, available_options: List[Option]) -> str:
109
+ opt_identifiers = ErrorHandler.get_available_options(available_options)
110
+ similar = ErrorHandler.find_similar_items(option, opt_identifiers)
111
+
112
+ message = f"'{option}' is not a valid option."
113
+
114
+ if similar:
115
+ suggestion = f"Did you mean: {', '.join(similar)}?"
116
+ else:
117
+ suggestion = f"Available options: {', '.join(sorted(set([opt.identifiers[0] for opt in available_options])))}"
118
+
119
+ return ErrorHandler.format_error("Unknown Option", message, suggestion)
120
+
121
+ @staticmethod
122
+ def handle_missing_requirement(requirement_message: str) -> str:
123
+ message = requirement_message
124
+ suggestion = "Please provide all required parameters."
125
+ return ErrorHandler.format_error("Missing Requirement", message, suggestion)
126
+
127
+ @staticmethod
128
+ def handle_invalid_agent(error_message: str) -> str:
129
+ message = f"Failed to retrieve or validate the agent.\n Details: {error_message}"
130
+ suggestion = "Check your agent configuration and ensure the agent exists."
131
+ return ErrorHandler.format_error("Invalid Agent", message, suggestion)
132
+
133
+ @staticmethod
134
+ def handle_wrong_argument(error_message: str, usage: str) -> str:
135
+ Console.write_stderr(f"usage: {usage}")
136
+ message = error_message
137
+ suggestion = "Check the command syntax and try again."
138
+ return ErrorHandler.format_error("Invalid Argument", message, suggestion)
139
+
140
+ @staticmethod
141
+ def handle_keyboard_interrupt() -> str:
142
+ return "\n\nOperation cancelled by user."
143
+
144
+ @staticmethod
145
+ def handle_unexpected_error(exception: Exception) -> str:
146
+ logger.error(f"Unexpected error occurred: {exception}")
147
+ logger.error(traceback.format_exc())
148
+
149
+ message = "An unexpected error occurred. This may be a bug."
150
+ suggestion = f"Please report this issue to geai-sdk@globant.com with the following details:\n Error: {str(exception)}\n Run with geai-dbg for more details."
151
+ return ErrorHandler.format_error("Critical Error", message, suggestion, show_help=False)
pygeai/cli/geai.py CHANGED
@@ -1,36 +1,104 @@
1
1
  import sys
2
+ import logging
3
+ from typing import List, Optional
2
4
 
5
+ from pygeai import logger
3
6
  from pygeai.cli.commands.base import base_commands, base_options
4
7
  from pygeai.cli.commands import ArgumentsEnum, Command
5
8
  from pygeai.cli.parsers import CommandParser
6
9
  from pygeai.cli.texts.help import CLI_USAGE
10
+ from pygeai.cli.error_handler import ErrorHandler, ExitCode
7
11
  from pygeai.core.base.session import get_session
8
- from pygeai.core.common.exceptions import UnknownArgumentError, MissingRequirementException, WrongArgumentError
9
-
10
-
11
- def main():
12
- driver = CLIDriver()
13
- return driver.main()
12
+ from pygeai.core.common.exceptions import UnknownArgumentError, MissingRequirementException, WrongArgumentError, \
13
+ InvalidAgentException
14
+ from pygeai.core.utils.console import Console
15
+
16
+
17
+ def setup_verbose_logging() -> None:
18
+ """
19
+ Configure verbose logging for the CLI.
20
+
21
+ Sets up a console handler with DEBUG level logging and a formatted output
22
+ that includes timestamp, logger name, level, and message.
23
+ """
24
+ if logger.handlers:
25
+ for handler in logger.handlers:
26
+ if not isinstance(handler, logging.NullHandler):
27
+ return
28
+
29
+ logger.setLevel(logging.DEBUG)
30
+ console_handler = logging.StreamHandler(sys.stderr)
31
+ console_handler.setLevel(logging.DEBUG)
32
+ formatter = logging.Formatter(
33
+ '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
34
+ datefmt='%Y-%m-%d %H:%M:%S'
35
+ )
36
+ console_handler.setFormatter(formatter)
37
+ logger.addHandler(console_handler)
38
+ logger.propagate = False
39
+ logger.debug("Verbose mode enabled")
40
+
41
+
42
+ def main() -> int:
43
+ """
44
+ Main entry point for the GEAI CLI application.
45
+
46
+ :return: int - Exit code indicating success or error.
47
+ """
48
+ try:
49
+ driver = CLIDriver()
50
+ return driver.main()
51
+ except MissingRequirementException as e:
52
+ error_msg = ErrorHandler.handle_missing_requirement(str(e))
53
+ Console.write_stderr(error_msg)
54
+ return ExitCode.MISSING_REQUIREMENT
14
55
 
15
56
 
16
57
  class CLIDriver:
17
-
18
- def __init__(self, session=None):
58
+ """
59
+ Main CLI driver for the GEAI command-line interface.
60
+
61
+ The CLIDriver orchestrates command parsing, execution, and error handling
62
+ for all GEAI CLI operations. It supports multi-profile session management
63
+ via the --alias flag and provides comprehensive error handling with
64
+ user-friendly messages.
65
+ """
66
+
67
+ def __init__(self, session=None, credentials_file=None) -> None:
19
68
  """
20
- Sets session to be used while running the command, either with a specified alias,
21
- environment variables or function parameters.
22
- Once the session is defined, it won't change during the curse of the execution.
69
+ Initialize the CLI driver with optional session and credentials file.
70
+
71
+ Sets up the session to be used while running commands, either with a
72
+ specified alias, environment variables, or function parameters.
73
+ Once the session is defined, it won't change during the execution.
74
+
75
+ :param session: Optional session object. If None, uses 'default' or
76
+ alias-specified session from command-line arguments.
77
+ :param credentials_file: Optional path to custom credentials file.
23
78
  """
79
+ from pygeai.core.common.config import get_settings
80
+
24
81
  arguments = sys.argv
82
+
83
+ if credentials_file or "--credentials" in arguments or "--creds" in arguments:
84
+ if not credentials_file:
85
+ credentials_file = self._get_credentials_file(arguments)
86
+ get_settings(credentials_file=credentials_file)
87
+ logger.debug(f"Using custom credentials file: {credentials_file}")
88
+
25
89
  if "-a" in arguments or "--alias" in arguments:
26
90
  alias = self._get_alias(arguments)
27
91
  session = get_session(alias)
28
92
 
29
- self.session = get_session() if session is None else session
93
+ self.session = get_session("default") if session is None else session
30
94
 
31
- def _get_alias(self, arguments: list):
95
+ def _get_alias(self, arguments: List[str]) -> str:
32
96
  """
33
- Retrieves and removes alias and alias flag from argument list
97
+ Retrieves and removes alias and alias flag from argument list.
98
+
99
+ :param arguments: List[str] - Command line arguments.
100
+ :return: str - The alias value.
101
+ :raises ValueError: If alias flag is present but no value provided.
34
102
  """
35
103
  alias_index = None
36
104
 
@@ -42,63 +110,136 @@ class CLIDriver:
42
110
  _ = arguments.pop(alias_index)
43
111
  alias = arguments.pop(alias_index)
44
112
  return alias
113
+
114
+ def _get_credentials_file(self, arguments: List[str]) -> str:
115
+ """
116
+ Retrieves and removes credentials file path and flag from argument list.
117
+
118
+ :param arguments: List[str] - Command line arguments.
119
+ :return: str - The credentials file path.
120
+ :raises ValueError: If credentials flag is present but no value provided.
121
+ """
122
+ creds_index = None
45
123
 
46
- def main(self, args=None):
124
+ if "--credentials" in arguments:
125
+ creds_index = arguments.index("--credentials")
126
+ elif "--creds" in arguments:
127
+ creds_index = arguments.index("--creds")
128
+
129
+ _ = arguments.pop(creds_index)
130
+ credentials_file = arguments.pop(creds_index)
131
+ return credentials_file
132
+
133
+ def main(self, args: Optional[List[str]] = None) -> int:
47
134
  """
48
- If not argument is received, it defaults to help (first command in base_command list).
135
+ Execute the CLI command based on provided arguments.
136
+
137
+ If no argument is received, it defaults to help (first command in base_command list).
49
138
  Otherwise, it parses the arguments received to identify the appropriate command and either
50
139
  execute it or parse it again to detect subcommands.
140
+
141
+ :param args: Optional[List[str]] - Command line arguments. If None, uses sys.argv.
142
+ :return: int - Exit code (0 for success, non-zero for errors).
51
143
  """
52
144
  try:
53
- if len(sys.argv) > 1:
54
- arg = sys.argv[1] if args is None else args[1]
55
- arguments = sys.argv[2:] if args is None else args[2:]
56
-
145
+ argv = sys.argv if args is None else args
146
+
147
+ if "--verbose" in argv or "-v" in argv:
148
+ setup_verbose_logging()
149
+ argv_copy = [a for a in argv if a not in ("--verbose", "-v")]
150
+ if args is None:
151
+ sys.argv = argv_copy
152
+ else:
153
+ args = argv_copy
154
+ argv = argv_copy
155
+
156
+ logger.debug(f"Running geai with: {' '.join(a for a in argv)}")
157
+ logger.debug(f"Session: {self.session.alias if hasattr(self.session, 'alias') else 'default'}")
158
+
159
+ if len(argv) > 1:
160
+ arg = argv[1] if args is None else args[1]
161
+ arguments = argv[2:] if args is None else args[2:]
162
+
163
+ logger.debug(f"Identifying command for argument: {arg}")
57
164
  command = CommandParser(base_commands, base_options).identify_command(arg)
165
+ logger.debug(f"Command identified: {command.name}")
58
166
  else:
167
+ logger.debug("No arguments provided, defaulting to help command")
59
168
  command = base_commands[0]
60
169
  arguments = []
61
170
 
62
171
  self.process_command(command, arguments)
63
- except (UnknownArgumentError, WrongArgumentError) as e:
64
- sys.stderr.write(f"usage: {CLI_USAGE}")
65
- sys.stderr.write(str(e))
66
- sys.stderr.write("\n")
172
+ logger.debug(f"Command completed successfully")
173
+ return ExitCode.SUCCESS
174
+ except UnknownArgumentError as e:
175
+ if hasattr(e, 'available_commands') and e.available_commands:
176
+ error_msg = ErrorHandler.handle_unknown_command(e.arg, e.available_commands)
177
+ elif hasattr(e, 'available_options') and e.available_options:
178
+ error_msg = ErrorHandler.handle_unknown_option(e.arg, e.available_options)
179
+ else:
180
+ error_msg = ErrorHandler.format_error("Unknown Argument", str(e))
181
+
182
+ Console.write_stderr(error_msg)
183
+ return ExitCode.USER_INPUT_ERROR
184
+ except WrongArgumentError as e:
185
+ error_msg = ErrorHandler.handle_wrong_argument(str(e), CLI_USAGE)
186
+ Console.write_stderr(error_msg)
187
+ return ExitCode.USER_INPUT_ERROR
67
188
  except MissingRequirementException as e:
68
- sys.stderr.write(f"ERROR: Something is missing! {e}")
189
+ error_msg = ErrorHandler.handle_missing_requirement(str(e))
190
+ Console.write_stderr(error_msg)
191
+ return ExitCode.MISSING_REQUIREMENT
192
+ except InvalidAgentException as e:
193
+ error_msg = ErrorHandler.handle_invalid_agent(str(e))
194
+ Console.write_stderr(error_msg)
195
+ return ExitCode.SERVICE_ERROR
69
196
  except KeyboardInterrupt:
70
- sys.stdout.write("\n")
197
+ message = ErrorHandler.handle_keyboard_interrupt()
198
+ Console.write_stdout(message)
199
+ return ExitCode.KEYBOARD_INTERRUPT
71
200
  except Exception as e:
72
- sys.stderr.write(f"Unexpected error. Please report this bug to the developers. Error: {e}")
73
- return 255
201
+ error_msg = ErrorHandler.handle_unexpected_error(e)
202
+ Console.write_stderr(error_msg)
203
+ return ExitCode.UNEXPECTED_ERROR
74
204
 
75
205
  def process_command(self, command: Command, arguments: list[str]):
76
206
  """
77
207
  If the command has no action associated with it, it means it has subcommands, so it must be parsed again
78
208
  to identify it.
79
209
  """
210
+ logger.debug(f"Processing command: {command.name}, arguments: {arguments}")
211
+
80
212
  if command.action:
81
213
  if command.additional_args == ArgumentsEnum.NOT_AVAILABLE:
214
+ logger.debug(f"Executing command {command.name} without arguments")
82
215
  command.action()
83
216
  else:
217
+ logger.debug(f"Extracting options for command {command.name}")
84
218
  option_list = CommandParser(base_commands, command.options).extract_option_list(arguments)
219
+ logger.debug(f"Options extracted: {len(option_list)} items")
85
220
  command.action(option_list)
86
221
  elif command.subcommands:
87
222
  subcommand_arg = arguments[0] if len(arguments) > 0 else None
88
223
  subcommand_arguments = arguments[1:] if len(arguments) > 1 else []
89
-
224
+
225
+ logger.debug(f"Command has subcommands, identifying: {subcommand_arg}")
226
+
90
227
  available_commands = command.subcommands
91
228
  available_options = command.options
92
229
  parser = CommandParser(available_commands, available_options)
93
230
 
94
231
  if not subcommand_arg:
232
+ logger.debug(f"No subcommand specified, using default: {command.subcommands[0].name}")
95
233
  subcommand = command.subcommands[0]
96
234
  else:
97
235
  subcommand = parser.identify_command(subcommand_arg)
236
+ logger.debug(f"Subcommand identified: {subcommand.name}")
98
237
 
99
238
  if subcommand.additional_args == ArgumentsEnum.NOT_AVAILABLE:
239
+ logger.debug(f"Executing subcommand {subcommand.name} without arguments")
100
240
  subcommand.action()
101
241
  else:
242
+ logger.debug(f"Extracting options for subcommand {subcommand.name}")
102
243
  option_list = CommandParser(None, subcommand.options).extract_option_list(subcommand_arguments)
244
+ logger.debug(f"Options extracted: {len(option_list)} items")
103
245
  subcommand.action(option_list)
104
-