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
pygeai/dbg/debugger.py ADDED
@@ -0,0 +1,870 @@
1
+ import logging
2
+ import sys
3
+ import inspect
4
+ import readline
5
+ import pprint
6
+ import argparse
7
+ from types import FrameType
8
+ from typing import Optional, Any, Callable, Set, Dict, List, Tuple
9
+ from dataclasses import dataclass, field
10
+
11
+ from pygeai.cli.geai import main as geai
12
+ from pygeai.core.utils.console import Console
13
+
14
+
15
+ @dataclass
16
+ class Breakpoint:
17
+ """Represents a breakpoint with optional conditions."""
18
+ module: Optional[str] = None
19
+ function_name: Optional[str] = None
20
+ condition: Optional[str] = None
21
+ enabled: bool = True
22
+ hit_count: int = 0
23
+
24
+ def __hash__(self):
25
+ return hash((self.module, self.function_name))
26
+
27
+ def __eq__(self, other):
28
+ if not isinstance(other, Breakpoint):
29
+ return False
30
+ return self.module == other.module and self.function_name == other.function_name
31
+
32
+ def matches(self, module: str, func_name: str) -> bool:
33
+ """Check if this breakpoint matches the given module and function."""
34
+ if not self.enabled:
35
+ return False
36
+ module_match = self.module is None or self.module == module
37
+ func_match = self.function_name is None or self.function_name == func_name
38
+ return module_match and func_match
39
+
40
+ def __str__(self):
41
+ status = "enabled" if self.enabled else "disabled"
42
+ cond = f" [if {self.condition}]" if self.condition else ""
43
+ return f"{self.module or '*'}:{self.function_name or '*'} ({status}, hits: {self.hit_count}){cond}"
44
+
45
+
46
+ class Debugger:
47
+ """
48
+ A debugger for the GEAI application to trace and control execution flow.
49
+
50
+ This class implements a custom debugging mechanism using Python's `sys.settrace` to intercept function calls
51
+ and pause execution at specified breakpoints. Breakpoints can be set for specific modules or functions, allowing
52
+ developers to inspect local variables, execute arbitrary code in the current context, and control program flow
53
+ through an interactive command interface.
54
+
55
+ Features:
56
+ - Module filtering for performance (only traces pygeai modules by default)
57
+ - Breakpoint management (add, list, remove, enable/disable, conditional)
58
+ - Stack navigation (up/down frames)
59
+ - Stepping (step-into, step-over, step-out)
60
+ - Variable inspection with pretty-printing
61
+ - Source code display
62
+ - Stack trace viewing
63
+ - Readline support for command history
64
+ """
65
+
66
+ def __init__(self, target: Optional[Callable] = None, module_filter: str = "pygeai", verbose: bool = False, log_level: str = 'DEBUG'):
67
+ """
68
+ Initialize the debugger.
69
+
70
+ :param target: Optional[Callable] - The callable to debug. If None, defaults to pygeai.cli.geai.main (optional).
71
+ :param module_filter: str - Only trace modules starting with this prefix (for performance). Empty string traces all modules. Use '__main__' to trace only the main script (default is 'pygeai').
72
+ :param verbose: bool - If True, enable logging for pygeai modules (default is False).
73
+ :param log_level: str - Log level for verbose mode: 'DEBUG', 'INFO', 'WARNING', 'ERROR' (default is 'DEBUG').
74
+ """
75
+ self.target = target or geai
76
+ self.module_filter = module_filter
77
+ self.verbose = verbose
78
+ self.log_level = getattr(logging, log_level.upper(), logging.DEBUG)
79
+ self._setup_logging()
80
+ self.logger = logging.getLogger('geai.dbg')
81
+
82
+ self.breakpoints: Dict[Tuple[Optional[str], Optional[str]], Breakpoint] = {}
83
+ self.paused: bool = False
84
+ self.current_frame: Optional[FrameType] = None
85
+ self.frame_stack: List[FrameType] = []
86
+ self.current_frame_index: int = 0
87
+
88
+ # Stepping state
89
+ self.step_mode: Optional[str] = None # 'step', 'next', 'return', 'until'
90
+ self.step_frame: Optional[FrameType] = None
91
+ self.step_depth: int = 0
92
+ self.current_depth: int = 0
93
+
94
+ # Setup readline for command history
95
+ self._setup_readline()
96
+
97
+ self.logger.info("GEAI debugger started.")
98
+ self.logger.debug(f"Module filter: {self.module_filter}")
99
+
100
+ def _setup_logging(self):
101
+ """Setup logging configuration, avoiding duplicate handlers."""
102
+ logger = logging.getLogger('geai.dbg')
103
+
104
+ # Only setup if not already configured
105
+ if not logger.handlers:
106
+ logger.setLevel(logging.DEBUG)
107
+ console_handler = logging.StreamHandler()
108
+ console_handler.setLevel(logging.DEBUG)
109
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
110
+ console_handler.setFormatter(formatter)
111
+ logger.addHandler(console_handler)
112
+ logger.propagate = False
113
+
114
+ # If verbose mode, enable logging for pygeai modules at specified level
115
+ if self.verbose:
116
+ # Configure root logger to show at specified log level
117
+ root_logger = logging.getLogger()
118
+ if not root_logger.handlers:
119
+ root_logger.setLevel(self.log_level)
120
+ console_handler = logging.StreamHandler()
121
+ console_handler.setLevel(self.log_level)
122
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
123
+ console_handler.setFormatter(formatter)
124
+ root_logger.addHandler(console_handler)
125
+
126
+ # Ensure pygeai logger propagates to root
127
+ pygeai_logger = logging.getLogger('pygeai')
128
+ pygeai_logger.setLevel(self.log_level)
129
+ pygeai_logger.propagate = True
130
+
131
+ def _setup_readline(self):
132
+ """Setup readline for command history and tab completion."""
133
+ try:
134
+ import os
135
+ histfile = os.path.expanduser("~/.geai_dbg_history")
136
+ try:
137
+ readline.read_history_file(histfile)
138
+ readline.set_history_length(1000)
139
+ except FileNotFoundError:
140
+ pass
141
+
142
+ import atexit
143
+ atexit.register(readline.write_history_file, histfile)
144
+ except Exception as e:
145
+ self.logger.debug(f"Could not setup readline: {e}")
146
+
147
+ def reset(self):
148
+ """Reset debugger state."""
149
+ self.breakpoints.clear()
150
+ self.paused = False
151
+ self.current_frame = None
152
+ self.frame_stack.clear()
153
+ self.current_frame_index = 0
154
+ self.step_mode = None
155
+ self.step_frame = None
156
+ self.step_depth = 0
157
+ self.current_depth = 0
158
+ self.logger.info("Debugger state reset.")
159
+
160
+ def add_breakpoint(
161
+ self,
162
+ module: Optional[str] = None,
163
+ function_name: Optional[str] = None,
164
+ condition: Optional[str] = None
165
+ ) -> Breakpoint:
166
+ """
167
+ Add a breakpoint by module and/or function name.
168
+
169
+ :param module: Optional[str] - Module name to break on. None for any module (optional).
170
+ :param function_name: Optional[str] - Function name to break on. None for any function (optional).
171
+ :param condition: Optional[str] - Optional condition expression in Python code. Breakpoint only triggers if condition evaluates to True (optional).
172
+ :return: Breakpoint - The created Breakpoint object.
173
+ """
174
+ key = (module, function_name)
175
+ if key in self.breakpoints:
176
+ bp = self.breakpoints[key]
177
+ self.logger.warning(f"Breakpoint already exists: {bp}")
178
+ return bp
179
+
180
+ bp = Breakpoint(module=module, function_name=function_name, condition=condition)
181
+ self.breakpoints[key] = bp
182
+ self.logger.info(f"Breakpoint added: {bp}")
183
+ return bp
184
+
185
+ def remove_breakpoint(self, module: Optional[str] = None, function_name: Optional[str] = None) -> bool:
186
+ """Remove a breakpoint."""
187
+ key = (module, function_name)
188
+ if key in self.breakpoints:
189
+ bp = self.breakpoints.pop(key)
190
+ self.logger.info(f"Breakpoint removed: {bp}")
191
+ return True
192
+ self.logger.warning(f"Breakpoint not found: {module or '*'}:{function_name or '*'}")
193
+ return False
194
+
195
+ def list_breakpoints(self) -> List[Breakpoint]:
196
+ """List all breakpoints."""
197
+ return list(self.breakpoints.values())
198
+
199
+ def enable_breakpoint(self, module: Optional[str] = None, function_name: Optional[str] = None) -> bool:
200
+ """Enable a breakpoint."""
201
+ key = (module, function_name)
202
+ if key in self.breakpoints:
203
+ self.breakpoints[key].enabled = True
204
+ self.logger.info(f"Breakpoint enabled: {self.breakpoints[key]}")
205
+ return True
206
+ return False
207
+
208
+ def disable_breakpoint(self, module: Optional[str] = None, function_name: Optional[str] = None) -> bool:
209
+ """Disable a breakpoint."""
210
+ key = (module, function_name)
211
+ if key in self.breakpoints:
212
+ self.breakpoints[key].enabled = False
213
+ self.logger.info(f"Breakpoint disabled: {self.breakpoints[key]}")
214
+ return True
215
+ return False
216
+
217
+ def clear_breakpoints(self):
218
+ """Clear all breakpoints."""
219
+ count = len(self.breakpoints)
220
+ self.breakpoints.clear()
221
+ self.logger.info(f"Cleared {count} breakpoint(s).")
222
+
223
+ def _should_trace_module(self, module: Optional[str]) -> bool:
224
+ """Check if we should trace this module based on filter."""
225
+ if not module:
226
+ return False
227
+ if not self.module_filter:
228
+ return True
229
+ return module.startswith(self.module_filter)
230
+
231
+ def _check_condition(self, bp: Breakpoint, frame: FrameType) -> bool:
232
+ """Check if breakpoint condition is met."""
233
+ if not bp.condition:
234
+ return True
235
+
236
+ try:
237
+ result = eval(bp.condition, frame.f_globals, frame.f_locals)
238
+ return bool(result)
239
+ except Exception as e:
240
+ self.logger.error(f"Error evaluating breakpoint condition '{bp.condition}': {e}")
241
+ return False
242
+
243
+ def _build_frame_stack(self, frame: FrameType) -> List[FrameType]:
244
+ """Build a list of frames from current to top of stack."""
245
+ stack = []
246
+ current = frame
247
+ while current is not None:
248
+ stack.append(current)
249
+ current = current.f_back
250
+ return stack
251
+
252
+ def trace_function(self, frame: FrameType, event: str, arg: Any) -> Optional[Callable]:
253
+ """Trace function calls to intercept execution."""
254
+ module = frame.f_globals.get('__name__')
255
+
256
+ if not self._should_trace_module(module):
257
+ return None
258
+
259
+ function_name = frame.f_code.co_name
260
+
261
+ if event == 'call':
262
+ self.current_depth += 1
263
+
264
+ should_break = False
265
+ for bp in self.breakpoints.values():
266
+ if bp.matches(module, function_name):
267
+ if self._check_condition(bp, frame):
268
+ bp.hit_count += 1
269
+ self.logger.info(f"Breakpoint hit at {module}.{function_name} (hit #{bp.hit_count})")
270
+ should_break = True
271
+ break
272
+
273
+ if should_break:
274
+ self.paused = True
275
+ self.current_frame = frame
276
+ self.frame_stack = self._build_frame_stack(frame)
277
+ self.current_frame_index = 0
278
+ self.handle_breakpoint(frame)
279
+ self.paused = False
280
+
281
+ elif event == 'return':
282
+ self.current_depth -= 1
283
+
284
+ if self.step_mode == 'return' and frame == self.step_frame:
285
+ self.step_mode = None
286
+ self.paused = True
287
+ self.current_frame = frame
288
+ self.frame_stack = self._build_frame_stack(frame)
289
+ self.current_frame_index = 0
290
+ self.handle_breakpoint(frame)
291
+ self.paused = False
292
+
293
+ elif event == 'line':
294
+ if self.step_mode == 'step':
295
+ self.step_mode = None
296
+ self.paused = True
297
+ self.current_frame = frame
298
+ self.frame_stack = self._build_frame_stack(frame)
299
+ self.current_frame_index = 0
300
+ self.handle_breakpoint(frame)
301
+ self.paused = False
302
+ elif self.step_mode == 'next' and self.current_depth <= self.step_depth:
303
+ self.step_mode = None
304
+ self.paused = True
305
+ self.current_frame = frame
306
+ self.frame_stack = self._build_frame_stack(frame)
307
+ self.current_frame_index = 0
308
+ self.handle_breakpoint(frame)
309
+ self.paused = False
310
+
311
+ return self.trace_function
312
+
313
+ def _get_source_lines(self, frame: FrameType, context: int = 5) -> Optional[List[Tuple[int, str]]]:
314
+ """Get source code lines around the current line."""
315
+ try:
316
+ filename = frame.f_code.co_filename
317
+ lineno = frame.f_lineno
318
+
319
+ with open(filename, 'r') as f:
320
+ lines = f.readlines()
321
+
322
+ start = max(0, lineno - context - 1)
323
+ end = min(len(lines), lineno + context)
324
+
325
+ return [(i + 1, lines[i].rstrip()) for i in range(start, end)]
326
+ except Exception as e:
327
+ self.logger.debug(f"Could not get source: {e}")
328
+ return None
329
+
330
+ def _print_source(self, frame: FrameType, context: int = 5):
331
+ """Print source code around current line."""
332
+ lines = self._get_source_lines(frame, context)
333
+ if not lines:
334
+ Console.write_stdout("Source code not available.")
335
+ return
336
+
337
+ lineno = frame.f_lineno
338
+ Console.write_stdout(f"\nSource ({frame.f_code.co_filename}):")
339
+ for num, line in lines:
340
+ marker = "-> " if num == lineno else " "
341
+ Console.write_stdout(f"{marker}{num:4d} {line}")
342
+
343
+ def _print_stack_trace(self):
344
+ """Print stack trace."""
345
+ Console.write_stdout("\nStack trace (most recent call last):")
346
+ for i, frame in enumerate(reversed(self.frame_stack)):
347
+ marker = ">" if i == len(self.frame_stack) - 1 - self.current_frame_index else " "
348
+ module = frame.f_globals.get('__name__', '?')
349
+ func = frame.f_code.co_name
350
+ lineno = frame.f_lineno
351
+ filename = frame.f_code.co_filename
352
+ Console.write_stdout(f" {marker} #{i:2d} {module}.{func} at {filename}:{lineno}")
353
+
354
+ def _move_frame(self, direction: int) -> bool:
355
+ """Move up or down the frame stack."""
356
+ new_index = self.current_frame_index + direction
357
+ if 0 <= new_index < len(self.frame_stack):
358
+ self.current_frame_index = new_index
359
+ self.current_frame = self.frame_stack[new_index]
360
+ Console.write_stdout(f"Frame #{len(self.frame_stack) - 1 - new_index}: "
361
+ f"{self.current_frame.f_globals.get('__name__', '?')}."
362
+ f"{self.current_frame.f_code.co_name}")
363
+ return True
364
+ else:
365
+ Console.write_stdout(f"Cannot move {direction} (at {'top' if direction < 0 else 'bottom'} of stack)")
366
+ return False
367
+
368
+ def handle_breakpoint(self, frame: FrameType):
369
+ """Handle a breakpoint by prompting for interactive commands."""
370
+ module = frame.f_globals.get('__name__')
371
+ func = frame.f_code.co_name
372
+
373
+ Console.write_stdout(f"\n{'='*60}")
374
+ Console.write_stdout(f"Paused at {module}.{func} (line {frame.f_lineno})")
375
+ self._print_source(frame, context=3)
376
+ Console.write_stdout(f"{'='*60}")
377
+ Console.write_stdout("Type 'h' for help, 'c' to continue")
378
+
379
+ while True:
380
+ try:
381
+ command = input("(geai-dbg) ").strip()
382
+ if not command:
383
+ continue
384
+
385
+ parts = command.split(None, 1)
386
+ cmd = parts[0]
387
+ args = parts[1] if len(parts) > 1 else ""
388
+
389
+ if cmd in ('continue', 'c'):
390
+ break
391
+ elif cmd in ('quit', 'q'):
392
+ self.logger.info("Debugger terminated by user.")
393
+ sys.exit(0)
394
+ elif cmd in ('run', 'r'):
395
+ self.logger.info("Running program without further pauses.")
396
+ sys.settrace(None)
397
+ break
398
+
399
+ elif cmd in ('step', 's'):
400
+ self.step_mode = 'step'
401
+ self.step_depth = self.current_depth
402
+ break
403
+ elif cmd in ('next', 'n'):
404
+ self.step_mode = 'next'
405
+ self.step_depth = self.current_depth
406
+ break
407
+ elif cmd in ('return', 'ret'):
408
+ self.step_mode = 'return'
409
+ self.step_frame = frame
410
+ break
411
+
412
+ elif cmd in ('up', 'u'):
413
+ self._move_frame(1)
414
+ elif cmd in ('down', 'd'):
415
+ self._move_frame(-1)
416
+ elif cmd in ('where', 'w', 'bt', 'backtrace'):
417
+ self._print_stack_trace()
418
+
419
+ elif cmd in ('list', 'l'):
420
+ context = int(args) if args.isdigit() else 10
421
+ self._print_source(self.current_frame, context)
422
+
423
+ elif cmd in ('print', 'p'):
424
+ if not args:
425
+ Console.write_stdout("Usage: p <expression>")
426
+ else:
427
+ try:
428
+ result = eval(args, self.current_frame.f_globals, self.current_frame.f_locals)
429
+ Console.write_stdout(repr(result))
430
+ except Exception as e:
431
+ Console.write_stdout(f"Error: {e}")
432
+
433
+ elif cmd in ('pp',):
434
+ if not args:
435
+ Console.write_stdout("Usage: pp <expression>")
436
+ else:
437
+ try:
438
+ result = eval(args, self.current_frame.f_globals, self.current_frame.f_locals)
439
+ pprint.pprint(result)
440
+ except Exception as e:
441
+ Console.write_stdout(f"Error: {e}")
442
+
443
+ elif cmd in ('locals', 'loc'):
444
+ Console.write_stdout("\nLocal variables:")
445
+ pprint.pprint(dict(self.current_frame.f_locals))
446
+
447
+ elif cmd in ('globals', 'glob'):
448
+ Console.write_stdout("\nGlobal variables:")
449
+ filtered = {k: v for k, v in self.current_frame.f_globals.items()
450
+ if not k.startswith('__')}
451
+ pprint.pprint(filtered)
452
+
453
+ elif cmd in ('args', 'a'):
454
+ Console.write_stdout("\nFunction arguments:")
455
+ arginfo = inspect.getargvalues(self.current_frame)
456
+ for arg in arginfo.args:
457
+ Console.write_stdout(f" {arg} = {repr(self.current_frame.f_locals.get(arg))}")
458
+
459
+ elif cmd in ('break', 'b'):
460
+ if not args:
461
+ bps = self.list_breakpoints()
462
+ if bps:
463
+ Console.write_stdout("\nBreakpoints:")
464
+ for i, bp in enumerate(bps, 1):
465
+ Console.write_stdout(f" {i}. {bp}")
466
+ else:
467
+ Console.write_stdout("No breakpoints set.")
468
+ else:
469
+ if ':' in args:
470
+ mod, func = args.split(':', 1)
471
+ mod = mod.strip() or None
472
+ func = func.strip() or None
473
+ else:
474
+ mod = None
475
+ func = args.strip()
476
+ self.add_breakpoint(module=mod, function_name=func)
477
+
478
+ elif cmd in ('tbreak', 'tb'):
479
+ Console.write_stdout("Temporary breakpoints not yet implemented.")
480
+
481
+ elif cmd in ('clear', 'cl'):
482
+ if args:
483
+ if ':' in args:
484
+ mod, func = args.split(':', 1)
485
+ mod = mod.strip() or None
486
+ func = func.strip() or None
487
+ else:
488
+ mod = None
489
+ func = args.strip()
490
+ self.remove_breakpoint(module=mod, function_name=func)
491
+ else:
492
+ Console.write_stdout("Usage: cl <breakpoint> or 'clearall' to remove all")
493
+
494
+ elif cmd in ('clearall', 'cla'):
495
+ self.clear_breakpoints()
496
+
497
+ elif cmd in ('enable', 'en'):
498
+ if ':' in args:
499
+ mod, func = args.split(':', 1)
500
+ mod = mod.strip() or None
501
+ func = func.strip() or None
502
+ else:
503
+ mod = None
504
+ func = args.strip()
505
+ self.enable_breakpoint(module=mod, function_name=func)
506
+
507
+ elif cmd in ('disable', 'dis'):
508
+ if ':' in args:
509
+ mod, func = args.split(':', 1)
510
+ mod = mod.strip() or None
511
+ func = func.strip() or None
512
+ else:
513
+ mod = None
514
+ func = args.strip()
515
+ self.disable_breakpoint(module=mod, function_name=func)
516
+
517
+ elif cmd in ('breakpoint-module', 'bm'):
518
+ self.logger.info("Adding breakpoint on module")
519
+ module_name = input("(geai-dbg) Enter module name (or press Enter for any module): ").strip()
520
+ module_name = module_name if module_name else None
521
+ self.add_breakpoint(module=module_name)
522
+
523
+ elif cmd in ('breakpoint-function', 'bf'):
524
+ self.logger.info("Adding breakpoint on function name")
525
+ function_name = input("(geai-dbg) Enter function name (or press Enter for any function): ").strip()
526
+ function_name = function_name if function_name else None
527
+ module_name = input("(geai-dbg) Enter module name (optional, press Enter to skip): ").strip()
528
+ module_name = module_name if module_name else None
529
+ self.add_breakpoint(module=module_name, function_name=function_name)
530
+
531
+ elif cmd in ('list-modules', 'lm'):
532
+ self.logger.info("Listing available modules")
533
+ modules = [m for m in sys.modules if m.startswith(self.module_filter)]
534
+ Console.write_stdout(f"\nAvailable modules ({len(modules)}):")
535
+ for mod in sorted(modules)[:50]:
536
+ Console.write_stdout(f" {mod}")
537
+ if len(modules) > 50:
538
+ Console.write_stdout(f" ... and {len(modules) - 50} more")
539
+
540
+ elif cmd in ('help', 'h', '?'):
541
+ self._print_help()
542
+
543
+ else:
544
+ self.logger.info(f"Executing interactive command: {command}")
545
+ try:
546
+ try:
547
+ exec(command, self.current_frame.f_globals, self.current_frame.f_locals)
548
+ except SyntaxError:
549
+ result = eval(command, self.current_frame.f_globals, self.current_frame.f_locals)
550
+ Console.write_stdout(repr(result))
551
+ except Exception as e:
552
+ self.logger.error(f"Command execution failed: {e}")
553
+ Console.write_stdout(f"Error: {e}")
554
+
555
+ except EOFError:
556
+ self.logger.info("Debugger terminated by user (EOF).")
557
+ sys.exit(0)
558
+ except KeyboardInterrupt:
559
+ self.logger.info("Keyboard interrupt received. Continuing execution.")
560
+ break
561
+
562
+ def _print_help(self):
563
+ """Print help message."""
564
+ help_text = """
565
+ Available commands:
566
+
567
+ Flow Control:
568
+ continue, c Resume execution until next breakpoint
569
+ step, s Step into function calls
570
+ next, n Step over function calls (same level)
571
+ return, ret Continue until current function returns
572
+ run, r Run program to completion (disable tracing)
573
+ quit, q Exit the debugger
574
+
575
+ Stack Navigation:
576
+ where, w, bt Show stack trace
577
+ up, u Move up one stack frame
578
+ down, d Move down one stack frame
579
+
580
+ Source Display:
581
+ list, l [n] Show source code (n lines of context, default 10)
582
+
583
+ Variable Inspection:
584
+ print, p <expr> Evaluate and print expression
585
+ pp <expr> Pretty-print expression
586
+ locals, loc Show local variables
587
+ globals, glob Show global variables
588
+ args, a Show function arguments
589
+
590
+ Breakpoints:
591
+ break, b List all breakpoints
592
+ b <func> Set breakpoint on function
593
+ b <module>:<func> Set breakpoint on module:function
594
+ clear, cl <bp> Remove breakpoint
595
+ clearall, cla Remove all breakpoints
596
+ enable, en <bp> Enable breakpoint
597
+ disable, dis <bp> Disable breakpoint
598
+
599
+ Legacy Commands:
600
+ breakpoint-module, bm Add module breakpoint (interactive)
601
+ breakpoint-function, bf Add function breakpoint (interactive)
602
+ list-modules, lm List available modules
603
+
604
+ Other:
605
+ help, h, ? Show this help
606
+ <Python code> Execute arbitrary Python code
607
+
608
+ Examples:
609
+ p sys.argv Print command-line arguments
610
+ b main Set breakpoint on any 'main' function
611
+ b pygeai.cli:main Set breakpoint on pygeai.cli.main
612
+ pp locals() Pretty-print all local variables
613
+ """
614
+ Console.write_stdout(help_text)
615
+
616
+ def run(self):
617
+ """Run the target callable under the debugger."""
618
+ self.logger.info("Setting trace and running target")
619
+ sys.settrace(self.trace_function)
620
+ try:
621
+ self.target()
622
+ except Exception as e:
623
+ self.logger.error(f"Target execution failed: {e}")
624
+ raise
625
+ finally:
626
+ self.logger.info("Cleaning up trace")
627
+ sys.settrace(None)
628
+
629
+
630
+ def debug_file(
631
+ filepath: str,
632
+ args: Optional[List[str]] = None,
633
+ module_filter: Optional[str] = None,
634
+ breakpoint_specs: Optional[List[Tuple[Optional[str], Optional[str]]]] = None,
635
+ verbose: bool = False,
636
+ log_level: str = 'DEBUG'
637
+ ) -> Debugger:
638
+ """
639
+ Debug a Python file by executing it under the debugger.
640
+
641
+ :param filepath: str - Path to the Python file to debug (required).
642
+ :param args: Optional[List[str]] - Command-line arguments to pass to the script (optional).
643
+ :param module_filter: Optional[str] - Module prefix to trace. None auto-detects based on file content (optional).
644
+ :param breakpoint_specs: Optional[List[Tuple[Optional[str], Optional[str]]]] - List of (module, function) tuples for initial breakpoints (optional).
645
+ :param verbose: bool - Enable verbose logging (default False).
646
+ :param log_level: str - Log level for verbose mode: 'DEBUG', 'INFO', 'WARNING', 'ERROR' (default 'DEBUG').
647
+ :return: Debugger - Configured Debugger instance ready to run.
648
+ :raises FileNotFoundError: If the specified file doesn't exist.
649
+ """
650
+ import os
651
+
652
+ if not os.path.isfile(filepath):
653
+ raise FileNotFoundError(f"File not found: {filepath}")
654
+
655
+ import runpy
656
+
657
+ old_argv = sys.argv.copy()
658
+ sys.argv = [filepath] + (args or [])
659
+
660
+ def target():
661
+ try:
662
+ # Use runpy to properly execute as __main__ module
663
+ # This ensures unittest.main() and similar tools work correctly
664
+ runpy.run_path(filepath, run_name='__main__')
665
+ finally:
666
+ sys.argv = old_argv
667
+
668
+ # Auto-detect module filter based on file content
669
+ if module_filter is None:
670
+ with open(filepath, 'r') as f:
671
+ content = f.read()
672
+ if 'pygeai' in content or 'from pygeai' in content or 'import pygeai' in content:
673
+ module_filter = ''
674
+ else:
675
+ module_filter = '__main__'
676
+
677
+ dbg = Debugger(target=target, module_filter=module_filter, verbose=verbose, log_level=log_level)
678
+
679
+ if breakpoint_specs:
680
+ for module, function in breakpoint_specs:
681
+ dbg.add_breakpoint(module=module, function_name=function)
682
+
683
+ return dbg
684
+
685
+
686
+ def debug_module(
687
+ module_name: str,
688
+ function_name: str = 'main',
689
+ args: Optional[List[str]] = None,
690
+ module_filter: Optional[str] = None
691
+ ) -> Debugger:
692
+ """
693
+ Debug a specific module and function by importing and executing it under the debugger.
694
+
695
+ :param module_name: str - Fully qualified module name, e.g., 'pygeai.cli.geai' (required).
696
+ :param function_name: str - Function to call within the module (default is 'main').
697
+ :param args: Optional[List[str]] - Command-line arguments to pass (optional).
698
+ :param module_filter: Optional[str] - Module prefix to trace. None defaults to first part of module_name (optional).
699
+ :return: Debugger - Configured Debugger instance with an automatic breakpoint on the target function.
700
+ :raises ImportError: If the module or function cannot be imported.
701
+ """
702
+ import importlib
703
+
704
+ old_argv = sys.argv.copy()
705
+ sys.argv = [module_name] + (args or [])
706
+
707
+ try:
708
+ module = importlib.import_module(module_name)
709
+ func = getattr(module, function_name)
710
+ except (ImportError, AttributeError) as e:
711
+ raise ImportError(f"Cannot import {module_name}.{function_name}: {e}")
712
+
713
+ def target():
714
+ try:
715
+ func()
716
+ finally:
717
+ sys.argv = old_argv
718
+
719
+ if module_filter is None:
720
+ module_filter = module_name.split('.')[0]
721
+
722
+ dbg = Debugger(target=target, module_filter=module_filter)
723
+ dbg.add_breakpoint(module=module_name, function_name=function_name)
724
+
725
+ return dbg
726
+
727
+
728
+ def main():
729
+ """
730
+ Entry point for geai-dbg command.
731
+
732
+ Usage:
733
+ geai-dbg Debug geai CLI (default)
734
+ geai-dbg script.py [args...] Debug a Python file
735
+ geai-dbg -m module:func [args...] Debug a module function
736
+ geai-dbg -h Show help
737
+ """
738
+ parser = argparse.ArgumentParser(
739
+ prog='geai-dbg',
740
+ description='Interactive debugger for PyGEAI applications',
741
+ formatter_class=argparse.RawDescriptionHelpFormatter,
742
+ epilog="""
743
+ Examples:
744
+ geai-dbg Debug the geai CLI
745
+ geai-dbg script.py arg1 arg2 Debug a Python file with arguments
746
+ geai-dbg -v script.py Debug with verbose logging (DEBUG level)
747
+ geai-dbg -v --log-level INFO script.py Debug with INFO level logging
748
+ geai-dbg -m pygeai.cli.geai:main Debug a specific module function
749
+ geai-dbg -b main script.py Break on 'main' function
750
+ geai-dbg --filter pygeai script.py Only trace pygeai modules
751
+ """
752
+ )
753
+
754
+ parser.add_argument(
755
+ 'target',
756
+ nargs='?',
757
+ default=None,
758
+ help='Python file to debug (omit to debug geai CLI)'
759
+ )
760
+
761
+ parser.add_argument(
762
+ 'args',
763
+ nargs='*',
764
+ help='Arguments to pass to the target'
765
+ )
766
+
767
+ parser.add_argument(
768
+ '-m', '--module',
769
+ metavar='MODULE:FUNC',
770
+ help='Debug a module function (format: module.path:function_name)'
771
+ )
772
+
773
+ parser.add_argument(
774
+ '-b', '--break',
775
+ dest='breakpoints',
776
+ action='append',
777
+ metavar='BREAKPOINT',
778
+ help='Set initial breakpoint (format: [module:]function, can be repeated)'
779
+ )
780
+
781
+ parser.add_argument(
782
+ '--filter',
783
+ metavar='PREFIX',
784
+ help='Module prefix to trace (default: auto-detect)'
785
+ )
786
+
787
+ parser.add_argument(
788
+ '--trace-all',
789
+ action='store_true',
790
+ help='Trace all modules (warning: may be slow)'
791
+ )
792
+
793
+ parser.add_argument(
794
+ '-v', '--verbose',
795
+ action='store_true',
796
+ help='Enable verbose logging for pygeai modules'
797
+ )
798
+
799
+ parser.add_argument(
800
+ '--log-level',
801
+ choices=['DEBUG', 'INFO', 'WARNING', 'ERROR'],
802
+ default='DEBUG',
803
+ help='Log level for verbose mode (default: DEBUG)'
804
+ )
805
+
806
+ parsed_args = parser.parse_args()
807
+
808
+ try:
809
+ if parsed_args.module:
810
+ if ':' in parsed_args.module:
811
+ module_name, func_name = parsed_args.module.split(':', 1)
812
+ else:
813
+ module_name = parsed_args.module
814
+ func_name = 'main'
815
+
816
+ dbg = debug_module(
817
+ module_name=module_name,
818
+ function_name=func_name,
819
+ args=parsed_args.args,
820
+ module_filter='' if parsed_args.trace_all else parsed_args.filter
821
+ )
822
+
823
+ elif parsed_args.target:
824
+ breakpoint_specs = []
825
+ if parsed_args.breakpoints:
826
+ for bp in parsed_args.breakpoints:
827
+ if ':' in bp:
828
+ mod, func = bp.split(':', 1)
829
+ breakpoint_specs.append((mod or None, func or None))
830
+ else:
831
+ breakpoint_specs.append((None, bp))
832
+
833
+ dbg = debug_file(
834
+ filepath=parsed_args.target,
835
+ args=parsed_args.args,
836
+ module_filter='' if parsed_args.trace_all else parsed_args.filter,
837
+ breakpoint_specs=breakpoint_specs if breakpoint_specs else None,
838
+ verbose=parsed_args.verbose,
839
+ log_level=parsed_args.log_level
840
+ )
841
+
842
+ else:
843
+ dbg = Debugger(module_filter='pygeai')
844
+ dbg.add_breakpoint(module='pygeai.cli.geai', function_name='main')
845
+
846
+ if parsed_args.breakpoints and not parsed_args.target:
847
+ for bp in parsed_args.breakpoints:
848
+ if ':' in bp:
849
+ mod, func = bp.split(':', 1)
850
+ dbg.add_breakpoint(module=mod or None, function_name=func or None)
851
+ else:
852
+ dbg.add_breakpoint(function_name=bp)
853
+
854
+ Console.write_stdout("GEAI Debugger started. Type 'h' for help, 'c' to continue, 'q' to quit.")
855
+
856
+ dbg.run()
857
+
858
+ except FileNotFoundError as e:
859
+ Console.write_stdout(f"Error: {e}")
860
+ sys.exit(1)
861
+ except ImportError as e:
862
+ Console.write_stdout(f"Error: {e}")
863
+ sys.exit(1)
864
+ except Exception as e:
865
+ logging.getLogger('geai.dbg').error(f"Debugger failed: {e}", exc_info=True)
866
+ sys.exit(1)
867
+
868
+
869
+ if __name__ == "__main__":
870
+ main()