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,21 +1,31 @@
1
1
  import sys
2
2
  from abc import ABC, abstractmethod
3
+ from typing import Optional
3
4
 
4
- from pygeai.core.models import Project
5
+ from pygeai import logger
6
+ from pygeai.core.files.responses import UploadFileResponse
7
+ from pygeai.core.models import Project, UsageLimit
5
8
  from pygeai.core.base.responses import ErrorListResponse
9
+ from pygeai.core.utils.console import Console
10
+ from pygeai.core.files.managers import FileManager
11
+ from pygeai.core.files.models import File
6
12
  from pygeai.lab.managers import AILabManager
7
13
  from pygeai.lab.models import Agent, Tool, AgenticProcess, Task
14
+ from pygeai.organization.limits.managers import UsageLimitManager
8
15
  from pygeai.organization.managers import OrganizationManager
16
+ from pygeai.assistant.managers import AssistantManager
17
+ from pygeai.assistant.rag.models import RAGAssistant
18
+ from pygeai.core.secrets.clients import SecretClient
9
19
 
10
20
 
11
21
  class MigrationStrategy(ABC):
12
22
 
13
23
  def __init__(
14
24
  self,
15
- from_api_key: str = None,
16
- from_instance: str = None,
17
- to_api_key: str = None,
18
- to_instance: str = None
25
+ from_api_key: str,
26
+ from_instance: str,
27
+ to_api_key: Optional[str] = None,
28
+ to_instance: Optional[str] = None
19
29
  ):
20
30
  self.from_api_key = from_api_key
21
31
  self.from_instance = from_instance
@@ -26,112 +36,226 @@ class MigrationStrategy(ABC):
26
36
  def migrate(self):
27
37
  pass
28
38
 
39
+ def get_display_info(self) -> str:
40
+ """
41
+ Return a human-readable description of what this strategy will migrate.
42
+ Used for progress tracking and logging.
43
+
44
+ :return: String description like "agent abc-123" or "project MyProject"
45
+ """
46
+ return self.__class__.__name__.replace("MigrationStrategy", "").lower()
47
+
29
48
 
30
49
  class ProjectMigrationStrategy(MigrationStrategy):
31
50
  """
32
51
  Migrate a project from a GEAI instance.
33
52
  The target project can be in another organization or the same one; in the same instance or another.
53
+
54
+ Note: This strategy requires organization scope API keys for both source and destination,
55
+ as it needs to create projects and manage usage limits using the Organization API.
56
+ See: https://docs.globant.ai/en/wiki?22,Organization+API
34
57
  """
35
58
 
36
59
  def __init__(
37
60
  self,
38
- from_api_key: str = None,
39
- from_instance: str = None,
40
- to_api_key: str = None,
41
- to_instance: str = None,
42
- from_project_id: str = None,
43
- to_project_name: str = None,
44
- admin_email: str = None
61
+ from_api_key: str,
62
+ from_instance: str,
63
+ from_project_id: str,
64
+ to_project_name: str,
65
+ admin_email: str,
66
+ to_api_key: Optional[str] = None,
67
+ to_instance: Optional[str] = None
45
68
  ):
46
69
  super().__init__(from_api_key, from_instance, to_api_key, to_instance)
47
70
  self.from_project_id = from_project_id
48
71
  self.to_project_name = to_project_name
49
72
  self.admin_email = admin_email
50
- self.source_manager = OrganizationManager(
73
+ self._source_manager = OrganizationManager(
51
74
  api_key=self.from_api_key,
52
75
  base_url=self.from_instance
53
76
  )
54
- self.destination_manager = OrganizationManager(
77
+ self._destination_manager = OrganizationManager(
55
78
  api_key=self.to_api_key,
56
79
  base_url=self.to_instance
57
80
  )
58
81
 
59
- def migrate(self):
60
- response = self.__migrate_project()
61
- if isinstance(response, ErrorListResponse):
62
- return response.to_dict()
63
- else:
64
- new_project = response.project
65
-
66
- self.__migrate_assistants(new_project)
82
+ def get_display_info(self) -> str:
83
+ return f"project '{self.to_project_name}'"
67
84
 
68
- sys.stdout.write(f"Migrated project: \n{response}\n")
69
-
70
- def __migrate_project(self):
71
- project_data = self.source_manager.get_project_data(project_id=self.from_project_id)
85
+ def migrate(self):
86
+ """
87
+ Execute the project migration from source to destination instance.
88
+
89
+ :return: The ID of the created project
90
+ :raises ValueError: If project data cannot be retrieved or migration fails
91
+ """
92
+ new_project = self._migrate_project()
93
+ project_name = getattr(new_project, 'name', 'Unknown')
94
+ project_id = getattr(new_project, 'id', None)
95
+ logger.info(f"Successfully migrated project {self.from_project_id} to {project_name}")
96
+ return project_id
97
+
98
+ def _migrate_project(self) -> Project:
99
+ """
100
+ Migrate the project data and create it in the destination instance.
101
+
102
+ :return: The newly created project
103
+ :raises ValueError: If project retrieval or creation fails
104
+ """
105
+ project_data = self._source_manager.get_project_data(project_id=self.from_project_id)
106
+
107
+ if not hasattr(project_data, "project"):
108
+ raise ValueError(f"Unable to retrieve project data for project {self.from_project_id}")
72
109
 
73
110
  new_project = project_data.project
74
111
  new_project.name = self.to_project_name
75
112
  new_project.email = self.admin_email
76
- response = self.destination_manager.create_project(new_project)
77
-
78
- return response
113
+
114
+ logger.debug(f"Creating project with destination manager:")
115
+ logger.debug(f" - API Key (first 20 chars): {self.to_api_key[:20] if self.to_api_key else 'None'}...")
116
+ logger.debug(f" - Base URL: {self.to_instance}")
117
+ logger.debug(f" - Project Name: {self.to_project_name}")
118
+ logger.debug(f" - Admin Email: {self.admin_email}")
119
+
120
+ try:
121
+ response = self._destination_manager.create_project(new_project)
122
+ except Exception as e:
123
+ error_msg = f"Create project failed: {e}"
124
+ logger.error(error_msg)
125
+ logger.error(f" - Operation: Create project")
126
+ logger.error(f" - Base URL: {self.to_instance}")
127
+ logger.error(f" - API Key used (first 20 chars): {self.to_api_key[:20] if self.to_api_key else 'None'}...")
128
+ Console.write_stderr(f"\nDEBUG: Operation failed: Create project")
129
+ Console.write_stderr(f"DEBUG: Base URL: {self.to_instance}")
130
+ Console.write_stderr(f"DEBUG: API Key used (first 20 chars): {self.to_api_key[:20] if self.to_api_key else 'None'}...")
131
+ raise ValueError(error_msg) from e
79
132
 
80
- def __migrate_assistants(self, new_project: Project):
133
+ if isinstance(response, ErrorListResponse):
134
+ error_detail = response.to_dict()
135
+ logger.error(f"Create project returned error response: {error_detail}")
136
+ logger.error(f" - Operation: Create project")
137
+ logger.error(f" - Base URL: {self.to_instance}")
138
+ logger.error(f" - API Key used (first 20 chars): {self.to_api_key[:20] if self.to_api_key else 'None'}...")
139
+ Console.write_stderr(f"\nDEBUG: Operation failed: Create project")
140
+ Console.write_stderr(f"DEBUG: Base URL: {self.to_instance}")
141
+ Console.write_stderr(f"DEBUG: API Key used (first 20 chars): {self.to_api_key[:20] if self.to_api_key else 'None'}...")
142
+ raise ValueError(f"Failed to create project: {error_detail}")
143
+
144
+ if not response or not hasattr(response, "project"):
145
+ raise ValueError("Project creation returned invalid response")
146
+
147
+ return response.project
148
+
149
+ def _migrate_assistants(self, new_project: Project):
150
+ """
151
+ Migrate assistants associated with the project.
152
+
153
+ :param new_project: The newly created project to migrate assistants to
154
+ """
81
155
  pass
82
156
 
83
157
 
84
- class AgentMigrationStrategy(MigrationStrategy):
158
+ class _LabResourceMigrationStrategy(MigrationStrategy):
85
159
  """
86
- Migrate an agent from a GEAI instance.
87
- The target project can be in another organization or the same one; in the same instance or another.
160
+ Base class for migrating AI Lab resources (agents, tools, processes, tasks).
161
+ Provides common functionality for resource migration.
88
162
  """
89
163
 
90
164
  def __init__(
91
165
  self,
92
- from_api_key: str = None,
93
- from_instance: str = None,
94
- to_api_key: str = None,
95
- to_instance: str = None,
96
- from_project_id: str = None,
97
- to_project_id: str = None,
98
- agent_id: str = None
166
+ from_api_key: str,
167
+ from_instance: str,
168
+ to_api_key: Optional[str] = None,
169
+ to_instance: Optional[str] = None
99
170
  ):
100
171
  super().__init__(from_api_key, from_instance, to_api_key, to_instance)
101
- self.from_project_id = from_project_id
102
- self.to_project_id = to_project_id
103
- self.agent_id = agent_id
104
- self.source_manager = AILabManager(
172
+ self._source_manager = AILabManager(
105
173
  api_key=self.from_api_key,
106
174
  base_url=self.from_instance
107
175
  )
108
- self.destination_manager = AILabManager(
176
+ self._destination_manager = AILabManager(
109
177
  api_key=self.to_api_key,
110
178
  base_url=self.to_instance
111
179
  )
112
180
 
113
- def migrate(self):
114
- new_agent = self.__migrate_agent()
115
- if isinstance(new_agent, ErrorListResponse):
116
- sys.stderr.write(f"{new_agent.to_dict()}\n")
181
+ @abstractmethod
182
+ def _get_resource(self, resource_id: str):
183
+ """Retrieve the resource from source instance"""
184
+ pass
185
+
186
+ @abstractmethod
187
+ def _create_resource(self, resource):
188
+ """Create the resource in destination instance"""
189
+ pass
117
190
 
118
- sys.stdout.write(f"New agent detail: \n{new_agent}\n")
191
+ @abstractmethod
192
+ def _get_resource_name(self) -> str:
193
+ """Return the name of the resource type for logging/errors"""
194
+ pass
119
195
 
120
- def __migrate_agent(self):
121
- new_agent = None
122
- try:
123
- source_agent = self.source_manager.get_agent(project_id=self.from_project_id, agent_id=self.agent_id)
124
- if not isinstance(source_agent, Agent):
125
- raise ValueError("Unable to retrieve requested agent.")
196
+ def get_display_info(self) -> str:
197
+ resource_id = getattr(self, f"{self._get_resource_name()}_id", "unknown")
198
+ return f"{self._get_resource_name()} {resource_id}"
126
199
 
127
- new_agent = self.destination_manager.create_agent(project_id=self.to_project_id, agent=source_agent)
200
+ def migrate(self):
201
+ """
202
+ Execute the resource migration from source to destination instance.
203
+
204
+ :raises ValueError: If resource retrieval or creation fails
205
+ """
206
+ resource_id = getattr(self, f"{self._get_resource_name()}_id")
207
+ new_resource = self._migrate_resource(resource_id)
208
+ Console.write_stdout(f"New {self._get_resource_name()} detail: \n{new_resource}")
209
+ logger.info(f"Successfully migrated {self._get_resource_name()} {resource_id}")
210
+
211
+ def _migrate_resource(self, resource_id: str):
212
+ """
213
+ Retrieve resource from source and create in destination.
214
+
215
+ :param resource_id: The ID of the resource to migrate
216
+ :return: The newly created resource
217
+ :raises ValueError: If migration fails
218
+ """
219
+ try:
220
+ source_resource = self._get_resource(resource_id)
221
+ new_resource = self._create_resource(source_resource)
222
+ return new_resource
128
223
  except Exception as e:
129
- sys.stderr.write(f"Agent migration failed: {e} \n")
224
+ logger.error(f"{self._get_resource_name().capitalize()} migration failed: {e}")
225
+ raise ValueError(f"{self._get_resource_name().capitalize()} migration failed: {e}") from e
130
226
 
131
- return new_agent
132
227
 
228
+ class AgentMigrationStrategy(_LabResourceMigrationStrategy):
229
+ """
230
+ Migrate an agent from a GEAI instance.
231
+ The target project can be in another organization or the same one; in the same instance or another.
232
+ """
133
233
 
134
- class ToolMigrationStrategy(MigrationStrategy):
234
+ def __init__(
235
+ self,
236
+ from_api_key: str,
237
+ from_instance: str,
238
+ agent_id: str,
239
+ to_api_key: Optional[str] = None,
240
+ to_instance: Optional[str] = None
241
+ ):
242
+ super().__init__(from_api_key, from_instance, to_api_key, to_instance)
243
+ self.agent_id = agent_id
244
+
245
+ def _get_resource(self, resource_id: str) -> Agent:
246
+ agent = self._source_manager.get_agent(agent_id=resource_id)
247
+ if not isinstance(agent, Agent):
248
+ raise ValueError(f"Unable to retrieve agent {resource_id}")
249
+ return agent
250
+
251
+ def _create_resource(self, resource: Agent) -> Agent:
252
+ return self._destination_manager.create_agent(agent=resource)
253
+
254
+ def _get_resource_name(self) -> str:
255
+ return "agent"
256
+
257
+
258
+ class ToolMigrationStrategy(_LabResourceMigrationStrategy):
135
259
  """
136
260
  Migrate a tool from a GEAI instance.
137
261
  The target project can be in another organization or the same one; in the same instance or another.
@@ -139,143 +263,341 @@ class ToolMigrationStrategy(MigrationStrategy):
139
263
 
140
264
  def __init__(
141
265
  self,
142
- from_api_key: str = None,
143
- from_instance: str = None,
144
- to_api_key: str = None,
145
- to_instance: str = None,
146
- from_project_id: str = None,
147
- to_project_id: str = None,
148
- tool_id: str = None
266
+ from_api_key: str,
267
+ from_instance: str,
268
+ tool_id: str,
269
+ to_api_key: Optional[str] = None,
270
+ to_instance: Optional[str] = None
149
271
  ):
150
272
  super().__init__(from_api_key, from_instance, to_api_key, to_instance)
151
- self.from_project_id = from_project_id
152
- self.to_project_id = to_project_id
153
273
  self.tool_id = tool_id
154
- self.source_manager = AILabManager(
274
+
275
+ def _get_resource(self, resource_id: str) -> Tool:
276
+ tool = self._source_manager.get_tool(tool_id=resource_id)
277
+ if not isinstance(tool, Tool):
278
+ raise ValueError(f"Unable to retrieve tool {resource_id}")
279
+ return tool
280
+
281
+ def _create_resource(self, resource: Tool) -> Tool:
282
+ return self._destination_manager.create_tool(tool=resource)
283
+
284
+ def _get_resource_name(self) -> str:
285
+ return "tool"
286
+
287
+
288
+ class AgenticProcessMigrationStrategy(_LabResourceMigrationStrategy):
289
+ """
290
+ Migrate an agentic process from a GEAI instance.
291
+ The target project can be in another organization or the same one; in the same instance or another.
292
+ """
293
+
294
+ def __init__(
295
+ self,
296
+ from_api_key: str,
297
+ from_instance: str,
298
+ process_id: str,
299
+ to_api_key: Optional[str] = None,
300
+ to_instance: Optional[str] = None
301
+ ):
302
+ super().__init__(from_api_key, from_instance, to_api_key, to_instance)
303
+ self.process_id = process_id
304
+
305
+ def _get_resource(self, resource_id: str) -> AgenticProcess:
306
+ process = self._source_manager.get_process(process_id=resource_id)
307
+ if not isinstance(process, AgenticProcess):
308
+ raise ValueError(f"Unable to retrieve process {resource_id}")
309
+ return process
310
+
311
+ def _create_resource(self, resource: AgenticProcess) -> AgenticProcess:
312
+ return self._destination_manager.create_process(process=resource)
313
+
314
+ def _get_resource_name(self) -> str:
315
+ return "process"
316
+
317
+
318
+ class TaskMigrationStrategy(_LabResourceMigrationStrategy):
319
+ """
320
+ Migrate a task from a GEAI instance.
321
+ The target project can be in another organization or the same one; in the same instance or another.
322
+ """
323
+
324
+ def __init__(
325
+ self,
326
+ from_api_key: str,
327
+ from_instance: str,
328
+ task_id: str,
329
+ to_api_key: Optional[str] = None,
330
+ to_instance: Optional[str] = None
331
+ ):
332
+ super().__init__(from_api_key, from_instance, to_api_key, to_instance)
333
+ self.task_id = task_id
334
+
335
+ def _get_resource(self, resource_id: str) -> Task:
336
+ task = self._source_manager.get_task(task_id=resource_id)
337
+ if not isinstance(task, Task):
338
+ raise ValueError(f"Unable to retrieve task {resource_id}")
339
+ return task
340
+
341
+ def _create_resource(self, resource: Task) -> Task:
342
+ return self._destination_manager.create_task(task=resource)
343
+
344
+ def _get_resource_name(self) -> str:
345
+ return "task"
346
+
347
+
348
+ class UsageLimitMigrationStrategy(MigrationStrategy):
349
+ """
350
+ Migrate usage limit from a GEAI organization.
351
+ The target organization can be in the same instance or another.
352
+ """
353
+
354
+ def __init__(
355
+ self,
356
+ from_api_key: str,
357
+ from_instance: str,
358
+ from_organization_id: str,
359
+ to_organization_id: str,
360
+ to_api_key: Optional[str] = None,
361
+ to_instance: Optional[str] = None
362
+ ):
363
+ super().__init__(from_api_key, from_instance, to_api_key, to_instance)
364
+ self.from_organization_id = from_organization_id
365
+ self.to_organization_id = to_organization_id
366
+ self._source_manager = UsageLimitManager(
155
367
  api_key=self.from_api_key,
156
- base_url=self.from_instance
368
+ base_url=self.from_instance,
369
+ organization_id=self.from_organization_id
157
370
  )
158
- self.destination_manager = AILabManager(
371
+ self._destination_manager = UsageLimitManager(
159
372
  api_key=self.to_api_key,
160
- base_url=self.to_instance
373
+ base_url=self.to_instance,
374
+ organization_id=self.to_organization_id
161
375
  )
162
376
 
163
- def migrate(self):
164
- new_tool = self.__migrate_tool()
165
- if isinstance(new_tool, ErrorListResponse):
166
- sys.stderr.write(f"{new_tool.to_dict()}\n")
377
+ def get_display_info(self) -> str:
378
+ return f"usage limits (org {self.from_organization_id})"
167
379
 
168
- sys.stdout.write(f"New tool detail: \n{new_tool}\n")
169
-
170
- def __migrate_tool(self):
171
- new_tool = None
380
+ def migrate(self):
381
+ """
382
+ Execute the usage limit migration from source to destination organization.
383
+
384
+ :raises ValueError: If usage limit retrieval or creation fails
385
+ """
386
+ new_limit = self._migrate_usage_limit()
387
+ logger.info(f"Successfully migrated usage limit from org {self.from_organization_id} to {self.to_organization_id}")
388
+
389
+ def _migrate_usage_limit(self) -> UsageLimit:
390
+ """
391
+ Retrieve latest usage limit from source and create in destination.
392
+
393
+ :return: The newly created usage limit
394
+ :raises ValueError: If migration fails
395
+ """
172
396
  try:
173
- source_tool = self.source_manager.get_tool(project_id=self.from_project_id, tool_id=self.tool_id)
174
- if not isinstance(source_tool, Tool):
175
- raise ValueError("Unable to retrieve requested tool.")
397
+ source_limit = self._source_manager.get_latest_usage_limit_from_organization()
398
+ if not isinstance(source_limit, UsageLimit):
399
+ raise ValueError("Unable to retrieve usage limit from source organization")
176
400
 
177
- new_tool = self.destination_manager.create_tool(project_id=self.to_project_id, tool=source_tool)
401
+ source_limit.id = None
402
+ new_limit = self._destination_manager.set_organization_usage_limit(source_limit)
403
+ return new_limit
178
404
  except Exception as e:
179
- sys.stderr.write(f"Tool migration failed: {e}\n")
405
+ logger.error(f"Usage limit migration failed: {e}")
406
+ raise ValueError(f"Usage limit migration failed: {e}") from e
180
407
 
181
- return new_tool
182
408
 
183
-
184
- class AgenticProcessMigrationStrategy(MigrationStrategy):
409
+ class RAGAssistantMigrationStrategy(MigrationStrategy):
185
410
  """
186
- Migrate an agentic process from a GEAI instance.
187
- The target project can be in another organization or the same one; in the same instance or another.
411
+ Migrate RAG assistant from a GEAI instance.
412
+ The target instance can be the same or another.
188
413
  """
189
414
 
190
415
  def __init__(
191
416
  self,
192
- from_api_key: str = None,
193
- from_instance: str = None,
194
- to_api_key: str = None,
195
- to_instance: str = None,
196
- from_project_id: str = None,
197
- to_project_id: str = None,
198
- process_id: str = None
417
+ from_api_key: str,
418
+ from_instance: str,
419
+ assistant_name: str,
420
+ to_api_key: Optional[str] = None,
421
+ to_instance: Optional[str] = None
199
422
  ):
200
423
  super().__init__(from_api_key, from_instance, to_api_key, to_instance)
201
- self.from_project_id = from_project_id
202
- self.to_project_id = to_project_id
203
- self.process_id = process_id
204
- self.source_manager = AILabManager(
424
+ self.assistant_name = assistant_name
425
+ self._source_manager = AssistantManager(
205
426
  api_key=self.from_api_key,
206
427
  base_url=self.from_instance
207
428
  )
208
- self.destination_manager = AILabManager(
429
+ self._destination_manager = AssistantManager(
209
430
  api_key=self.to_api_key,
210
431
  base_url=self.to_instance
211
432
  )
212
433
 
213
- def migrate(self):
214
- new_process = self.__migrate_process()
215
- if isinstance(new_process, ErrorListResponse):
216
- sys.stdout.write(f"{new_process.to_dict()}\n")
217
-
218
- sys.stdout.write(f"New process detail: \n{new_process}\n")
434
+ def get_display_info(self) -> str:
435
+ return f"RAG assistant '{self.assistant_name}'"
219
436
 
220
- def __migrate_process(self):
221
- new_process = None
437
+ def migrate(self):
438
+ """
439
+ Execute the RAG assistant migration from source to destination instance.
440
+
441
+ :raises ValueError: If assistant retrieval or creation fails
442
+ """
443
+ new_assistant = self._migrate_assistant()
444
+ logger.info(f"Successfully migrated RAG assistant {self.assistant_name}")
445
+
446
+ def _migrate_assistant(self) -> RAGAssistant:
447
+ """
448
+ Retrieve RAG assistant from source and create in destination.
449
+
450
+ :return: The newly created RAG assistant
451
+ :raises ValueError: If migration fails
452
+ """
222
453
  try:
223
- source_process = self.source_manager.get_process(project_id=self.from_project_id, process_id=self.process_id)
224
- if not isinstance(source_process, AgenticProcess):
225
- raise ValueError("Unable to retrieve requested process.")
454
+ source_assistant = self._source_manager.get_assistant_data(assistant_name=self.assistant_name)
455
+ if not isinstance(source_assistant, RAGAssistant):
456
+ raise ValueError(f"Assistant {self.assistant_name} is not a RAG assistant")
226
457
 
227
- new_process = self.destination_manager.create_process(project_id=self.to_project_id, process=source_process)
458
+ source_assistant.id = None
459
+ new_assistant = self._destination_manager.create_assistant(source_assistant)
460
+ return new_assistant
228
461
  except Exception as e:
229
- sys.stderr.write(f"Process migration failed: {e}\n")
462
+ logger.error(f"RAG assistant migration failed: {e}")
463
+ raise ValueError(f"RAG assistant migration failed: {e}") from e
230
464
 
231
- return new_process
232
465
 
233
-
234
- class TaskMigrationStrategy(MigrationStrategy):
466
+ class FileMigrationStrategy(MigrationStrategy):
235
467
  """
236
- Migrate a task from a GEAI instance.
468
+ Migrate file from a GEAI project.
237
469
  The target project can be in another organization or the same one; in the same instance or another.
238
470
  """
239
471
 
240
472
  def __init__(
241
473
  self,
242
- from_api_key: str = None,
243
- from_instance: str = None,
244
- to_api_key: str = None,
245
- to_instance: str = None,
246
- from_project_id: str = None,
247
- to_project_id: str = None,
248
- task_id: str = None
474
+ from_api_key: str,
475
+ from_instance: str,
476
+ from_organization_id: str,
477
+ from_project_id: str,
478
+ to_organization_id: str,
479
+ to_project_id: str,
480
+ file_id: str,
481
+ to_api_key: Optional[str] = None,
482
+ to_instance: Optional[str] = None
249
483
  ):
250
484
  super().__init__(from_api_key, from_instance, to_api_key, to_instance)
485
+ self.from_organization_id = from_organization_id
251
486
  self.from_project_id = from_project_id
487
+ self.to_organization_id = to_organization_id
252
488
  self.to_project_id = to_project_id
253
- self.task_id = task_id
254
- self.source_manager = AILabManager(
489
+ self.file_id = file_id
490
+ self._source_manager = FileManager(
255
491
  api_key=self.from_api_key,
256
- base_url=self.from_instance
492
+ base_url=self.from_instance,
493
+ organization_id=self.from_organization_id,
494
+ project_id=self.from_project_id
257
495
  )
258
- self.destination_manager = AILabManager(
496
+ self._destination_manager = FileManager(
259
497
  api_key=self.to_api_key,
260
- base_url=self.to_instance
498
+ base_url=self.to_instance,
499
+ organization_id=self.to_organization_id,
500
+ project_id=self.to_project_id
261
501
  )
262
502
 
503
+ def get_display_info(self) -> str:
504
+ return f"file {self.file_id}"
505
+
263
506
  def migrate(self):
264
- new_task = self.__migrate_task()
265
- if isinstance(new_task, ErrorListResponse):
266
- sys.stderr.write(f"{new_task.to_dict()}\n")
507
+ """
508
+ Execute the file migration from source to destination project.
509
+
510
+ :raises ValueError: If file retrieval or upload fails
511
+ """
512
+ upload_file_response = self._migrate_file()
513
+ logger.info(f"Successfully migrated file {self.file_id}")
514
+
515
+ def _migrate_file(self) -> UploadFileResponse:
516
+ """
517
+ Retrieve file from source and upload to destination.
518
+
519
+ :return: The newly uploaded file
520
+ :raises ValueError: If migration fails
521
+ """
522
+ try:
523
+ source_file = self._source_manager.get_file_data(file_id=self.file_id)
524
+ if not isinstance(source_file, File):
525
+ raise ValueError(f"Unable to retrieve file {self.file_id}")
526
+
527
+ file_content = self._source_manager.get_file_content(file_id=self.file_id)
528
+ upload_response = self._destination_manager.upload_file_from_content(
529
+ file_name=source_file.name,
530
+ content=file_content,
531
+ folder=None
532
+ )
533
+ return upload_response
534
+ except Exception as e:
535
+ logger.error(f"File migration failed: {e}")
536
+ raise ValueError(f"File migration failed: {e}") from e
267
537
 
268
- sys.stdout.write(f"New task detail: \n{new_task}\n")
269
538
 
270
- def __migrate_task(self):
271
- new_task = None
272
- try:
273
- source_task = self.source_manager.get_task(project_id=self.from_project_id, task_id=self.task_id)
274
- if not isinstance(source_task, Task):
275
- raise ValueError("Unable to retrieve requested task.")
539
+ class SecretMigrationStrategy(MigrationStrategy):
540
+ """
541
+ Migrate secret from a GEAI project.
542
+ The target project can be in another organization or the same one; in the same instance or another.
543
+ """
276
544
 
277
- new_task = self.destination_manager.create_task(project_id=self.to_project_id, task=source_task)
278
- except Exception as e:
279
- sys.stderr.write(f"Task migration failed: {e}\n")
545
+ def __init__(
546
+ self,
547
+ from_api_key: str,
548
+ from_instance: str,
549
+ secret_id: str,
550
+ to_api_key: Optional[str] = None,
551
+ to_instance: Optional[str] = None
552
+ ):
553
+ super().__init__(from_api_key, from_instance, to_api_key, to_instance)
554
+ self.secret_id = secret_id
555
+ self._source_client = SecretClient(
556
+ api_key=self.from_api_key,
557
+ base_url=self.from_instance
558
+ )
559
+ self._destination_client = SecretClient(
560
+ api_key=self.to_api_key,
561
+ base_url=self.to_instance
562
+ )
563
+
564
+ def get_display_info(self) -> str:
565
+ return f"secret {self.secret_id}"
280
566
 
281
- return new_task
567
+ def migrate(self):
568
+ """
569
+ Execute the secret migration from source to destination project.
570
+
571
+ :raises ValueError: If secret retrieval or creation fails
572
+ """
573
+ new_secret = self._migrate_secret()
574
+ logger.info(f"Successfully migrated secret {self.secret_id}")
575
+
576
+ def _migrate_secret(self) -> dict:
577
+ """
578
+ Retrieve secret from source and create in destination.
579
+
580
+ :return: The newly created secret
581
+ :raises ValueError: If migration fails
582
+ """
583
+ try:
584
+ source_secret = self._source_client.get_secret(secret_id=self.secret_id)
585
+ if not isinstance(source_secret, dict):
586
+ raise ValueError(f"Unable to retrieve secret {self.secret_id}")
587
+
588
+ secret_name = source_secret.get("name")
589
+ secret_string = source_secret.get("secretString")
590
+ secret_description = source_secret.get("description")
591
+
592
+ if not secret_name or not secret_string:
593
+ raise ValueError(f"Secret {self.secret_id} missing required fields (name or secretString)")
594
+
595
+ new_secret = self._destination_client.create_secret(
596
+ name=secret_name,
597
+ secret_string=secret_string,
598
+ description=secret_description
599
+ )
600
+ return new_secret
601
+ except Exception as e:
602
+ logger.error(f"Secret migration failed: {e}")
603
+ raise ValueError(f"Secret migration failed: {e}") from e