pygeai 0.1.51b3__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 (648) hide show
  1. pygeai/__init__.py +9 -1
  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 +18 -45
  146. pygeai/assistant/data/clients.py +1 -0
  147. pygeai/assistant/data_analyst/clients.py +8 -12
  148. pygeai/assistant/managers.py +195 -157
  149. pygeai/assistant/mappers.py +4 -2
  150. pygeai/assistant/rag/clients.py +27 -67
  151. pygeai/assistant/rag/mappers.py +12 -6
  152. pygeai/assistant/rag/models.py +301 -159
  153. pygeai/auth/__init__.py +0 -0
  154. pygeai/auth/clients.py +129 -0
  155. pygeai/auth/endpoints.py +6 -0
  156. pygeai/chat/clients.py +308 -37
  157. pygeai/chat/endpoints.py +3 -0
  158. pygeai/chat/iris.py +2 -8
  159. pygeai/chat/managers.py +9 -6
  160. pygeai/chat/session.py +38 -0
  161. pygeai/chat/settings.py +6 -0
  162. pygeai/chat/ui.py +678 -0
  163. pygeai/cli/__init__.py +0 -1
  164. pygeai/cli/commands/admin.py +7 -10
  165. pygeai/cli/commands/analytics.py +533 -0
  166. pygeai/cli/commands/assistant.py +9 -9
  167. pygeai/cli/commands/auth.py +299 -0
  168. pygeai/cli/commands/base.py +71 -9
  169. pygeai/cli/commands/chat.py +676 -19
  170. pygeai/cli/commands/common.py +28 -24
  171. pygeai/cli/commands/configuration.py +66 -13
  172. pygeai/cli/commands/docs.py +105 -0
  173. pygeai/cli/commands/embeddings.py +58 -11
  174. pygeai/cli/commands/evaluation.py +38 -38
  175. pygeai/cli/commands/feedback.py +3 -4
  176. pygeai/cli/commands/files.py +7 -8
  177. pygeai/cli/commands/gam.py +85 -10
  178. pygeai/cli/commands/lab/ai_lab.py +340 -484
  179. pygeai/cli/commands/lab/options.py +8 -0
  180. pygeai/cli/commands/lab/spec.py +273 -0
  181. pygeai/cli/commands/lab/utils.py +13 -0
  182. pygeai/cli/commands/llm.py +6 -7
  183. pygeai/cli/commands/migrate.py +1064 -436
  184. pygeai/cli/commands/organization.py +516 -11
  185. pygeai/cli/commands/rag.py +13 -14
  186. pygeai/cli/commands/rerank.py +3 -5
  187. pygeai/cli/commands/secrets.py +8 -9
  188. pygeai/cli/commands/usage_limits.py +18 -20
  189. pygeai/cli/commands/validators.py +144 -1
  190. pygeai/cli/commands/version.py +4 -5
  191. pygeai/cli/error_handler.py +151 -0
  192. pygeai/cli/geai.py +170 -31
  193. pygeai/cli/geai_proxy.py +86 -25
  194. pygeai/cli/install_man.py +93 -22
  195. pygeai/cli/parsers.py +75 -25
  196. pygeai/cli/texts/help.py +265 -28
  197. pygeai/core/base/clients.py +53 -12
  198. pygeai/core/base/mappers.py +11 -2
  199. pygeai/core/base/session.py +95 -11
  200. pygeai/core/common/config.py +78 -14
  201. pygeai/core/common/exceptions.py +96 -6
  202. pygeai/core/embeddings/__init__.py +19 -0
  203. pygeai/core/embeddings/clients.py +23 -5
  204. pygeai/core/embeddings/managers.py +9 -4
  205. pygeai/core/embeddings/mappers.py +16 -2
  206. pygeai/core/embeddings/responses.py +9 -2
  207. pygeai/core/feedback/clients.py +8 -3
  208. pygeai/core/files/clients.py +23 -24
  209. pygeai/core/files/managers.py +121 -30
  210. pygeai/core/files/responses.py +4 -3
  211. pygeai/core/handlers.py +10 -1
  212. pygeai/core/llm/clients.py +22 -29
  213. pygeai/core/models.py +127 -11
  214. pygeai/core/plugins/clients.py +6 -6
  215. pygeai/core/rerank/clients.py +9 -3
  216. pygeai/core/rerank/managers.py +22 -5
  217. pygeai/core/secrets/clients.py +16 -37
  218. pygeai/core/services/response.py +18 -0
  219. pygeai/core/services/rest.py +159 -49
  220. pygeai/core/utils/__init__.py +0 -0
  221. pygeai/core/utils/console.py +83 -0
  222. pygeai/core/utils/parsers.py +32 -0
  223. pygeai/core/utils/validators.py +10 -0
  224. pygeai/dbg/__init__.py +3 -0
  225. pygeai/dbg/debugger.py +854 -14
  226. pygeai/evaluation/clients.py +7 -4
  227. pygeai/evaluation/dataset/clients.py +46 -44
  228. pygeai/evaluation/plan/clients.py +28 -26
  229. pygeai/evaluation/result/clients.py +38 -5
  230. pygeai/gam/clients.py +50 -28
  231. pygeai/gam/endpoints.py +2 -1
  232. pygeai/health/__init__.py +0 -0
  233. pygeai/health/clients.py +24 -0
  234. pygeai/health/endpoints.py +1 -0
  235. pygeai/lab/__init__.py +0 -90
  236. pygeai/lab/agents/clients.py +203 -162
  237. pygeai/lab/agents/endpoints.py +4 -0
  238. pygeai/lab/agents/mappers.py +57 -7
  239. pygeai/lab/clients.py +24 -0
  240. pygeai/lab/constants.py +3 -0
  241. pygeai/lab/managers.py +571 -541
  242. pygeai/lab/models.py +108 -19
  243. pygeai/lab/processes/clients.py +332 -340
  244. pygeai/lab/processes/mappers.py +3 -3
  245. pygeai/lab/runners.py +90 -0
  246. pygeai/lab/spec/__init__.py +0 -0
  247. pygeai/lab/spec/loader.py +24 -0
  248. pygeai/lab/spec/parsers.py +39 -0
  249. pygeai/lab/strategies/clients.py +67 -63
  250. pygeai/lab/strategies/mappers.py +1 -1
  251. pygeai/lab/tools/clients.py +85 -118
  252. pygeai/lab/tools/endpoints.py +4 -0
  253. pygeai/lab/tools/mappers.py +5 -5
  254. pygeai/man/man1/geai-proxy.1 +116 -0
  255. pygeai/man/man1/geai.1 +2580 -66
  256. pygeai/migration/__init__.py +33 -0
  257. pygeai/migration/strategies.py +468 -146
  258. pygeai/migration/tools.py +170 -3
  259. pygeai/organization/clients.py +245 -50
  260. pygeai/organization/endpoints.py +17 -8
  261. pygeai/organization/limits/clients.py +34 -32
  262. pygeai/organization/limits/managers.py +108 -49
  263. pygeai/organization/managers.py +347 -53
  264. pygeai/organization/mappers.py +102 -2
  265. pygeai/organization/responses.py +58 -1
  266. pygeai/proxy/clients.py +6 -3
  267. pygeai/proxy/config.py +14 -1
  268. pygeai/proxy/managers.py +61 -33
  269. pygeai/proxy/servers.py +196 -51
  270. pygeai/proxy/tool.py +33 -16
  271. pygeai/tests/admin/__init__.py +0 -0
  272. pygeai/tests/admin/test_clients.py +148 -0
  273. pygeai/tests/analytics/__init__.py +0 -0
  274. pygeai/tests/analytics/test_clients.py +86 -0
  275. pygeai/tests/analytics/test_managers.py +94 -0
  276. pygeai/tests/analytics/test_mappers.py +84 -0
  277. pygeai/tests/analytics/test_responses.py +73 -0
  278. pygeai/tests/assistants/rag/test_clients.py +346 -0
  279. pygeai/tests/assistants/rag/test_models.py +292 -0
  280. pygeai/tests/assistants/test_clients.py +176 -82
  281. pygeai/tests/assistants/test_managers.py +191 -57
  282. pygeai/tests/auth/__init__.py +0 -0
  283. pygeai/tests/auth/test_clients.py +289 -0
  284. pygeai/tests/auth/test_oauth.py +172 -0
  285. pygeai/tests/auth/test_session_logging.py +150 -0
  286. pygeai/tests/chat/__init__.py +0 -0
  287. pygeai/tests/chat/test_clients.py +393 -0
  288. pygeai/tests/chat/test_iris.py +38 -0
  289. pygeai/tests/chat/test_session.py +62 -0
  290. pygeai/tests/chat/test_ui.py +224 -0
  291. pygeai/tests/cli/commands/__init__.py +0 -0
  292. pygeai/tests/cli/commands/lab/__init__.py +0 -0
  293. pygeai/tests/cli/commands/lab/test_ai_lab.py +786 -0
  294. pygeai/tests/cli/commands/lab/test_common.py +208 -0
  295. pygeai/tests/cli/commands/lab/test_spec.py +246 -0
  296. pygeai/tests/cli/commands/test_assistant.py +202 -0
  297. pygeai/tests/cli/commands/test_chat.py +130 -0
  298. pygeai/tests/cli/commands/test_common.py +350 -0
  299. pygeai/tests/cli/commands/test_embeddings.py +132 -0
  300. pygeai/tests/cli/commands/test_evaluation.py +656 -0
  301. pygeai/tests/cli/commands/test_feedback.py +65 -0
  302. pygeai/tests/cli/commands/test_files.py +161 -0
  303. pygeai/tests/cli/commands/test_gam.py +201 -0
  304. pygeai/tests/cli/commands/test_llm.py +114 -0
  305. pygeai/tests/cli/commands/test_migrate.py +176 -0
  306. pygeai/tests/cli/commands/test_organization.py +276 -0
  307. pygeai/tests/cli/commands/test_rag.py +266 -0
  308. pygeai/tests/cli/commands/test_rerank.py +110 -0
  309. pygeai/tests/cli/commands/test_secrets.py +171 -0
  310. pygeai/tests/cli/commands/test_show_help.py +41 -0
  311. pygeai/tests/cli/commands/test_usage_limits.py +412 -0
  312. pygeai/tests/cli/commands/test_validators.py +160 -0
  313. pygeai/tests/cli/commands/test_version.py +81 -0
  314. pygeai/tests/cli/docker/__init__.py +0 -0
  315. pygeai/tests/cli/test_credentials_flag.py +316 -0
  316. pygeai/tests/cli/test_error_handler.py +225 -0
  317. pygeai/tests/cli/test_geai_driver.py +154 -0
  318. pygeai/tests/cli/test_parsers.py +5 -5
  319. pygeai/tests/core/base/data/models.py +7 -0
  320. pygeai/tests/core/base/test_mappers.py +43 -11
  321. pygeai/tests/core/base/test_models.py +3 -1
  322. pygeai/tests/core/base/test_responses.py +53 -0
  323. pygeai/tests/core/common/__init__.py +0 -0
  324. pygeai/tests/core/common/data/__init__.py +0 -0
  325. pygeai/tests/core/common/test_config.py +186 -0
  326. pygeai/tests/core/common/test_decorators.py +69 -0
  327. pygeai/tests/core/embeddings/__init__.py +0 -0
  328. pygeai/tests/core/embeddings/test_clients.py +225 -0
  329. pygeai/tests/core/embeddings/test_managers.py +171 -0
  330. pygeai/tests/core/embeddings/test_mappers.py +142 -0
  331. pygeai/tests/core/feedback/__init__.py +0 -0
  332. pygeai/tests/core/feedback/test_clients.py +64 -0
  333. pygeai/tests/core/files/test_clients.py +128 -0
  334. pygeai/tests/core/files/test_managers.py +124 -78
  335. pygeai/tests/core/files/test_mappers.py +137 -0
  336. pygeai/tests/core/files/test_models.py +103 -0
  337. pygeai/tests/core/files/test_responses.py +122 -0
  338. pygeai/tests/core/llm/__init__.py +0 -0
  339. pygeai/tests/core/llm/test_clients.py +142 -0
  340. pygeai/tests/core/plugins/__init__.py +0 -0
  341. pygeai/tests/core/plugins/test_clients.py +66 -0
  342. pygeai/tests/core/rerank/test_clients.py +76 -0
  343. pygeai/tests/core/rerank/test_managers.py +61 -39
  344. pygeai/tests/core/secrets/__init__.py +0 -0
  345. pygeai/tests/core/secrets/test_clients.py +264 -0
  346. pygeai/tests/core/services/__init__.py +0 -0
  347. pygeai/tests/core/services/test_rest.py +273 -0
  348. pygeai/tests/core/test_handlers.py +66 -0
  349. pygeai/tests/core/utils/__init__.py +0 -0
  350. pygeai/tests/core/utils/test_console.py +80 -0
  351. pygeai/tests/dbg/__init__.py +0 -0
  352. pygeai/tests/dbg/test_debugger.py +591 -0
  353. pygeai/tests/evaluation/__init__.py +0 -0
  354. pygeai/tests/evaluation/dataset/__init__.py +0 -0
  355. pygeai/tests/evaluation/dataset/test_clients.py +265 -0
  356. pygeai/tests/evaluation/plan/__init__.py +0 -0
  357. pygeai/tests/evaluation/plan/test_clients.py +195 -0
  358. pygeai/tests/evaluation/result/__init__.py +0 -0
  359. pygeai/tests/evaluation/result/test_clients.py +66 -0
  360. pygeai/tests/gam/__init__.py +0 -0
  361. pygeai/tests/gam/test_clients.py +195 -0
  362. pygeai/tests/health/__init__.py +0 -0
  363. pygeai/tests/health/test_clients.py +41 -0
  364. pygeai/tests/integration/__init__.py +0 -0
  365. pygeai/tests/integration/assistants/__init__.py +0 -0
  366. pygeai/tests/integration/assistants/rag/__init__.py +0 -0
  367. pygeai/tests/integration/assistants/rag/test_create_rag.py +91 -0
  368. pygeai/tests/integration/chat/__init__.py +0 -0
  369. pygeai/tests/integration/chat/test_generate_image.py +158 -0
  370. pygeai/tests/integration/lab/__init__.py +0 -0
  371. pygeai/tests/integration/lab/agents/__init__.py +0 -0
  372. pygeai/tests/integration/lab/agents/test_agents_list.py +106 -0
  373. pygeai/tests/integration/lab/agents/test_create_agent.py +319 -0
  374. pygeai/tests/integration/lab/agents/test_create_sharing_link.py +70 -0
  375. pygeai/tests/integration/lab/agents/test_delete_agent.py +75 -0
  376. pygeai/tests/integration/lab/agents/test_get_agent.py +94 -0
  377. pygeai/tests/integration/lab/agents/test_publish_agent_revision.py +127 -0
  378. pygeai/tests/integration/lab/agents/test_update_agent.py +250 -0
  379. pygeai/tests/integration/lab/processes/__init__.py +0 -0
  380. pygeai/tests/integration/lab/processes/test_create_process.py +345 -0
  381. pygeai/tests/integration/lab/processes/test_create_task.py +211 -0
  382. pygeai/tests/integration/lab/processes/test_delete_process.py +111 -0
  383. pygeai/tests/integration/lab/processes/test_get_process.py +201 -0
  384. pygeai/tests/integration/lab/processes/test_list_process_instances.py +91 -0
  385. pygeai/tests/integration/lab/processes/test_list_processes.py +138 -0
  386. pygeai/tests/integration/lab/processes/test_publish_process_revision.py +232 -0
  387. pygeai/tests/integration/lab/processes/test_update_process.py +289 -0
  388. pygeai/tests/integration/lab/reasoning_strategies/__init__.py +0 -0
  389. pygeai/tests/integration/lab/reasoning_strategies/test_get_reasoning_strategy.py +70 -0
  390. pygeai/tests/integration/lab/reasoning_strategies/test_list_reasoning_strategies.py +93 -0
  391. pygeai/tests/integration/lab/reasoning_strategies/test_update_reasoning_strategy.py +149 -0
  392. pygeai/tests/integration/lab/tools/__init__.py +0 -0
  393. pygeai/tests/integration/lab/tools/test_create_tool.py +288 -0
  394. pygeai/tests/integration/lab/tools/test_delete_tool.py +87 -0
  395. pygeai/tests/integration/lab/tools/test_get_parameter.py +98 -0
  396. pygeai/tests/integration/lab/tools/test_get_tool.py +91 -0
  397. pygeai/tests/integration/lab/tools/test_list_tools.py +106 -0
  398. pygeai/tests/integration/lab/tools/test_publish_tool_revision.py +119 -0
  399. pygeai/tests/integration/lab/tools/test_set_parameter.py +114 -0
  400. pygeai/tests/integration/lab/tools/test_update_tool.py +267 -0
  401. pygeai/tests/lab/agents/__init__.py +0 -0
  402. pygeai/tests/lab/agents/test_clients.py +481 -0
  403. pygeai/tests/lab/agents/test_mappers.py +440 -0
  404. pygeai/tests/lab/processes/__init__.py +0 -0
  405. pygeai/tests/lab/processes/test_clients.py +1416 -0
  406. pygeai/tests/lab/processes/test_mappers.py +1092 -0
  407. pygeai/tests/lab/spec/__init__.py +0 -0
  408. pygeai/tests/lab/spec/test_loader.py +59 -0
  409. pygeai/tests/lab/spec/test_parsers.py +182 -0
  410. pygeai/tests/lab/strategies/__init__.py +0 -0
  411. pygeai/tests/lab/strategies/test_clients.py +241 -0
  412. pygeai/tests/lab/strategies/test_mappers.py +132 -0
  413. pygeai/tests/lab/test_managers.py +553 -0
  414. pygeai/tests/lab/test_models.py +500 -3
  415. pygeai/tests/lab/tools/__init__.py +0 -0
  416. pygeai/tests/lab/tools/test_clients.py +521 -0
  417. pygeai/tests/lab/tools/test_mappers.py +198 -0
  418. pygeai/tests/migration/__init__.py +0 -0
  419. pygeai/tests/migration/test_strategies.py +405 -0
  420. pygeai/tests/migration/test_tools.py +159 -0
  421. pygeai/tests/organization/limits/test_clients.py +567 -0
  422. pygeai/tests/organization/limits/test_managers.py +298 -56
  423. pygeai/tests/organization/test_clients.py +600 -30
  424. pygeai/tests/organization/test_managers.py +424 -0
  425. pygeai/tests/organization/test_mappers.py +153 -0
  426. pygeai/tests/organization/test_responses.py +137 -0
  427. pygeai/tests/proxy/__init__.py +1 -0
  428. pygeai/tests/proxy/test_clients.py +397 -0
  429. pygeai/tests/proxy/test_config.py +171 -0
  430. pygeai/tests/proxy/test_integration.py +305 -0
  431. pygeai/tests/proxy/test_managers.py +312 -0
  432. pygeai/tests/proxy/test_servers.py +387 -0
  433. pygeai/tests/proxy/test_tool.py +176 -0
  434. pygeai/tests/snippets/analytics/__init__.py +0 -0
  435. pygeai/tests/snippets/analytics/get_agent_usage_per_user.py +16 -0
  436. pygeai/tests/snippets/analytics/get_agents_created_and_modified.py +11 -0
  437. pygeai/tests/snippets/analytics/get_average_cost_per_request.py +10 -0
  438. pygeai/tests/snippets/analytics/get_overall_error_rate.py +10 -0
  439. pygeai/tests/snippets/analytics/get_top_10_agents_by_requests.py +12 -0
  440. pygeai/tests/snippets/analytics/get_total_active_users.py +10 -0
  441. pygeai/tests/snippets/analytics/get_total_cost.py +10 -0
  442. pygeai/tests/snippets/analytics/get_total_requests_per_day.py +12 -0
  443. pygeai/tests/snippets/analytics/get_total_tokens.py +12 -0
  444. pygeai/tests/snippets/auth/__init__.py +0 -0
  445. pygeai/tests/snippets/chat/chat_completion_with_reasoning_effort.py +18 -0
  446. pygeai/tests/snippets/chat/get_response.py +15 -0
  447. pygeai/tests/snippets/chat/get_response_complete_example.py +67 -0
  448. pygeai/tests/snippets/chat/get_response_streaming.py +20 -0
  449. pygeai/tests/snippets/chat/get_response_with_files.py +16 -0
  450. pygeai/tests/snippets/chat/get_response_with_instructions.py +19 -0
  451. pygeai/tests/snippets/chat/get_response_with_metadata.py +24 -0
  452. pygeai/tests/snippets/chat/get_response_with_parallel_tools.py +58 -0
  453. pygeai/tests/snippets/chat/get_response_with_reasoning.py +21 -0
  454. pygeai/tests/snippets/chat/get_response_with_store.py +38 -0
  455. pygeai/tests/snippets/chat/get_response_with_tools.py +36 -0
  456. pygeai/tests/snippets/chat/get_response_with_truncation.py +24 -0
  457. pygeai/tests/snippets/dbg/__init__.py +0 -0
  458. pygeai/tests/snippets/dbg/basic_debugging.py +32 -0
  459. pygeai/tests/snippets/dbg/breakpoint_management.py +48 -0
  460. pygeai/tests/snippets/dbg/file_debugging.py +72 -0
  461. pygeai/tests/snippets/dbg/module_debugging.py +61 -0
  462. pygeai/tests/snippets/dbg/stack_navigation.py +45 -0
  463. pygeai/tests/snippets/dbg/stepping_example.py +40 -0
  464. pygeai/tests/snippets/embeddings/cache_example.py +31 -0
  465. pygeai/tests/snippets/embeddings/cohere_example.py +41 -0
  466. pygeai/tests/snippets/embeddings/openai_base64_example.py +27 -0
  467. pygeai/tests/snippets/embeddings/openai_example.py +30 -0
  468. pygeai/tests/snippets/embeddings/similarity_example.py +42 -0
  469. pygeai/tests/snippets/evaluation/dataset/__init__.py +0 -0
  470. pygeai/tests/snippets/evaluation/dataset/complete_workflow_example.py +195 -0
  471. pygeai/tests/snippets/evaluation/dataset/create_dataset.py +26 -0
  472. pygeai/tests/snippets/evaluation/dataset/create_dataset_from_file.py +11 -0
  473. pygeai/tests/snippets/evaluation/dataset/create_dataset_row.py +17 -0
  474. pygeai/tests/snippets/evaluation/dataset/create_expected_source.py +18 -0
  475. pygeai/tests/snippets/evaluation/dataset/create_filter_variable.py +19 -0
  476. pygeai/tests/snippets/evaluation/dataset/delete_dataset.py +9 -0
  477. pygeai/tests/snippets/evaluation/dataset/delete_dataset_row.py +10 -0
  478. pygeai/tests/snippets/evaluation/dataset/delete_expected_source.py +15 -0
  479. pygeai/tests/snippets/evaluation/dataset/delete_filter_variable.py +15 -0
  480. pygeai/tests/snippets/evaluation/dataset/get_dataset.py +9 -0
  481. pygeai/tests/snippets/evaluation/dataset/get_dataset_row.py +10 -0
  482. pygeai/tests/snippets/evaluation/dataset/get_expected_source.py +15 -0
  483. pygeai/tests/snippets/evaluation/dataset/get_filter_variable.py +15 -0
  484. pygeai/tests/snippets/evaluation/dataset/list_dataset_rows.py +9 -0
  485. pygeai/tests/snippets/evaluation/dataset/list_datasets.py +6 -0
  486. pygeai/tests/snippets/evaluation/dataset/list_expected_sources.py +10 -0
  487. pygeai/tests/snippets/evaluation/dataset/list_filter_variables.py +10 -0
  488. pygeai/tests/snippets/evaluation/dataset/update_dataset.py +15 -0
  489. pygeai/tests/snippets/evaluation/dataset/update_dataset_row.py +20 -0
  490. pygeai/tests/snippets/evaluation/dataset/update_expected_source.py +18 -0
  491. pygeai/tests/snippets/evaluation/dataset/update_filter_variable.py +19 -0
  492. pygeai/tests/snippets/evaluation/dataset/upload_dataset_rows_file.py +10 -0
  493. pygeai/tests/snippets/evaluation/plan/__init__.py +0 -0
  494. pygeai/tests/snippets/evaluation/plan/add_plan_system_metric.py +13 -0
  495. pygeai/tests/snippets/evaluation/plan/complete_workflow_example.py +136 -0
  496. pygeai/tests/snippets/evaluation/plan/create_evaluation_plan.py +24 -0
  497. pygeai/tests/snippets/evaluation/plan/create_rag_evaluation_plan.py +22 -0
  498. pygeai/tests/snippets/evaluation/plan/delete_evaluation_plan.py +9 -0
  499. pygeai/tests/snippets/evaluation/plan/delete_plan_system_metric.py +13 -0
  500. pygeai/tests/snippets/evaluation/plan/execute_evaluation_plan.py +11 -0
  501. pygeai/tests/snippets/evaluation/plan/get_evaluation_plan.py +9 -0
  502. pygeai/tests/snippets/evaluation/plan/get_plan_system_metric.py +13 -0
  503. pygeai/tests/snippets/evaluation/plan/get_system_metric.py +9 -0
  504. pygeai/tests/snippets/evaluation/plan/list_evaluation_plans.py +7 -0
  505. pygeai/tests/snippets/evaluation/plan/list_plan_system_metrics.py +9 -0
  506. pygeai/tests/snippets/evaluation/plan/list_system_metrics.py +7 -0
  507. pygeai/tests/snippets/evaluation/plan/update_evaluation_plan.py +22 -0
  508. pygeai/tests/snippets/evaluation/plan/update_plan_system_metric.py +14 -0
  509. pygeai/tests/snippets/evaluation/result/__init__.py +0 -0
  510. pygeai/tests/snippets/evaluation/result/complete_workflow_example.py +150 -0
  511. pygeai/tests/snippets/evaluation/result/get_evaluation_result.py +26 -0
  512. pygeai/tests/snippets/evaluation/result/list_evaluation_results.py +17 -0
  513. pygeai/tests/snippets/files/delete_file.py +1 -4
  514. pygeai/tests/snippets/files/get_file_content.py +2 -4
  515. pygeai/tests/snippets/files/get_file_data.py +1 -4
  516. pygeai/tests/snippets/files/get_file_list.py +1 -6
  517. pygeai/tests/snippets/files/upload_file.py +1 -5
  518. pygeai/tests/snippets/gam/gam_access_token.py +87 -0
  519. pygeai/tests/snippets/lab/agentic_flow_example_1.py +25 -23
  520. pygeai/tests/snippets/lab/agentic_flow_example_4.py +23 -23
  521. pygeai/tests/snippets/lab/agents/create_agent.py +5 -8
  522. pygeai/tests/snippets/lab/agents/create_agent_2.py +1 -5
  523. pygeai/tests/snippets/lab/agents/create_agent_edge_case.py +48 -0
  524. pygeai/tests/snippets/lab/agents/create_agent_with_permissions.py +39 -0
  525. pygeai/tests/snippets/lab/agents/create_agent_with_properties.py +46 -0
  526. pygeai/tests/snippets/lab/agents/create_agent_without_instructions.py +48 -0
  527. pygeai/tests/snippets/lab/agents/delete_agent.py +1 -5
  528. pygeai/tests/snippets/lab/agents/get_agent.py +2 -11
  529. pygeai/tests/snippets/lab/agents/get_agent_with_new_fields.py +62 -0
  530. pygeai/tests/snippets/lab/agents/get_sharing_link.py +2 -7
  531. pygeai/tests/snippets/lab/agents/list_agents.py +4 -7
  532. pygeai/tests/snippets/lab/agents/publish_agent_revision.py +2 -6
  533. pygeai/tests/snippets/lab/agents/update_agent.py +1 -5
  534. pygeai/tests/snippets/lab/agents/update_agent_properties.py +50 -0
  535. pygeai/tests/snippets/lab/assistant_to_agent.py +191 -0
  536. pygeai/tests/snippets/lab/crud_ui.py +462 -0
  537. pygeai/tests/snippets/lab/processes/create_process.py +3 -5
  538. pygeai/tests/snippets/lab/processes/create_task.py +3 -5
  539. pygeai/tests/snippets/lab/processes/jobs/list_jobs.py +10 -19
  540. pygeai/tests/snippets/lab/processes/kbs/create_kb.py +2 -5
  541. pygeai/tests/snippets/lab/processes/kbs/get_kb.py +10 -16
  542. pygeai/tests/snippets/lab/processes/kbs/list_kbs.py +13 -20
  543. pygeai/tests/snippets/lab/processes/kbs/try_all.py +5 -7
  544. pygeai/tests/snippets/lab/processes/list_processes.py +5 -7
  545. pygeai/tests/snippets/lab/runner_1.py +1 -1
  546. pygeai/tests/snippets/lab/samples/summarize_files.py +3 -3
  547. pygeai/tests/snippets/lab/strategies/create_reasoning_strategy.py +2 -5
  548. pygeai/tests/snippets/lab/strategies/get_reasoning_strategy.py +2 -5
  549. pygeai/tests/snippets/lab/strategies/list_reasoning_strategies.py +3 -6
  550. pygeai/tests/snippets/lab/strategies/update_reasoning_strategy.py +2 -5
  551. pygeai/tests/snippets/lab/tools/create_tool.py +4 -10
  552. pygeai/tests/snippets/lab/tools/create_tool_edge_case.py +50 -0
  553. pygeai/tests/snippets/lab/tools/delete_tool.py +2 -6
  554. pygeai/tests/snippets/lab/tools/get_parameter.py +5 -7
  555. pygeai/tests/snippets/lab/tools/get_tool.py +5 -7
  556. pygeai/tests/snippets/lab/tools/list_tools.py +3 -7
  557. pygeai/tests/snippets/lab/tools/publish_tool_revision.py +3 -5
  558. pygeai/tests/snippets/lab/tools/set_parameters.py +4 -9
  559. pygeai/tests/snippets/lab/tools/update_tool.py +4 -8
  560. pygeai/tests/snippets/lab/use_cases/__init__.py +0 -0
  561. pygeai/tests/snippets/lab/use_cases/create_cli_expert.py +1640 -0
  562. pygeai/tests/snippets/lab/use_cases/create_lab_expert.py +4541 -0
  563. pygeai/tests/snippets/lab/use_cases/create_tool_headless_web_browser.py +133 -0
  564. pygeai/tests/snippets/lab/use_cases/create_web_designer.py +189 -0
  565. pygeai/tests/snippets/lab/use_cases/create_web_reader.py +185 -0
  566. pygeai/tests/snippets/lab/{file_summarizer_example.py → use_cases/file_summarizer_example.py} +3 -3
  567. pygeai/tests/snippets/lab/{file_summarizer_example_2.py → use_cases/file_summarizer_example_2.py} +12 -12
  568. pygeai/tests/snippets/lab/use_cases/update_cli_expert.py +1773 -0
  569. pygeai/tests/snippets/lab/use_cases/update_lab_expert.py +4541 -0
  570. pygeai/tests/snippets/lab/use_cases/update_web_designer.py +188 -0
  571. pygeai/tests/snippets/lab/use_cases/update_web_reader.py +195 -0
  572. pygeai/tests/snippets/lab/use_cases/update_web_reader_with_tool.py +210 -0
  573. pygeai/tests/snippets/migrate/__init__.py +45 -0
  574. pygeai/tests/snippets/migrate/agent_migration.py +110 -0
  575. pygeai/tests/snippets/migrate/assistant_migration.py +64 -0
  576. pygeai/tests/snippets/migrate/orchestrator_examples.py +179 -0
  577. pygeai/tests/snippets/migrate/process_migration.py +64 -0
  578. pygeai/tests/snippets/migrate/project_migration.py +42 -0
  579. pygeai/tests/snippets/migrate/tool_migration.py +64 -0
  580. pygeai/tests/snippets/organization/add_project_member.py +10 -0
  581. pygeai/tests/snippets/organization/add_project_member_batch.py +44 -0
  582. pygeai/tests/snippets/organization/create_project.py +2 -2
  583. pygeai/tests/snippets/organization/get_memberships.py +12 -0
  584. pygeai/tests/snippets/organization/get_organization_members.py +6 -0
  585. pygeai/tests/snippets/organization/get_project_members.py +6 -0
  586. pygeai/tests/snippets/organization/get_project_memberships.py +12 -0
  587. pygeai/tests/snippets/organization/get_project_roles.py +6 -0
  588. pygeai/vendor/a2a/__init__.py +1 -0
  589. pygeai/vendor/a2a/auth/__init__.py +0 -0
  590. pygeai/vendor/a2a/auth/user.py +31 -0
  591. pygeai/vendor/a2a/client/__init__.py +19 -0
  592. pygeai/vendor/a2a/client/client.py +425 -0
  593. pygeai/vendor/a2a/client/errors.py +33 -0
  594. pygeai/vendor/a2a/client/helpers.py +22 -0
  595. pygeai/vendor/a2a/py.typed +0 -0
  596. pygeai/vendor/a2a/server/__init__.py +1 -0
  597. pygeai/vendor/a2a/server/agent_execution/__init__.py +18 -0
  598. pygeai/vendor/a2a/server/agent_execution/agent_executor.py +44 -0
  599. pygeai/vendor/a2a/server/agent_execution/context.py +155 -0
  600. pygeai/vendor/a2a/server/agent_execution/request_context_builder.py +20 -0
  601. pygeai/vendor/a2a/server/agent_execution/simple_request_context_builder.py +77 -0
  602. pygeai/vendor/a2a/server/apps/__init__.py +16 -0
  603. pygeai/vendor/a2a/server/apps/jsonrpc/__init__.py +16 -0
  604. pygeai/vendor/a2a/server/apps/jsonrpc/fastapi_app.py +88 -0
  605. pygeai/vendor/a2a/server/apps/jsonrpc/jsonrpc_app.py +426 -0
  606. pygeai/vendor/a2a/server/apps/jsonrpc/starlette_app.py +123 -0
  607. pygeai/vendor/a2a/server/context.py +23 -0
  608. pygeai/vendor/a2a/server/events/__init__.py +21 -0
  609. pygeai/vendor/a2a/server/events/event_consumer.py +149 -0
  610. pygeai/vendor/a2a/server/events/event_queue.py +156 -0
  611. pygeai/vendor/a2a/server/events/in_memory_queue_manager.py +85 -0
  612. pygeai/vendor/a2a/server/events/queue_manager.py +35 -0
  613. pygeai/vendor/a2a/server/request_handlers/__init__.py +20 -0
  614. pygeai/vendor/a2a/server/request_handlers/default_request_handler.py +435 -0
  615. pygeai/vendor/a2a/server/request_handlers/jsonrpc_handler.py +327 -0
  616. pygeai/vendor/a2a/server/request_handlers/request_handler.py +161 -0
  617. pygeai/vendor/a2a/server/request_handlers/response_helpers.py +133 -0
  618. pygeai/vendor/a2a/server/tasks/__init__.py +20 -0
  619. pygeai/vendor/a2a/server/tasks/inmemory_push_notifier.py +62 -0
  620. pygeai/vendor/a2a/server/tasks/inmemory_task_store.py +51 -0
  621. pygeai/vendor/a2a/server/tasks/push_notifier.py +25 -0
  622. pygeai/vendor/a2a/server/tasks/result_aggregator.py +151 -0
  623. pygeai/vendor/a2a/server/tasks/task_manager.py +253 -0
  624. pygeai/vendor/a2a/server/tasks/task_store.py +22 -0
  625. pygeai/vendor/a2a/server/tasks/task_updater.py +155 -0
  626. pygeai/vendor/a2a/types.py +1624 -0
  627. pygeai/vendor/a2a/utils/__init__.py +40 -0
  628. pygeai/vendor/a2a/utils/artifact.py +72 -0
  629. pygeai/vendor/a2a/utils/errors.py +69 -0
  630. pygeai/vendor/a2a/utils/helpers.py +176 -0
  631. pygeai/vendor/a2a/utils/message.py +83 -0
  632. pygeai/vendor/a2a/utils/task.py +57 -0
  633. pygeai/vendor/a2a/utils/telemetry.py +299 -0
  634. pygeai-0.6.0b15.dist-info/METADATA +205 -0
  635. pygeai-0.6.0b15.dist-info/RECORD +799 -0
  636. {pygeai-0.1.51b3.dist-info → pygeai-0.6.0b15.dist-info}/WHEEL +1 -1
  637. {pygeai-0.1.51b3.dist-info → pygeai-0.6.0b15.dist-info}/entry_points.txt +2 -1
  638. {pygeai-0.1.51b3.dist-info → pygeai-0.6.0b15.dist-info}/licenses/LICENSE +13 -1
  639. pygeai-0.6.0b15.dist-info/top_level.txt +1 -0
  640. docs/geai-proxy/README.md +0 -145
  641. docs/source/conf.py +0 -45
  642. pygeai/tests/core/test_managers.py +0 -233
  643. pygeai-0.1.51b3.dist-info/METADATA +0 -130
  644. pygeai-0.1.51b3.dist-info/RECORD +0 -324
  645. pygeai-0.1.51b3.dist-info/top_level.txt +0 -3
  646. scripts/bump_beta_version.py +0 -56
  647. {scripts → pygeai/analytics}/__init__.py +0 -0
  648. /pygeai/tests/snippets/lab/{c_code_fixer_agent_flow.py → use_cases/c_code_fixer_agent_flow.py} +0 -0
@@ -1,7 +1,7 @@
1
1
  from pydantic.main import BaseModel
2
2
 
3
3
  from pygeai.core.models import Assistant, Project, ProjectToken, \
4
- RequestItem
4
+ RequestItem, Role, Member, OrganizationMembership, ProjectMembership, Organization
5
5
 
6
6
 
7
7
  class AssistantListResponse(BaseModel):
@@ -22,3 +22,60 @@ class ProjectTokensResponse(BaseModel):
22
22
 
23
23
  class ProjectItemListResponse(BaseModel):
24
24
  items: list[RequestItem]
25
+
26
+ def to_list(self):
27
+ return [item.to_dict() for item in self.items] if self.items else []
28
+
29
+ def __getitem__(self, index: int) -> RequestItem:
30
+ if self.items is None:
31
+ raise IndexError("ProjectItemListResponse is empty")
32
+ return self.items[index]
33
+
34
+ def __len__(self) -> int:
35
+ return len(self.items) if self.items else 0
36
+
37
+ def __iter__(self):
38
+ """Make ProjectItemListResponse iterable over its items."""
39
+ if self.items is None:
40
+ return iter([])
41
+ return iter(self.items)
42
+
43
+ def append(self, item: RequestItem) -> None:
44
+ """Append an Agent instance to the items list."""
45
+ if self.items is None:
46
+ self.items = []
47
+ self.items.append(item)
48
+
49
+
50
+ class MembershipsResponse(BaseModel):
51
+ count: int
52
+ pages: int
53
+ organizations: list[OrganizationMembership]
54
+
55
+
56
+ class ProjectMembershipsResponse(BaseModel):
57
+ count: int
58
+ pages: int
59
+ projects: list[ProjectMembership]
60
+
61
+
62
+ class ProjectRolesResponse(BaseModel):
63
+ roles: list[Role]
64
+
65
+
66
+ class ProjectMembersResponse(BaseModel):
67
+ members: list[Member]
68
+
69
+
70
+ class OrganizationMembersResponse(BaseModel):
71
+ members: list[Member]
72
+
73
+
74
+ class OrganizationListResponse(BaseModel):
75
+ count: int
76
+ pages: int
77
+ organizations: list[Organization]
78
+
79
+
80
+ class OrganizationDataResponse(BaseModel):
81
+ organization: Organization
pygeai/proxy/clients.py CHANGED
@@ -3,7 +3,9 @@ from typing import Optional, Dict, Any, List
3
3
  import uuid
4
4
  import requests
5
5
  from urllib3.exceptions import MaxRetryError
6
- from pygeai.proxy.tool import MCPTool
6
+ from pygeai.proxy.tool import ProxiedTool
7
+ from pygeai.core.utils.validators import validate_status_code
8
+ from pygeai.core.utils.parsers import parse_json_response
7
9
 
8
10
 
9
11
  @dataclass
@@ -21,7 +23,7 @@ class ToolProxyData:
21
23
  name: Optional[str] = None
22
24
  description: Optional[str] = None
23
25
  affinity: Optional[uuid.UUID] = None
24
- tools: Optional[List[MCPTool]] = None
26
+ tools: Optional[List[ProxiedTool]] = None
25
27
 
26
28
  def to_dict(self) -> Dict[str, Any]:
27
29
  """
@@ -150,7 +152,8 @@ class ProxyClient:
150
152
  response = self.session.request(method, url, **kwargs)
151
153
  response.raise_for_status()
152
154
  try:
153
- return response.json()
155
+ validate_status_code(response)
156
+ return parse_json_response(response, "unknown operation")
154
157
  except ValueError:
155
158
  return response.text
156
159
  except requests.exceptions.Timeout:
pygeai/proxy/config.py CHANGED
@@ -1,7 +1,7 @@
1
1
  from pygeai.core.common.config import SettingsManager
2
2
  from typing import Optional
3
3
  import uuid
4
-
4
+ import os
5
5
 
6
6
  class ProxySettingsManager(SettingsManager):
7
7
  """
@@ -100,6 +100,19 @@ class ProxySettingsManager(SettingsManager):
100
100
  """
101
101
  self.set_setting_value("PROXY_AFFINITY", str(affinity), alias)
102
102
 
103
+ def get_setting_value(self, setting_key: str, alias: str):
104
+ """
105
+ Get the value of a specific setting for a specific alias.
106
+
107
+ :param setting_key: str - Key of the setting to get
108
+ :param alias: str - Alias for the settings section. Defaults to DEFAULT_ALIAS.
109
+ """
110
+ env_var_name = setting_key.upper()
111
+ if os.getenv(env_var_name) and alias == self.DEFAULT_ALIAS:
112
+ return os.getenv(env_var_name)
113
+ else:
114
+ return super().get_setting_value(setting_key, alias)
115
+
103
116
  def get_proxy_config(self, alias: str = DEFAULT_ALIAS) -> dict:
104
117
  """
105
118
  Get the complete proxy configuration for a specific alias.
pygeai/proxy/managers.py CHANGED
@@ -6,10 +6,11 @@ import sys
6
6
  import requests
7
7
  from urllib3.exceptions import MaxRetryError
8
8
  import mcp.types as types
9
- from pygeai.proxy.servers import Server, MCPTool
9
+ import a2a.types as a2a_types
10
+ from pygeai.proxy.servers import MCPServer, ToolServer, ProxiedTool, A2AServer
10
11
  from pygeai.proxy.config import ProxySettingsManager
11
12
  from pygeai.proxy.clients import ProxyClient, ToolProxyData, ToolProxyJobResult
12
-
13
+ from pygeai.core.utils.console import Console
13
14
 
14
15
  class ServerManager:
15
16
  """
@@ -28,8 +29,8 @@ class ServerManager:
28
29
  """
29
30
  self.servers_cfg = servers_cfg
30
31
  self.settings = settings
31
- self.servers: Dict[str, Server] = {}
32
- self.tools: Dict[str, MCPTool] = {}
32
+ self.servers: Dict[str, ToolServer] = {}
33
+ self.tools: Dict[str, ProxiedTool] = {}
33
34
  self.exit_stack: AsyncExitStack = AsyncExitStack()
34
35
 
35
36
  async def _initialize_servers(self) -> None:
@@ -40,23 +41,34 @@ class ServerManager:
40
41
  :raises: Exception - If server initialization fails
41
42
  """
42
43
  for server_cfg in self.servers_cfg:
43
- sys.stdout.write(f"Initializing server {server_cfg['name']}\n")
44
- server = Server(server_cfg['name'], server_cfg, self.settings)
44
+ Console.write_stdout(f"Initializing server {server_cfg['name']} type: {server_cfg['type']}")
45
+ if server_cfg['type'] == 'mcp':
46
+ server = MCPServer(server_cfg['name'], server_cfg, self.settings)
47
+ elif server_cfg['type'] == 'a2a':
48
+ server = A2AServer(server_cfg['name'], server_cfg, self.settings)
49
+ else:
50
+ raise ValueError(f"Invalid server type: {server_cfg['type']}")
45
51
  try:
46
52
  await self.exit_stack.enter_async_context(server.exit_stack)
47
53
  await server.initialize()
48
54
  self.servers[server.name] = server
49
- sys.stdout.write(f"Server {server.name} initialized successfully\n")
55
+ Console.write_stdout(f"\nServer {server.name} initialized successfully", end="\n\n")
50
56
  except Exception as e:
51
- sys.stdout.write(f"Failed to initialize server {server.name}: {e}\n")
57
+ Console.write_exception(f"Failed to initialize server {server.name}:", e)
52
58
  raise
53
59
 
54
60
  for server in self.servers.values():
55
- sys.stdout.write(f"Listing tools for server {server.name}\n")
61
+ Console.write_stdout(f"Listing tools for server {server.name}", end="")
62
+ if server.public_prefix:
63
+ Console.write_stdout(f" | access scope:public prefix: {server.public_prefix}")
64
+ else:
65
+ Console.write_stdout(" ! access scope:private")
66
+
56
67
  tools = await server.list_tools()
57
68
  for tool in tools:
58
69
  self.tools[tool.get_full_name()] = tool
59
- sys.stdout.write(f"\tTool {tool.get_full_name()} added to server {server.name}\n")
70
+ Console.write_stdout(f"\tTool {tool.get_full_name()} added to server {server.name}")
71
+
60
72
  async def _initialize_client(self) -> ProxyClient:
61
73
  """
62
74
  Initialize the client.
@@ -68,17 +80,29 @@ class ServerManager:
68
80
  try:
69
81
  alias = self.settings.get_current_alias()
70
82
  client = ProxyClient(self.settings.get_api_key(alias), self.settings.get_base_url(alias), self.settings.get_proxy_id(alias))
71
- sys.stdout.write(f"Registering proxy {self.settings.get_proxy_id(alias)} with name {self.settings.get_proxy_name(alias)} and description {self.settings.get_proxy_description(alias)} \n")
72
- client.register(proxy_data=ToolProxyData(
83
+ Console.write_stdout(f"\nRegistering proxy {self.settings.get_proxy_id(alias)} with name {self.settings.get_proxy_name(alias)} and description {self.settings.get_proxy_description(alias)}")
84
+ result = client.register(proxy_data=ToolProxyData(
73
85
  id=self.settings.get_proxy_id(alias),
74
86
  name=self.settings.get_proxy_name(alias),
75
87
  description=self.settings.get_proxy_description(alias),
76
88
  affinity=self.settings.get_proxy_affinity(alias),
77
89
  tools=list(self.tools.values())
78
90
  ))
79
- sys.stdout.write(f"Proxy registered successfully\n")
91
+ Console.write_stdout("----------------------------------")
92
+ Console.write_stdout(f"Proxy registered successfully:")
93
+ if isinstance(result, dict) and isinstance(result.get("Messages"), list):
94
+ for message in result["Messages"]:
95
+ description = message.get("Description", "")
96
+ message_type = message.get("Type", None)
97
+
98
+ if message_type == 1:
99
+ Console.write_stderr(description)
100
+ elif message_type == 2:
101
+ Console.write_stdout(description)
102
+ Console.write_stdout("----------------------------------")
80
103
  return client
81
104
  except (ConnectionError, MaxRetryError):
105
+ Console.write_exception(f"Error registering proxy {self.settings.get_proxy_id(alias)}:")
82
106
  raise
83
107
 
84
108
  async def execute_tool(
@@ -126,7 +150,7 @@ class ServerManager:
126
150
  data = json.loads(raw_json)
127
151
  return data['function']['name'], data['function']['arguments']
128
152
  except (json.JSONDecodeError, KeyError) as e:
129
- sys.stderr.write(f"Error extracting function call info: {e}\n")
153
+ Console.write_stdout(f"Error extracting function call info: {e}")
130
154
  return None, None
131
155
 
132
156
  async def start(self) -> None:
@@ -143,17 +167,16 @@ class ServerManager:
143
167
  try:
144
168
  client = await self._initialize_client()
145
169
  except (ConnectionError, TimeoutError, RuntimeError) as e:
146
- sys.stdout.write(f"Error during client initialization: {e}\n")
170
+ Console.write_exception(f"Error during client initialization:", e)
147
171
  for i in range(15, 0, -1):
148
- sys.stdout.write(f"\rRetrying in {i} seconds... ")
149
- sys.stdout.flush()
172
+ Console.write_stdout(f"\rRetrying in {i} seconds... ",'')
150
173
  await asyncio.sleep(1)
151
- sys.stdout.write("\rRetrying now... \n")
174
+ Console.write_stdout("\rRetrying now... ")
152
175
  retry_count += 1
153
176
  continue
154
177
 
155
178
  retry_count = 0
156
- sys.stdout.write(f"Waiting for jobs...\n")
179
+ Console.write_stdout(f"Waiting for jobs...")
157
180
  while True:
158
181
  try:
159
182
  jobs = client.dequeue()
@@ -161,24 +184,24 @@ class ServerManager:
161
184
  except requests.exceptions.RequestException as e:
162
185
  retry_count += 1
163
186
  if retry_count >= MAX_RETRIES:
164
- sys.stdout.write(f"Failed to dequeue jobs after {MAX_RETRIES} retries. \nException: {e}\nExiting...\n")
187
+ Console.write_stderr(f"Failed to dequeue jobs after {MAX_RETRIES} retries.")
188
+ Console.write_exception(f"Exception:", e, "\nExiting...")
165
189
  return
166
- sys.stdout.write(f"Failed to dequeue jobs (attempt {retry_count}/{MAX_RETRIES}):\n")
190
+ Console.write_stderr(f"Failed to dequeue jobs (attempt {retry_count}/{MAX_RETRIES}):")
167
191
  for i in range(15, 0, -1):
168
- sys.stdout.write(f"\rRetrying in {i} seconds... ")
169
- sys.stdout.flush()
192
+ Console.write_stdout(f"\rRetrying in {i} seconds... ",'')
170
193
  await asyncio.sleep(1)
171
- sys.stdout.write("\rRetrying now... \n")
194
+ Console.write_stdout("\rRetrying now... ")
172
195
  continue
173
196
  for job in jobs:
174
- sys.stdout.write(f"----------------------------------Job: {job.id}----------------------------------\n")
197
+ Console.write_stdout(f"----------------------------------Job: {job.id}----------------------------------")
175
198
  tool_name, arguments = self.extract_function_call_info(job.input)
176
199
  if tool_name:
177
- sys.stdout.write(f"Executing tool {job.server}/{tool_name} with arguments {arguments}\n")
200
+ Console.write_stdout(f"Executing tool {job.server}/{tool_name} with arguments {arguments}")
178
201
  try:
179
202
  result = await self.execute_tool(job.server, tool_name, json.loads(arguments))
180
- except (RuntimeError, ConnectionError, TimeoutError) as e:
181
- sys.stdout.write(f"Error executing tool {tool_name}: {e}\n")
203
+ except (Exception) as e:
204
+ Console.write_exception(f"Error executing tool {tool_name}:", e)
182
205
  continue
183
206
 
184
207
  if isinstance(result.content, list):
@@ -186,19 +209,24 @@ class ServerManager:
186
209
  for item in result.content:
187
210
  if isinstance(item, types.TextContent):
188
211
  text_parts.append(item.text)
212
+ elif isinstance(item, a2a_types.Part):
213
+ if isinstance(item.root, a2a_types.TextPart):
214
+ text_parts.append(item.root.text)
215
+ else:
216
+ Console.write_stdout(f"Unknown content type {type(item.root)}")
189
217
  else:
190
- sys.stderr.write(f"Unknown content type {type(item)}\n")
218
+ Console.write_stdout(f"Unknown content type {type(item)}")
191
219
 
192
220
  if text_parts:
193
221
  job.output = "\n".join(text_parts)
194
- sys.stdout.write(f"result: {job.output} success: {not result.isError}\n")
222
+ Console.write_stdout(f"result: {job.output} success: {not result.isError}")
195
223
  try:
196
224
  client.send_result(ToolProxyJobResult(success=result.isError, job=job))
197
225
  except (ConnectionError, TimeoutError, RuntimeError) as e:
198
- sys.stdout.write(f"Error sending result: {e}\n")
226
+ Console.write_exception("Error sending result:", e)
199
227
  else:
200
- sys.stdout.write(f"{result}\n")
228
+ Console.write_stdout(f"{result}")
201
229
  await asyncio.sleep(1)
202
230
  finally:
203
- sys.stdout.write("Proxy stopped\n")
231
+ Console.write_stdout("Proxy stopped")
204
232
  await self.exit_stack.aclose()
pygeai/proxy/servers.py CHANGED
@@ -1,27 +1,34 @@
1
1
  """Server module for managing MCP server connections and tool execution."""
2
-
3
2
  import asyncio
4
3
  import os
5
4
  import shutil
6
- import sys
5
+ import httpx
6
+ from types import SimpleNamespace
7
+ from uuid import uuid4
7
8
  from contextlib import AsyncExitStack
9
+ from abc import ABC, abstractmethod
8
10
  from typing import Any, Dict
9
11
  from mcp import ClientSession, StdioServerParameters
10
12
  from mcp.client.stdio import stdio_client
11
13
  from mcp.client.sse import sse_client
12
- from pygeai.proxy.tool import MCPTool
14
+ from pygeai.proxy.tool import ProxiedTool
13
15
  from pygeai.proxy.config import ProxySettingsManager
16
+ from a2a.client import A2AClient, A2ACardResolver
17
+ from a2a.types import (
18
+ AgentCard, SendMessageRequest, MessageSendParams,
19
+ Message, Task, SendMessageSuccessResponse
20
+ )
14
21
 
22
+ from pygeai.core.utils.console import Console
15
23
 
16
- class Server:
24
+ class ToolServer(ABC):
17
25
  """
18
- Manages MCP server connections and tool execution.
26
+ Interface for tool servers like MCP and A2A.
19
27
 
20
- :param sever_name: str - Name of the server
21
- :param config: Dict[str, Any] - Server configuration
22
- :param settings: ProxySettingsManager - Proxy settings manager
28
+ Subclasses must implement methods to initialize the server,
29
+ list available tools, and execute a tool.
23
30
  """
24
-
31
+
25
32
  def __init__(self, sever_name: str, config: Dict[str, Any], settings: ProxySettingsManager):
26
33
  """
27
34
  Initialize the server.
@@ -33,11 +40,10 @@ class Server:
33
40
  self.config = config
34
41
  self.settings = settings
35
42
  self.name: str = sever_name
36
- self.stdio_context: Any | None = None
37
- self.session: ClientSession | None = None
43
+ self.public_prefix: str | None = None
38
44
  self.exit_stack: AsyncExitStack = AsyncExitStack()
39
- self.publicpreffix: str | None = None
40
45
 
46
+ @abstractmethod
41
47
  async def initialize(self) -> None:
42
48
  """
43
49
  Initialize the server connection.
@@ -47,8 +53,155 @@ class Server:
47
53
  :raises: RuntimeError - If server initialization fails
48
54
  :raises: ConnectionError - If connection to server fails
49
55
  """
50
- self.publicpreffix = self.config.get("publicpreffix")
51
- transport = self.config.get("transport") or ("sse" if "uri" in self.config else "stdio")
56
+ pass
57
+
58
+ @abstractmethod
59
+ async def list_tools(self) -> list[ProxiedTool]:
60
+ """
61
+ List available tools from the server.
62
+
63
+ :return: list[Tool] - List of available tools
64
+ :raises: RuntimeError - If server is not initialized
65
+ """
66
+ pass
67
+
68
+ @abstractmethod
69
+ async def execute_tool(
70
+ self,
71
+ tool_name: str,
72
+ arguments: dict[str, Any],
73
+ retries: int = 2,
74
+ delay: float = 1.0,
75
+ ) -> Any:
76
+ """
77
+ Execute a tool with retry mechanism.
78
+
79
+ :param tool_name: str - Name of the tool to execute
80
+ :param arguments: dict[str, Any] - Tool arguments
81
+ :param retries: int - Number of retry attempts
82
+ :param delay: float - Delay between retries in seconds
83
+ :return: Any - Tool execution result
84
+ :raises: RuntimeError - If server is not initialized
85
+ :raises: ConnectionError - If connection to server fails
86
+ :raises: ValueError - If tool execution fails
87
+ """
88
+ pass
89
+
90
+ class A2AServer(ToolServer):
91
+ """
92
+ Manages A2A server connections and tool execution.
93
+ """
94
+ def __init__(self, sever_name: str, config: Dict[str, Any], settings: ProxySettingsManager):
95
+ super().__init__(sever_name, config, settings)
96
+ self.client: A2AClient | None = None
97
+ self.card_url: str = self.config["url"]
98
+ self.agent_card: AgentCard | None = None
99
+ self.httpx_client: httpx.AsyncClient | None = None
100
+
101
+ async def initialize(self) -> None:
102
+ """
103
+ Initialize the A2A client from the agent card and convert agent skills into tools
104
+ compatible with OpenAI function call format.
105
+ """
106
+ try:
107
+ self.httpx_client = httpx.AsyncClient(timeout=60.0)
108
+ self.public_prefix = self.config.get("public_prefix")
109
+ headers = self.config.get("headers")
110
+ if headers:
111
+ self.httpx_client.headers.update(headers)
112
+ resolver = A2ACardResolver(httpx_client=self.httpx_client, base_url=self.card_url)
113
+ self.agent_card = await resolver.get_agent_card()
114
+ self.client = A2AClient(httpx_client=self.httpx_client, agent_card=self.agent_card)
115
+
116
+ except httpx.HTTPError as e:
117
+ Console.write_exception(f"HTTP error initializing A2A server {self.name}:", e)
118
+ raise ConnectionError(f"Failed to connect to A2A server: {e}") from e
119
+ except ValueError as e:
120
+ Console.write_exception(f"Invalid configuration for A2A server {self.name}:" ,e)
121
+ raise ValueError(f"Invalid A2A server configuration: {e}") from e
122
+ except RuntimeError as e:
123
+ Console.write_exception(f"Runtime error initializing A2A server {self.name}:", e)
124
+ raise RuntimeError(f"A2A server initialization failed: {e}") from e
125
+
126
+ async def list_tools(self) -> list[ProxiedTool]:
127
+ if not self.client:
128
+ raise RuntimeError(f"Server {self.name} not initialized")
129
+ input_schema = {
130
+ "type": "object",
131
+ "properties": {
132
+ "input-text": {
133
+ "type": "string",
134
+ "description": "The input text to send to the agent for execution."
135
+ }
136
+ },
137
+ "required": ["input-text"]
138
+ }
139
+ tools = []
140
+ for skill in self.agent_card.skills:
141
+ tools.append(ProxiedTool(self.name, skill.id, skill.description, self.public_prefix, input_schema))
142
+ return tools
143
+
144
+ async def execute_tool(
145
+ self,
146
+ tool_name: str,
147
+ arguments: dict[str, Any],
148
+ retries: int = 2,
149
+ delay: float = 1.0,
150
+ ) -> Any:
151
+ Console.write_stdout(f"Executing {tool_name}...")
152
+ message_id = uuid4().hex
153
+ send_message_payload: dict[str, Any] = {
154
+ 'message': {
155
+ 'role': 'user',
156
+ 'parts': [
157
+ {
158
+ 'kind': 'text',
159
+ 'text': (
160
+ 'Use your skill:' + tool_name +
161
+ ' with this input:' + arguments["input-text"]
162
+ )
163
+ }
164
+ ],
165
+ 'messageId': message_id,
166
+ },
167
+ }
168
+ request = SendMessageRequest(
169
+ id=message_id,
170
+ params=MessageSendParams(**send_message_payload)
171
+ )
172
+
173
+ response = await self.client.send_message(request)
174
+ result = []
175
+ if isinstance(response.root, SendMessageSuccessResponse):
176
+ if isinstance(response.root.result, Message):
177
+ result = response.root.result.parts
178
+ elif isinstance(response.root, Task):
179
+ Console.write_stderr(f"Task response: {response.root.result}")
180
+ else:
181
+ Console.write_stderr(f"Unknown response type: {type(response.root)}")
182
+ raise ValueError(f"Unknown response type: {type(response.root)}")
183
+
184
+ return SimpleNamespace(content=result, isError=False)
185
+
186
+ class MCPServer(ToolServer):
187
+ """
188
+ Manages MCP server connections and tool execution.
189
+
190
+ :param sever_name: str - Name of the server
191
+ :param config: Dict[str, Any] - Server configuration
192
+ :param settings: ProxySettingsManager - Proxy settings manager
193
+ """
194
+ def __init__(self, sever_name: str, config: Dict[str, Any], settings: ProxySettingsManager):
195
+ super().__init__(sever_name, config, settings)
196
+ self.public_prefix = config.get("public_prefix")
197
+ self.stdio_context: Any | None = None
198
+ self.session: ClientSession | None = None
199
+
200
+ async def initialize(self) -> None:
201
+ self.public_prefix = self.config.get("public_prefix")
202
+ transport = self.config.get("transport") or (
203
+ "sse" if ("uri" in self.config or "url" in self.config) else "stdio"
204
+ )
52
205
  try:
53
206
  if transport == "stdio":
54
207
  command = (
@@ -62,9 +215,11 @@ class Server:
62
215
  server_params = StdioServerParameters(
63
216
  command=command,
64
217
  args=self.config["args"],
65
- env={**os.environ, **self.config["env"]}
66
- if self.config.get("env")
67
- else None,
218
+ env=(
219
+ {**os.environ, **self.config["env"]}
220
+ if self.config.get("env")
221
+ else None
222
+ ),
68
223
  )
69
224
 
70
225
  stdio_transport = await self.exit_stack.enter_async_context(
@@ -72,17 +227,19 @@ class Server:
72
227
  )
73
228
  read, write = stdio_transport
74
229
  elif transport == "sse":
75
- uri = self.config.get("uri")
230
+ uri = self.config.get("uri", self.config["url"])
76
231
  if not uri:
77
232
  raise ValueError("Missing 'uri' for sse transport")
78
-
79
- sse_transport = await self.exit_stack.enter_async_context(
80
- sse_client(
81
- url=self.config["uri"],
82
- headers=self.config.get("headers")
233
+ try:
234
+ sse_transport = await self.exit_stack.enter_async_context(
235
+ sse_client(
236
+ url=uri,
237
+ headers=self.config.get("headers")
238
+ )
83
239
  )
84
- )
85
- read, write = sse_transport
240
+ read, write = sse_transport
241
+ except httpx.HTTPStatusError as e:
242
+ Console.write_exception(f"HTTP error initializing MCP server {self.name}:", e)
86
243
  else:
87
244
  raise ValueError(f"Unsupported transport: {transport}")
88
245
 
@@ -92,16 +249,10 @@ class Server:
92
249
  await session.initialize()
93
250
  self.session = session
94
251
  except (RuntimeError, ConnectionError, ValueError) as e:
95
- sys.stderr.write(f"Error initializing server {self.name}: {e}\n")
252
+ Console.write_exception(f"Error initializing server {self.name}:", e)
96
253
  raise
97
254
 
98
- async def list_tools(self) -> list[MCPTool]:
99
- """
100
- List available tools from the server.
101
-
102
- :return: list[Tool] - List of available tools
103
- :raises: RuntimeError - If server is not initialized
104
- """
255
+ async def list_tools(self) -> list[ProxiedTool]:
105
256
  if not self.session:
106
257
  raise RuntimeError(f"Server {self.name} not initialized")
107
258
 
@@ -112,7 +263,13 @@ class Server:
112
263
  if isinstance(item, tuple) and item[0] == "tools":
113
264
  for tool in item[1]:
114
265
  tools.append(
115
- MCPTool(self.name, tool.name, tool.description, self.publicpreffix, tool.inputSchema)
266
+ ProxiedTool(
267
+ self.name,
268
+ tool.name,
269
+ tool.description,
270
+ self.public_prefix,
271
+ tool.inputSchema
272
+ )
116
273
  )
117
274
 
118
275
  return tools
@@ -124,36 +281,24 @@ class Server:
124
281
  retries: int = 2,
125
282
  delay: float = 1.0,
126
283
  ) -> Any:
127
- """
128
- Execute a tool with retry mechanism.
129
-
130
- :param tool_name: str - Name of the tool to execute
131
- :param arguments: dict[str, Any] - Tool arguments
132
- :param retries: int - Number of retry attempts
133
- :param delay: float - Delay between retries in seconds
134
- :return: Any - Tool execution result
135
- :raises: RuntimeError - If server is not initialized
136
- :raises: ConnectionError - If connection to server fails
137
- :raises: ValueError - If tool execution fails
138
- """
139
284
  if not self.session:
140
285
  raise RuntimeError(f"Server {self.name} not initialized")
141
286
 
142
287
  attempt = 0
143
288
  while attempt < retries:
144
289
  try:
145
- sys.stdout.write(f"Executing {tool_name}...\n")
290
+ Console.write_stdout(f"Executing {tool_name}...")
146
291
  result = await self.session.call_tool(tool_name, arguments)
147
292
  return result
148
293
 
149
294
  except (RuntimeError, ConnectionError, ValueError) as e:
150
295
  attempt += 1
151
- sys.stderr.write(
152
- f"Error executing tool: {e}. Attempt {attempt} of {retries}.\n"
296
+ Console.write_exception(
297
+ "Error executing tool:", e, f". Attempt {attempt} of {retries}.\n"
153
298
  )
154
299
  if attempt < retries:
155
- sys.stderr.write(f"Retrying in {delay} seconds...\n")
300
+ Console.write_stdout(f"Retrying in {delay} seconds...")
156
301
  await asyncio.sleep(delay)
157
302
  else:
158
- sys.stderr.write("Max retries reached. Failing.\n")
303
+ Console.write_stdout("Max retries reached. Failing.")
159
304
  raise