pygeai 0.1.6__py3-none-any.whl → 0.6.0b15__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (788) hide show
  1. pygeai/__init__.py +11 -2
  2. pygeai/_docs/Makefile +20 -0
  3. pygeai/_docs/make.bat +35 -0
  4. pygeai/_docs/source/conf.py +117 -0
  5. pygeai/_docs/source/content/ai_lab/cli.rst +747 -0
  6. pygeai/_docs/source/content/ai_lab/models.rst +1734 -0
  7. pygeai/_docs/source/content/ai_lab/runner.rst +253 -0
  8. pygeai/_docs/source/content/ai_lab/spec.rst +431 -0
  9. pygeai/_docs/source/content/ai_lab/usage.rst +1011 -0
  10. pygeai/_docs/source/content/ai_lab.rst +102 -0
  11. pygeai/_docs/source/content/analytics.rst +598 -0
  12. pygeai/_docs/source/content/api_reference/admin.rst +161 -0
  13. pygeai/_docs/source/content/api_reference/assistant.rst +326 -0
  14. pygeai/_docs/source/content/api_reference/auth.rst +379 -0
  15. pygeai/_docs/source/content/api_reference/chat.rst +754 -0
  16. pygeai/_docs/source/content/api_reference/embeddings.rst +154 -0
  17. pygeai/_docs/source/content/api_reference/evaluation.rst +590 -0
  18. pygeai/_docs/source/content/api_reference/feedback.rst +237 -0
  19. pygeai/_docs/source/content/api_reference/files.rst +592 -0
  20. pygeai/_docs/source/content/api_reference/gam.rst +401 -0
  21. pygeai/_docs/source/content/api_reference/health.rst +58 -0
  22. pygeai/_docs/source/content/api_reference/project.rst +738 -0
  23. pygeai/_docs/source/content/api_reference/proxy.rst +318 -0
  24. pygeai/_docs/source/content/api_reference/rag.rst +710 -0
  25. pygeai/_docs/source/content/api_reference/rerank.rst +94 -0
  26. pygeai/_docs/source/content/api_reference/secrets.rst +495 -0
  27. pygeai/_docs/source/content/api_reference/usage_limits.rst +390 -0
  28. pygeai/_docs/source/content/api_reference.rst +58 -0
  29. pygeai/_docs/source/content/authentication.rst +295 -0
  30. pygeai/_docs/source/content/chat_gui.rst +121 -0
  31. pygeai/_docs/source/content/cli.rst +203 -0
  32. pygeai/_docs/source/content/debugger.rst +651 -0
  33. pygeai/_docs/source/content/intro.rst +67 -0
  34. pygeai/_docs/source/content/migration.rst +929 -0
  35. pygeai/_docs/source/content/modules.rst +7 -0
  36. pygeai/_docs/source/content/quickstart.rst +143 -0
  37. pygeai/_docs/source/content/samples.rst +394 -0
  38. pygeai/_docs/source/index.rst +75 -0
  39. pygeai/_docs/source/modules.rst +7 -0
  40. pygeai/_docs/source/pygeai.admin.rst +29 -0
  41. pygeai/_docs/source/pygeai.analytics.rst +53 -0
  42. pygeai/_docs/source/pygeai.assistant.data.rst +21 -0
  43. pygeai/_docs/source/pygeai.assistant.data_analyst.rst +29 -0
  44. pygeai/_docs/source/pygeai.assistant.rag.rst +53 -0
  45. pygeai/_docs/source/pygeai.assistant.rst +55 -0
  46. pygeai/_docs/source/pygeai.auth.rst +29 -0
  47. pygeai/_docs/source/pygeai.chat.rst +69 -0
  48. pygeai/_docs/source/pygeai.cli.commands.flows.rst +10 -0
  49. pygeai/_docs/source/pygeai.cli.commands.lab.rst +53 -0
  50. pygeai/_docs/source/pygeai.cli.commands.rst +222 -0
  51. pygeai/_docs/source/pygeai.cli.rst +62 -0
  52. pygeai/_docs/source/pygeai.cli.texts.rst +21 -0
  53. pygeai/_docs/source/pygeai.core.base.rst +53 -0
  54. pygeai/_docs/source/pygeai.core.common.rst +37 -0
  55. pygeai/_docs/source/pygeai.core.embeddings.rst +61 -0
  56. pygeai/_docs/source/pygeai.core.feedback.rst +37 -0
  57. pygeai/_docs/source/pygeai.core.files.rst +61 -0
  58. pygeai/_docs/source/pygeai.core.llm.rst +29 -0
  59. pygeai/_docs/source/pygeai.core.plugins.rst +37 -0
  60. pygeai/_docs/source/pygeai.core.rerank.rst +53 -0
  61. pygeai/_docs/source/pygeai.core.rst +63 -0
  62. pygeai/_docs/source/pygeai.core.secrets.rst +29 -0
  63. pygeai/_docs/source/pygeai.core.services.llm.rst +29 -0
  64. pygeai/_docs/source/pygeai.core.services.rst +37 -0
  65. pygeai/_docs/source/pygeai.core.utils.rst +37 -0
  66. pygeai/_docs/source/pygeai.dbg.rst +21 -0
  67. pygeai/_docs/source/pygeai.evaluation.dataset.rst +29 -0
  68. pygeai/_docs/source/pygeai.evaluation.plan.rst +29 -0
  69. pygeai/_docs/source/pygeai.evaluation.result.rst +29 -0
  70. pygeai/_docs/source/pygeai.evaluation.rst +31 -0
  71. pygeai/_docs/source/pygeai.flows.rst +29 -0
  72. pygeai/_docs/source/pygeai.gam.rst +29 -0
  73. pygeai/_docs/source/pygeai.health.rst +29 -0
  74. pygeai/_docs/source/pygeai.lab.agents.rst +37 -0
  75. pygeai/_docs/source/pygeai.lab.processes.rst +37 -0
  76. pygeai/_docs/source/pygeai.lab.rst +65 -0
  77. pygeai/_docs/source/pygeai.lab.spec.rst +29 -0
  78. pygeai/_docs/source/pygeai.lab.strategies.rst +37 -0
  79. pygeai/_docs/source/pygeai.lab.tools.rst +37 -0
  80. pygeai/_docs/source/pygeai.man.man1.rst +10 -0
  81. pygeai/_docs/source/pygeai.man.rst +18 -0
  82. pygeai/_docs/source/pygeai.migration.rst +29 -0
  83. pygeai/_docs/source/pygeai.organization.limits.rst +45 -0
  84. pygeai/_docs/source/pygeai.organization.rst +61 -0
  85. pygeai/_docs/source/pygeai.proxy.rst +53 -0
  86. pygeai/_docs/source/pygeai.rst +35 -0
  87. pygeai/_docs/source/pygeai.tests.admin.rst +21 -0
  88. pygeai/_docs/source/pygeai.tests.analytics.rst +45 -0
  89. pygeai/_docs/source/pygeai.tests.assistants.rag.rst +37 -0
  90. pygeai/_docs/source/pygeai.tests.assistants.rst +45 -0
  91. pygeai/_docs/source/pygeai.tests.auth.rst +29 -0
  92. pygeai/_docs/source/pygeai.tests.chat.rst +45 -0
  93. pygeai/_docs/source/pygeai.tests.cli.commands.lab.rst +37 -0
  94. pygeai/_docs/source/pygeai.tests.cli.commands.rst +165 -0
  95. pygeai/_docs/source/pygeai.tests.cli.docker.rst +10 -0
  96. pygeai/_docs/source/pygeai.tests.cli.rst +46 -0
  97. pygeai/_docs/source/pygeai.tests.core.base.data.rst +29 -0
  98. pygeai/_docs/source/pygeai.tests.core.base.rst +45 -0
  99. pygeai/_docs/source/pygeai.tests.core.common.data.rst +10 -0
  100. pygeai/_docs/source/pygeai.tests.core.common.rst +37 -0
  101. pygeai/_docs/source/pygeai.tests.core.embeddings.rst +37 -0
  102. pygeai/_docs/source/pygeai.tests.core.feedback.rst +21 -0
  103. pygeai/_docs/source/pygeai.tests.core.files.rst +53 -0
  104. pygeai/_docs/source/pygeai.tests.core.llm.rst +21 -0
  105. pygeai/_docs/source/pygeai.tests.core.plugins.rst +21 -0
  106. pygeai/_docs/source/pygeai.tests.core.rerank.rst +37 -0
  107. pygeai/_docs/source/pygeai.tests.core.rst +39 -0
  108. pygeai/_docs/source/pygeai.tests.core.secrets.rst +21 -0
  109. pygeai/_docs/source/pygeai.tests.core.services.rst +21 -0
  110. pygeai/_docs/source/pygeai.tests.core.utils.rst +21 -0
  111. pygeai/_docs/source/pygeai.tests.dbg.rst +21 -0
  112. pygeai/_docs/source/pygeai.tests.evaluation.dataset.rst +21 -0
  113. pygeai/_docs/source/pygeai.tests.evaluation.plan.rst +21 -0
  114. pygeai/_docs/source/pygeai.tests.evaluation.result.rst +21 -0
  115. pygeai/_docs/source/pygeai.tests.evaluation.rst +20 -0
  116. pygeai/_docs/source/pygeai.tests.gam.rst +21 -0
  117. pygeai/_docs/source/pygeai.tests.health.rst +21 -0
  118. pygeai/_docs/source/pygeai.tests.integration.assistants.rag.rst +21 -0
  119. pygeai/_docs/source/pygeai.tests.integration.assistants.rst +18 -0
  120. pygeai/_docs/source/pygeai.tests.integration.chat.rst +21 -0
  121. pygeai/_docs/source/pygeai.tests.integration.lab.agents.rst +69 -0
  122. pygeai/_docs/source/pygeai.tests.integration.lab.processes.rst +77 -0
  123. pygeai/_docs/source/pygeai.tests.integration.lab.reasoning_strategies.rst +37 -0
  124. pygeai/_docs/source/pygeai.tests.integration.lab.rst +21 -0
  125. pygeai/_docs/source/pygeai.tests.integration.lab.tools.rst +77 -0
  126. pygeai/_docs/source/pygeai.tests.integration.rst +20 -0
  127. pygeai/_docs/source/pygeai.tests.lab.agents.rst +29 -0
  128. pygeai/_docs/source/pygeai.tests.lab.processes.rst +29 -0
  129. pygeai/_docs/source/pygeai.tests.lab.rst +49 -0
  130. pygeai/_docs/source/pygeai.tests.lab.spec.rst +29 -0
  131. pygeai/_docs/source/pygeai.tests.lab.strategies.rst +29 -0
  132. pygeai/_docs/source/pygeai.tests.lab.tools.rst +29 -0
  133. pygeai/_docs/source/pygeai.tests.migration.rst +29 -0
  134. pygeai/_docs/source/pygeai.tests.organization.limits.rst +29 -0
  135. pygeai/_docs/source/pygeai.tests.organization.rst +53 -0
  136. pygeai/_docs/source/pygeai.tests.proxy.rst +61 -0
  137. pygeai/_docs/source/pygeai.tests.rst +33 -0
  138. pygeai/admin/clients.py +14 -11
  139. pygeai/admin/endpoints.py +2 -2
  140. pygeai/analytics/clients.py +505 -0
  141. pygeai/analytics/endpoints.py +35 -0
  142. pygeai/analytics/managers.py +606 -0
  143. pygeai/analytics/mappers.py +207 -0
  144. pygeai/analytics/responses.py +240 -0
  145. pygeai/assistant/clients.py +48 -57
  146. pygeai/assistant/data/__init__.py +0 -0
  147. pygeai/assistant/data/clients.py +15 -0
  148. pygeai/assistant/data_analyst/__init__.py +0 -0
  149. pygeai/assistant/data_analyst/clients.py +75 -0
  150. pygeai/assistant/data_analyst/endpoints.py +2 -0
  151. pygeai/assistant/endpoints.py +0 -2
  152. pygeai/assistant/managers.py +738 -0
  153. pygeai/assistant/mappers.py +153 -0
  154. pygeai/assistant/rag/clients.py +132 -21
  155. pygeai/assistant/rag/mappers.py +228 -0
  156. pygeai/assistant/rag/models.py +396 -0
  157. pygeai/assistant/rag/responses.py +10 -0
  158. pygeai/auth/__init__.py +0 -0
  159. pygeai/auth/clients.py +129 -0
  160. pygeai/auth/endpoints.py +6 -0
  161. pygeai/chat/clients.py +406 -31
  162. pygeai/chat/endpoints.py +3 -0
  163. pygeai/chat/iris.py +17 -0
  164. pygeai/chat/managers.py +64 -0
  165. pygeai/chat/session.py +38 -0
  166. pygeai/chat/settings.py +6 -0
  167. pygeai/chat/ui.py +678 -0
  168. pygeai/cli/__init__.py +0 -1
  169. pygeai/cli/commands/admin.py +9 -12
  170. pygeai/cli/commands/analytics.py +533 -0
  171. pygeai/cli/commands/assistant.py +11 -11
  172. pygeai/cli/commands/auth.py +299 -0
  173. pygeai/cli/commands/base.py +201 -7
  174. pygeai/cli/commands/chat.py +875 -14
  175. pygeai/cli/commands/common.py +30 -26
  176. pygeai/cli/commands/configuration.py +84 -9
  177. pygeai/cli/commands/docs.py +105 -0
  178. pygeai/cli/commands/embeddings.py +187 -0
  179. pygeai/cli/commands/evaluation.py +2069 -0
  180. pygeai/cli/commands/feedback.py +93 -0
  181. pygeai/cli/commands/files.py +312 -0
  182. pygeai/cli/commands/flows/__init__.py +0 -0
  183. pygeai/cli/commands/gam.py +349 -0
  184. pygeai/cli/commands/lab/__init__.py +0 -0
  185. pygeai/cli/commands/lab/ai_lab.py +4110 -0
  186. pygeai/cli/commands/lab/common.py +135 -0
  187. pygeai/cli/commands/lab/options.py +8 -0
  188. pygeai/cli/commands/lab/spec.py +273 -0
  189. pygeai/cli/commands/lab/utils.py +13 -0
  190. pygeai/cli/commands/llm.py +164 -0
  191. pygeai/cli/commands/migrate.py +1198 -0
  192. pygeai/cli/commands/options.py +86 -0
  193. pygeai/cli/commands/organization.py +560 -98
  194. pygeai/cli/commands/rag.py +306 -10
  195. pygeai/cli/commands/rerank.py +108 -0
  196. pygeai/cli/commands/secrets.py +357 -0
  197. pygeai/cli/commands/usage_limits.py +583 -0
  198. pygeai/cli/commands/validators.py +209 -0
  199. pygeai/cli/commands/version.py +44 -0
  200. pygeai/cli/error_handler.py +151 -0
  201. pygeai/cli/geai.py +171 -30
  202. pygeai/cli/geai_proxy.py +318 -0
  203. pygeai/cli/install_man.py +107 -0
  204. pygeai/cli/parsers.py +78 -25
  205. pygeai/cli/texts/help.py +712 -55
  206. pygeai/core/__init__.py +9 -1
  207. pygeai/core/base/clients.py +61 -10
  208. pygeai/core/base/mappers.py +208 -30
  209. pygeai/core/base/models.py +8 -308
  210. pygeai/core/base/responses.py +18 -1
  211. pygeai/core/base/session.py +110 -17
  212. pygeai/core/common/config.py +98 -16
  213. pygeai/core/common/decorators.py +44 -0
  214. pygeai/core/common/exceptions.py +104 -4
  215. pygeai/core/embeddings/__init__.py +19 -0
  216. pygeai/core/embeddings/clients.py +93 -0
  217. pygeai/core/embeddings/endpoints.py +1 -0
  218. pygeai/core/embeddings/managers.py +62 -0
  219. pygeai/core/embeddings/mappers.py +52 -0
  220. pygeai/core/embeddings/models.py +14 -0
  221. pygeai/core/embeddings/responses.py +31 -0
  222. pygeai/core/feedback/__init__.py +0 -0
  223. pygeai/core/feedback/clients.py +50 -0
  224. pygeai/core/feedback/endpoints.py +1 -0
  225. pygeai/core/feedback/models.py +10 -0
  226. pygeai/core/files/__init__.py +0 -0
  227. pygeai/core/files/clients.py +156 -0
  228. pygeai/core/files/endpoints.py +5 -0
  229. pygeai/core/files/managers.py +224 -0
  230. pygeai/core/files/mappers.py +44 -0
  231. pygeai/core/files/models.py +24 -0
  232. pygeai/core/files/responses.py +19 -0
  233. pygeai/core/handlers.py +32 -0
  234. pygeai/core/llm/__init__.py +0 -0
  235. pygeai/core/llm/clients.py +53 -0
  236. pygeai/core/llm/endpoints.py +4 -0
  237. pygeai/core/models.py +799 -0
  238. pygeai/core/plugins/__init__.py +0 -0
  239. pygeai/core/plugins/clients.py +32 -0
  240. pygeai/core/plugins/endpoints.py +1 -0
  241. pygeai/core/plugins/models.py +86 -0
  242. pygeai/core/rerank/__init__.py +0 -0
  243. pygeai/core/rerank/clients.py +35 -0
  244. pygeai/core/rerank/endpoints.py +1 -0
  245. pygeai/core/rerank/managers.py +47 -0
  246. pygeai/core/rerank/mappers.py +23 -0
  247. pygeai/core/rerank/models.py +27 -0
  248. pygeai/core/responses.py +104 -0
  249. pygeai/core/secrets/__init__.py +0 -0
  250. pygeai/core/secrets/clients.py +212 -0
  251. pygeai/core/secrets/endpoints.py +7 -0
  252. pygeai/core/services/llm/__init__.py +0 -0
  253. pygeai/core/services/llm/model.py +186 -0
  254. pygeai/core/services/llm/providers.py +15 -0
  255. pygeai/core/services/response.py +18 -0
  256. pygeai/core/services/rest.py +311 -89
  257. pygeai/core/utils/__init__.py +0 -0
  258. pygeai/core/utils/console.py +83 -0
  259. pygeai/core/utils/parsers.py +32 -0
  260. pygeai/core/utils/validators.py +10 -0
  261. pygeai/dbg/__init__.py +3 -0
  262. pygeai/dbg/debugger.py +870 -0
  263. pygeai/evaluation/__init__.py +0 -0
  264. pygeai/evaluation/clients.py +19 -0
  265. pygeai/evaluation/dataset/__init__.py +0 -0
  266. pygeai/evaluation/dataset/clients.py +514 -0
  267. pygeai/evaluation/dataset/endpoints.py +26 -0
  268. pygeai/evaluation/plan/__init__.py +0 -0
  269. pygeai/evaluation/plan/clients.py +302 -0
  270. pygeai/evaluation/plan/endpoints.py +16 -0
  271. pygeai/evaluation/result/__init__.py +0 -0
  272. pygeai/evaluation/result/clients.py +70 -0
  273. pygeai/evaluation/result/endpoints.py +2 -0
  274. pygeai/flows/__init__.py +0 -0
  275. pygeai/flows/endpoints.py +362 -0
  276. pygeai/flows/models.py +1304 -0
  277. pygeai/gam/__init__.py +0 -0
  278. pygeai/gam/clients.py +178 -0
  279. pygeai/gam/endpoints.py +4 -0
  280. pygeai/health/__init__.py +0 -0
  281. pygeai/health/clients.py +24 -0
  282. pygeai/health/endpoints.py +1 -0
  283. pygeai/lab/__init__.py +0 -0
  284. pygeai/lab/agents/__init__.py +0 -0
  285. pygeai/lab/agents/clients.py +426 -0
  286. pygeai/lab/agents/endpoints.py +12 -0
  287. pygeai/lab/agents/mappers.py +319 -0
  288. pygeai/lab/clients.py +24 -0
  289. pygeai/lab/constants.py +3 -0
  290. pygeai/lab/managers.py +1558 -0
  291. pygeai/lab/models.py +1719 -0
  292. pygeai/lab/processes/__init__.py +0 -0
  293. pygeai/lab/processes/clients.py +1051 -0
  294. pygeai/lab/processes/endpoints.py +26 -0
  295. pygeai/lab/processes/mappers.py +395 -0
  296. pygeai/lab/runners.py +90 -0
  297. pygeai/lab/spec/__init__.py +0 -0
  298. pygeai/lab/spec/loader.py +24 -0
  299. pygeai/lab/spec/parsers.py +39 -0
  300. pygeai/lab/strategies/__init__.py +0 -0
  301. pygeai/lab/strategies/clients.py +212 -0
  302. pygeai/lab/strategies/endpoints.py +5 -0
  303. pygeai/lab/strategies/mappers.py +58 -0
  304. pygeai/lab/tools/__init__.py +0 -0
  305. pygeai/lab/tools/clients.py +465 -0
  306. pygeai/lab/tools/endpoints.py +13 -0
  307. pygeai/lab/tools/mappers.py +131 -0
  308. pygeai/man/__init__.py +1 -0
  309. pygeai/man/man1/__init__.py +1 -0
  310. pygeai/man/man1/geai-proxy.1 +246 -0
  311. pygeai/man/man1/geai.1 +2615 -0
  312. pygeai/migration/__init__.py +33 -0
  313. pygeai/migration/strategies.py +603 -0
  314. pygeai/migration/tools.py +180 -0
  315. pygeai/organization/clients.py +246 -18
  316. pygeai/organization/endpoints.py +17 -8
  317. pygeai/organization/limits/__init__.py +0 -0
  318. pygeai/organization/limits/clients.py +281 -0
  319. pygeai/organization/limits/endpoints.py +15 -0
  320. pygeai/organization/limits/managers.py +331 -0
  321. pygeai/organization/limits/mappers.py +21 -0
  322. pygeai/organization/managers.py +537 -0
  323. pygeai/organization/mappers.py +111 -46
  324. pygeai/organization/responses.py +61 -11
  325. pygeai/proxy/__init__.py +0 -0
  326. pygeai/proxy/clients.py +216 -0
  327. pygeai/proxy/config.py +128 -0
  328. pygeai/proxy/managers.py +232 -0
  329. pygeai/proxy/servers.py +304 -0
  330. pygeai/proxy/tool.py +69 -0
  331. pygeai/tests/admin/__init__.py +0 -0
  332. pygeai/tests/admin/test_clients.py +148 -0
  333. pygeai/tests/analytics/__init__.py +0 -0
  334. pygeai/tests/analytics/test_clients.py +86 -0
  335. pygeai/tests/analytics/test_managers.py +94 -0
  336. pygeai/tests/analytics/test_mappers.py +84 -0
  337. pygeai/tests/analytics/test_responses.py +73 -0
  338. pygeai/tests/assistants/rag/__init__.py +0 -0
  339. pygeai/tests/assistants/rag/test_clients.py +346 -0
  340. pygeai/tests/assistants/rag/test_mappers.py +189 -0
  341. pygeai/tests/assistants/rag/test_models.py +292 -0
  342. pygeai/tests/assistants/test_clients.py +176 -80
  343. pygeai/tests/assistants/test_managers.py +198 -0
  344. pygeai/tests/assistants/test_mappers.py +111 -0
  345. pygeai/tests/auth/__init__.py +0 -0
  346. pygeai/tests/auth/test_clients.py +289 -0
  347. pygeai/tests/auth/test_oauth.py +172 -0
  348. pygeai/tests/auth/test_session_logging.py +150 -0
  349. pygeai/tests/chat/__init__.py +0 -0
  350. pygeai/tests/chat/test_clients.py +393 -0
  351. pygeai/tests/chat/test_iris.py +38 -0
  352. pygeai/tests/chat/test_session.py +62 -0
  353. pygeai/tests/chat/test_ui.py +224 -0
  354. pygeai/tests/cli/__init__.py +0 -0
  355. pygeai/tests/cli/commands/__init__.py +0 -0
  356. pygeai/tests/cli/commands/lab/__init__.py +0 -0
  357. pygeai/tests/cli/commands/lab/test_ai_lab.py +786 -0
  358. pygeai/tests/cli/commands/lab/test_common.py +208 -0
  359. pygeai/tests/cli/commands/lab/test_spec.py +246 -0
  360. pygeai/tests/cli/commands/test_assistant.py +202 -0
  361. pygeai/tests/cli/commands/test_chat.py +130 -0
  362. pygeai/tests/cli/commands/test_common.py +350 -0
  363. pygeai/tests/cli/commands/test_embeddings.py +132 -0
  364. pygeai/tests/cli/commands/test_evaluation.py +656 -0
  365. pygeai/tests/cli/commands/test_feedback.py +65 -0
  366. pygeai/tests/cli/commands/test_files.py +161 -0
  367. pygeai/tests/cli/commands/test_gam.py +201 -0
  368. pygeai/tests/cli/commands/test_llm.py +114 -0
  369. pygeai/tests/cli/commands/test_migrate.py +176 -0
  370. pygeai/tests/cli/commands/test_organization.py +276 -0
  371. pygeai/tests/cli/commands/test_rag.py +266 -0
  372. pygeai/tests/cli/commands/test_rerank.py +110 -0
  373. pygeai/tests/cli/commands/test_secrets.py +171 -0
  374. pygeai/tests/cli/commands/test_show_help.py +41 -0
  375. pygeai/tests/cli/commands/test_usage_limits.py +412 -0
  376. pygeai/tests/cli/commands/test_validators.py +160 -0
  377. pygeai/tests/cli/commands/test_version.py +81 -0
  378. pygeai/tests/cli/docker/__init__.py +0 -0
  379. pygeai/tests/cli/test_credentials_flag.py +316 -0
  380. pygeai/tests/cli/test_error_handler.py +225 -0
  381. pygeai/tests/cli/test_geai_driver.py +154 -0
  382. pygeai/tests/cli/test_parsers.py +154 -0
  383. pygeai/tests/core/base/__init__.py +0 -0
  384. pygeai/tests/core/base/data/__init__.py +0 -0
  385. pygeai/tests/core/base/data/mappers.py +117 -0
  386. pygeai/tests/core/base/data/models.py +312 -0
  387. pygeai/tests/core/base/test_mappers.py +569 -0
  388. pygeai/tests/core/base/test_models.py +261 -0
  389. pygeai/tests/core/base/test_responses.py +53 -0
  390. pygeai/tests/core/common/__init__.py +0 -0
  391. pygeai/tests/core/common/data/__init__.py +0 -0
  392. pygeai/tests/core/common/test_config.py +186 -0
  393. pygeai/tests/core/common/test_decorators.py +69 -0
  394. pygeai/tests/core/embeddings/__init__.py +0 -0
  395. pygeai/tests/core/embeddings/test_clients.py +225 -0
  396. pygeai/tests/core/embeddings/test_managers.py +171 -0
  397. pygeai/tests/core/embeddings/test_mappers.py +142 -0
  398. pygeai/tests/core/feedback/__init__.py +0 -0
  399. pygeai/tests/core/feedback/test_clients.py +64 -0
  400. pygeai/tests/core/files/__init__.py +0 -0
  401. pygeai/tests/core/files/test_clients.py +128 -0
  402. pygeai/tests/core/files/test_managers.py +219 -0
  403. pygeai/tests/core/files/test_mappers.py +137 -0
  404. pygeai/tests/core/files/test_models.py +103 -0
  405. pygeai/tests/core/files/test_responses.py +122 -0
  406. pygeai/tests/core/llm/__init__.py +0 -0
  407. pygeai/tests/core/llm/test_clients.py +142 -0
  408. pygeai/tests/core/plugins/__init__.py +0 -0
  409. pygeai/tests/core/plugins/test_clients.py +66 -0
  410. pygeai/tests/core/rerank/__init__.py +0 -0
  411. pygeai/tests/core/rerank/test_clients.py +76 -0
  412. pygeai/tests/core/rerank/test_managers.py +99 -0
  413. pygeai/tests/core/rerank/test_mappers.py +54 -0
  414. pygeai/tests/core/secrets/__init__.py +0 -0
  415. pygeai/tests/core/secrets/test_clients.py +264 -0
  416. pygeai/tests/core/services/__init__.py +0 -0
  417. pygeai/tests/core/services/test_rest.py +273 -0
  418. pygeai/tests/core/test_handlers.py +66 -0
  419. pygeai/tests/core/utils/__init__.py +0 -0
  420. pygeai/tests/core/utils/test_console.py +80 -0
  421. pygeai/tests/dbg/__init__.py +0 -0
  422. pygeai/tests/dbg/test_debugger.py +591 -0
  423. pygeai/tests/evaluation/__init__.py +0 -0
  424. pygeai/tests/evaluation/dataset/__init__.py +0 -0
  425. pygeai/tests/evaluation/dataset/test_clients.py +265 -0
  426. pygeai/tests/evaluation/plan/__init__.py +0 -0
  427. pygeai/tests/evaluation/plan/test_clients.py +195 -0
  428. pygeai/tests/evaluation/result/__init__.py +0 -0
  429. pygeai/tests/evaluation/result/test_clients.py +66 -0
  430. pygeai/tests/gam/__init__.py +0 -0
  431. pygeai/tests/gam/test_clients.py +195 -0
  432. pygeai/tests/health/__init__.py +0 -0
  433. pygeai/tests/health/test_clients.py +41 -0
  434. pygeai/tests/integration/__init__.py +0 -0
  435. pygeai/tests/integration/assistants/__init__.py +0 -0
  436. pygeai/tests/integration/assistants/rag/__init__.py +0 -0
  437. pygeai/tests/integration/assistants/rag/test_create_rag.py +91 -0
  438. pygeai/tests/integration/chat/__init__.py +0 -0
  439. pygeai/tests/integration/chat/test_generate_image.py +158 -0
  440. pygeai/tests/integration/lab/__init__.py +0 -0
  441. pygeai/tests/integration/lab/agents/__init__.py +0 -0
  442. pygeai/tests/integration/lab/agents/test_agents_list.py +106 -0
  443. pygeai/tests/integration/lab/agents/test_create_agent.py +319 -0
  444. pygeai/tests/integration/lab/agents/test_create_sharing_link.py +70 -0
  445. pygeai/tests/integration/lab/agents/test_delete_agent.py +75 -0
  446. pygeai/tests/integration/lab/agents/test_get_agent.py +94 -0
  447. pygeai/tests/integration/lab/agents/test_publish_agent_revision.py +127 -0
  448. pygeai/tests/integration/lab/agents/test_update_agent.py +250 -0
  449. pygeai/tests/integration/lab/processes/__init__.py +0 -0
  450. pygeai/tests/integration/lab/processes/test_create_process.py +345 -0
  451. pygeai/tests/integration/lab/processes/test_create_task.py +211 -0
  452. pygeai/tests/integration/lab/processes/test_delete_process.py +111 -0
  453. pygeai/tests/integration/lab/processes/test_get_process.py +201 -0
  454. pygeai/tests/integration/lab/processes/test_list_process_instances.py +91 -0
  455. pygeai/tests/integration/lab/processes/test_list_processes.py +138 -0
  456. pygeai/tests/integration/lab/processes/test_publish_process_revision.py +232 -0
  457. pygeai/tests/integration/lab/processes/test_update_process.py +289 -0
  458. pygeai/tests/integration/lab/reasoning_strategies/__init__.py +0 -0
  459. pygeai/tests/integration/lab/reasoning_strategies/test_get_reasoning_strategy.py +70 -0
  460. pygeai/tests/integration/lab/reasoning_strategies/test_list_reasoning_strategies.py +93 -0
  461. pygeai/tests/integration/lab/reasoning_strategies/test_update_reasoning_strategy.py +149 -0
  462. pygeai/tests/integration/lab/tools/__init__.py +0 -0
  463. pygeai/tests/integration/lab/tools/test_create_tool.py +288 -0
  464. pygeai/tests/integration/lab/tools/test_delete_tool.py +87 -0
  465. pygeai/tests/integration/lab/tools/test_get_parameter.py +98 -0
  466. pygeai/tests/integration/lab/tools/test_get_tool.py +91 -0
  467. pygeai/tests/integration/lab/tools/test_list_tools.py +106 -0
  468. pygeai/tests/integration/lab/tools/test_publish_tool_revision.py +119 -0
  469. pygeai/tests/integration/lab/tools/test_set_parameter.py +114 -0
  470. pygeai/tests/integration/lab/tools/test_update_tool.py +267 -0
  471. pygeai/tests/lab/__init__.py +0 -0
  472. pygeai/tests/lab/agents/__init__.py +0 -0
  473. pygeai/tests/lab/agents/test_clients.py +481 -0
  474. pygeai/tests/lab/agents/test_mappers.py +440 -0
  475. pygeai/tests/lab/processes/__init__.py +0 -0
  476. pygeai/tests/lab/processes/test_clients.py +1416 -0
  477. pygeai/tests/lab/processes/test_mappers.py +1092 -0
  478. pygeai/tests/lab/spec/__init__.py +0 -0
  479. pygeai/tests/lab/spec/test_loader.py +59 -0
  480. pygeai/tests/lab/spec/test_parsers.py +182 -0
  481. pygeai/tests/lab/strategies/__init__.py +0 -0
  482. pygeai/tests/lab/strategies/test_clients.py +241 -0
  483. pygeai/tests/lab/strategies/test_mappers.py +132 -0
  484. pygeai/tests/lab/test_managers.py +553 -0
  485. pygeai/tests/lab/test_mappers.py +245 -0
  486. pygeai/tests/lab/test_models.py +1154 -0
  487. pygeai/tests/lab/tools/__init__.py +0 -0
  488. pygeai/tests/lab/tools/test_clients.py +521 -0
  489. pygeai/tests/lab/tools/test_mappers.py +198 -0
  490. pygeai/tests/migration/__init__.py +0 -0
  491. pygeai/tests/migration/test_strategies.py +405 -0
  492. pygeai/tests/migration/test_tools.py +159 -0
  493. pygeai/tests/organization/limits/__init__.py +0 -0
  494. pygeai/tests/organization/limits/test_clients.py +567 -0
  495. pygeai/tests/organization/limits/test_managers.py +402 -0
  496. pygeai/tests/organization/test_clients.py +615 -64
  497. pygeai/tests/organization/test_managers.py +424 -0
  498. pygeai/tests/organization/test_mappers.py +153 -0
  499. pygeai/tests/organization/test_responses.py +137 -0
  500. pygeai/tests/proxy/__init__.py +1 -0
  501. pygeai/tests/proxy/test_clients.py +397 -0
  502. pygeai/tests/proxy/test_config.py +171 -0
  503. pygeai/tests/proxy/test_integration.py +305 -0
  504. pygeai/tests/proxy/test_managers.py +312 -0
  505. pygeai/tests/proxy/test_servers.py +387 -0
  506. pygeai/tests/proxy/test_tool.py +176 -0
  507. pygeai/tests/snippets/__init__.py +0 -0
  508. pygeai/tests/snippets/analytics/__init__.py +0 -0
  509. pygeai/tests/snippets/analytics/get_agent_usage_per_user.py +16 -0
  510. pygeai/tests/snippets/analytics/get_agents_created_and_modified.py +11 -0
  511. pygeai/tests/snippets/analytics/get_average_cost_per_request.py +10 -0
  512. pygeai/tests/snippets/analytics/get_overall_error_rate.py +10 -0
  513. pygeai/tests/snippets/analytics/get_top_10_agents_by_requests.py +12 -0
  514. pygeai/tests/snippets/analytics/get_total_active_users.py +10 -0
  515. pygeai/tests/snippets/analytics/get_total_cost.py +10 -0
  516. pygeai/tests/snippets/analytics/get_total_requests_per_day.py +12 -0
  517. pygeai/tests/snippets/analytics/get_total_tokens.py +12 -0
  518. pygeai/tests/snippets/assistants/__init__.py +0 -0
  519. pygeai/tests/snippets/assistants/create_chat_assistant.py +54 -0
  520. pygeai/tests/snippets/assistants/create_text_assistant.py +51 -0
  521. pygeai/tests/snippets/assistants/data_analyst/__init__.py +0 -0
  522. pygeai/tests/snippets/assistants/data_analyst/extend_and_check.py +100 -0
  523. pygeai/tests/snippets/assistants/data_analyst/extend_dataset.py +9 -0
  524. pygeai/tests/snippets/assistants/data_analyst/get_status.py +9 -0
  525. pygeai/tests/snippets/assistants/file_summarizer_assistant.py +149 -0
  526. pygeai/tests/snippets/assistants/get_assistant_data.py +8 -0
  527. pygeai/tests/snippets/assistants/get_assistant_list.py +7 -0
  528. pygeai/tests/snippets/assistants/rag/__init__.py +0 -0
  529. pygeai/tests/snippets/assistants/rag/create_rag_assistant.py +65 -0
  530. pygeai/tests/snippets/assistants/rag/delete_al_documents.py +7 -0
  531. pygeai/tests/snippets/assistants/rag/delete_document.py +10 -0
  532. pygeai/tests/snippets/assistants/rag/delete_rag_assistant.py +8 -0
  533. pygeai/tests/snippets/assistants/rag/get_document.py +10 -0
  534. pygeai/tests/snippets/assistants/rag/get_documents.py +7 -0
  535. pygeai/tests/snippets/assistants/rag/get_rag_assistant_data.py +8 -0
  536. pygeai/tests/snippets/assistants/rag/update_rag_assistant.py +48 -0
  537. pygeai/tests/snippets/assistants/rag/upload_document.py +19 -0
  538. pygeai/tests/snippets/assistants/send_feedback.py +14 -0
  539. pygeai/tests/snippets/assistants/update_chat_assistant.py +63 -0
  540. pygeai/tests/snippets/auth/__init__.py +0 -0
  541. pygeai/tests/snippets/chat/__init__.py +0 -0
  542. pygeai/tests/snippets/chat/cancel_request.py +7 -0
  543. pygeai/tests/snippets/chat/chat_completion.py +28 -0
  544. pygeai/tests/snippets/chat/chat_completion_1.py +40 -0
  545. pygeai/tests/snippets/chat/chat_completion_2.py +60 -0
  546. pygeai/tests/snippets/chat/chat_completion_3.py +27 -0
  547. pygeai/tests/snippets/chat/chat_completion_4.py +67 -0
  548. pygeai/tests/snippets/chat/chat_completion_streaming.py +63 -0
  549. pygeai/tests/snippets/chat/chat_completion_with_reasoning_effort.py +18 -0
  550. pygeai/tests/snippets/chat/get_request_status.py +7 -0
  551. pygeai/tests/snippets/chat/get_response.py +15 -0
  552. pygeai/tests/snippets/chat/get_response_complete_example.py +67 -0
  553. pygeai/tests/snippets/chat/get_response_streaming.py +20 -0
  554. pygeai/tests/snippets/chat/get_response_with_files.py +16 -0
  555. pygeai/tests/snippets/chat/get_response_with_instructions.py +19 -0
  556. pygeai/tests/snippets/chat/get_response_with_metadata.py +24 -0
  557. pygeai/tests/snippets/chat/get_response_with_parallel_tools.py +58 -0
  558. pygeai/tests/snippets/chat/get_response_with_reasoning.py +21 -0
  559. pygeai/tests/snippets/chat/get_response_with_store.py +38 -0
  560. pygeai/tests/snippets/chat/get_response_with_tools.py +36 -0
  561. pygeai/tests/snippets/chat/get_response_with_truncation.py +24 -0
  562. pygeai/tests/snippets/chat/send_chat_request.py +33 -0
  563. pygeai/tests/snippets/dbg/__init__.py +0 -0
  564. pygeai/tests/snippets/dbg/basic_debugging.py +32 -0
  565. pygeai/tests/snippets/dbg/breakpoint_management.py +48 -0
  566. pygeai/tests/snippets/dbg/file_debugging.py +72 -0
  567. pygeai/tests/snippets/dbg/module_debugging.py +61 -0
  568. pygeai/tests/snippets/dbg/stack_navigation.py +45 -0
  569. pygeai/tests/snippets/dbg/stepping_example.py +40 -0
  570. pygeai/tests/snippets/embeddings/__init__.py +0 -0
  571. pygeai/tests/snippets/embeddings/cache_example.py +31 -0
  572. pygeai/tests/snippets/embeddings/cohere_example.py +41 -0
  573. pygeai/tests/snippets/embeddings/generate_embeddings.py +26 -0
  574. pygeai/tests/snippets/embeddings/openai_base64_example.py +27 -0
  575. pygeai/tests/snippets/embeddings/openai_example.py +30 -0
  576. pygeai/tests/snippets/embeddings/similarity_example.py +42 -0
  577. pygeai/tests/snippets/evaluation/__init__.py +0 -0
  578. pygeai/tests/snippets/evaluation/dataset/__init__.py +0 -0
  579. pygeai/tests/snippets/evaluation/dataset/complete_workflow_example.py +195 -0
  580. pygeai/tests/snippets/evaluation/dataset/create_dataset.py +26 -0
  581. pygeai/tests/snippets/evaluation/dataset/create_dataset_from_file.py +11 -0
  582. pygeai/tests/snippets/evaluation/dataset/create_dataset_row.py +17 -0
  583. pygeai/tests/snippets/evaluation/dataset/create_expected_source.py +18 -0
  584. pygeai/tests/snippets/evaluation/dataset/create_filter_variable.py +19 -0
  585. pygeai/tests/snippets/evaluation/dataset/delete_dataset.py +9 -0
  586. pygeai/tests/snippets/evaluation/dataset/delete_dataset_row.py +10 -0
  587. pygeai/tests/snippets/evaluation/dataset/delete_expected_source.py +15 -0
  588. pygeai/tests/snippets/evaluation/dataset/delete_filter_variable.py +15 -0
  589. pygeai/tests/snippets/evaluation/dataset/get_dataset.py +9 -0
  590. pygeai/tests/snippets/evaluation/dataset/get_dataset_row.py +10 -0
  591. pygeai/tests/snippets/evaluation/dataset/get_expected_source.py +15 -0
  592. pygeai/tests/snippets/evaluation/dataset/get_filter_variable.py +15 -0
  593. pygeai/tests/snippets/evaluation/dataset/list_dataset_rows.py +9 -0
  594. pygeai/tests/snippets/evaluation/dataset/list_datasets.py +6 -0
  595. pygeai/tests/snippets/evaluation/dataset/list_expected_sources.py +10 -0
  596. pygeai/tests/snippets/evaluation/dataset/list_filter_variables.py +10 -0
  597. pygeai/tests/snippets/evaluation/dataset/update_dataset.py +15 -0
  598. pygeai/tests/snippets/evaluation/dataset/update_dataset_row.py +20 -0
  599. pygeai/tests/snippets/evaluation/dataset/update_expected_source.py +18 -0
  600. pygeai/tests/snippets/evaluation/dataset/update_filter_variable.py +19 -0
  601. pygeai/tests/snippets/evaluation/dataset/upload_dataset_rows_file.py +10 -0
  602. pygeai/tests/snippets/evaluation/plan/__init__.py +0 -0
  603. pygeai/tests/snippets/evaluation/plan/add_plan_system_metric.py +13 -0
  604. pygeai/tests/snippets/evaluation/plan/complete_workflow_example.py +136 -0
  605. pygeai/tests/snippets/evaluation/plan/create_evaluation_plan.py +24 -0
  606. pygeai/tests/snippets/evaluation/plan/create_rag_evaluation_plan.py +22 -0
  607. pygeai/tests/snippets/evaluation/plan/delete_evaluation_plan.py +9 -0
  608. pygeai/tests/snippets/evaluation/plan/delete_plan_system_metric.py +13 -0
  609. pygeai/tests/snippets/evaluation/plan/execute_evaluation_plan.py +11 -0
  610. pygeai/tests/snippets/evaluation/plan/get_evaluation_plan.py +9 -0
  611. pygeai/tests/snippets/evaluation/plan/get_plan_system_metric.py +13 -0
  612. pygeai/tests/snippets/evaluation/plan/get_system_metric.py +9 -0
  613. pygeai/tests/snippets/evaluation/plan/list_evaluation_plans.py +7 -0
  614. pygeai/tests/snippets/evaluation/plan/list_plan_system_metrics.py +9 -0
  615. pygeai/tests/snippets/evaluation/plan/list_system_metrics.py +7 -0
  616. pygeai/tests/snippets/evaluation/plan/update_evaluation_plan.py +22 -0
  617. pygeai/tests/snippets/evaluation/plan/update_plan_system_metric.py +14 -0
  618. pygeai/tests/snippets/evaluation/result/__init__.py +0 -0
  619. pygeai/tests/snippets/evaluation/result/complete_workflow_example.py +150 -0
  620. pygeai/tests/snippets/evaluation/result/get_evaluation_result.py +26 -0
  621. pygeai/tests/snippets/evaluation/result/list_evaluation_results.py +17 -0
  622. pygeai/tests/snippets/files/__init__.py +0 -0
  623. pygeai/tests/snippets/files/delete_file.py +9 -0
  624. pygeai/tests/snippets/files/get_file_content.py +10 -0
  625. pygeai/tests/snippets/files/get_file_data.py +9 -0
  626. pygeai/tests/snippets/files/get_file_list.py +6 -0
  627. pygeai/tests/snippets/files/upload_file.py +13 -0
  628. pygeai/tests/snippets/gam/__init__.py +0 -0
  629. pygeai/tests/snippets/gam/gam_access_token.py +87 -0
  630. pygeai/tests/snippets/lab/__init__.py +0 -0
  631. pygeai/tests/snippets/lab/agentic_flow_example_1.py +326 -0
  632. pygeai/tests/snippets/lab/agentic_flow_example_2.py +206 -0
  633. pygeai/tests/snippets/lab/agentic_flow_example_3.py +486 -0
  634. pygeai/tests/snippets/lab/agentic_flow_example_4.py +446 -0
  635. pygeai/tests/snippets/lab/agents/__init__.py +0 -0
  636. pygeai/tests/snippets/lab/agents/create_agent.py +48 -0
  637. pygeai/tests/snippets/lab/agents/create_agent_2.py +48 -0
  638. pygeai/tests/snippets/lab/agents/create_agent_edge_case.py +48 -0
  639. pygeai/tests/snippets/lab/agents/create_agent_with_permissions.py +39 -0
  640. pygeai/tests/snippets/lab/agents/create_agent_with_properties.py +46 -0
  641. pygeai/tests/snippets/lab/agents/create_agent_without_instructions.py +48 -0
  642. pygeai/tests/snippets/lab/agents/delete_agent.py +12 -0
  643. pygeai/tests/snippets/lab/agents/get_agent.py +24 -0
  644. pygeai/tests/snippets/lab/agents/get_agent_with_new_fields.py +62 -0
  645. pygeai/tests/snippets/lab/agents/get_sharing_link.py +13 -0
  646. pygeai/tests/snippets/lab/agents/list_agents.py +18 -0
  647. pygeai/tests/snippets/lab/agents/publish_agent_revision.py +12 -0
  648. pygeai/tests/snippets/lab/agents/update_agent.py +50 -0
  649. pygeai/tests/snippets/lab/agents/update_agent_properties.py +50 -0
  650. pygeai/tests/snippets/lab/assistant_to_agent.py +191 -0
  651. pygeai/tests/snippets/lab/crud_ui.py +462 -0
  652. pygeai/tests/snippets/lab/processes/__init__.py +0 -0
  653. pygeai/tests/snippets/lab/processes/create_process.py +24 -0
  654. pygeai/tests/snippets/lab/processes/create_task.py +8 -0
  655. pygeai/tests/snippets/lab/processes/jobs/__init__.py +0 -0
  656. pygeai/tests/snippets/lab/processes/jobs/list_jobs.py +21 -0
  657. pygeai/tests/snippets/lab/processes/kbs/__init__.py +0 -0
  658. pygeai/tests/snippets/lab/processes/kbs/create_kb.py +18 -0
  659. pygeai/tests/snippets/lab/processes/kbs/get_kb.py +26 -0
  660. pygeai/tests/snippets/lab/processes/kbs/list_kbs.py +30 -0
  661. pygeai/tests/snippets/lab/processes/kbs/try_all.py +73 -0
  662. pygeai/tests/snippets/lab/processes/list_processes.py +10 -0
  663. pygeai/tests/snippets/lab/runner_1.py +212 -0
  664. pygeai/tests/snippets/lab/samples/__init__.py +0 -0
  665. pygeai/tests/snippets/lab/samples/summarize_files.py +162 -0
  666. pygeai/tests/snippets/lab/strategies/__init__.py +0 -0
  667. pygeai/tests/snippets/lab/strategies/create_reasoning_strategy.py +22 -0
  668. pygeai/tests/snippets/lab/strategies/get_reasoning_strategy.py +10 -0
  669. pygeai/tests/snippets/lab/strategies/list_reasoning_strategies.py +16 -0
  670. pygeai/tests/snippets/lab/strategies/update_reasoning_strategy.py +26 -0
  671. pygeai/tests/snippets/lab/tools/__init__.py +0 -0
  672. pygeai/tests/snippets/lab/tools/create_tool.py +48 -0
  673. pygeai/tests/snippets/lab/tools/create_tool_edge_case.py +50 -0
  674. pygeai/tests/snippets/lab/tools/delete_tool.py +21 -0
  675. pygeai/tests/snippets/lab/tools/get_parameter.py +21 -0
  676. pygeai/tests/snippets/lab/tools/get_tool.py +22 -0
  677. pygeai/tests/snippets/lab/tools/list_tools.py +23 -0
  678. pygeai/tests/snippets/lab/tools/publish_tool_revision.py +13 -0
  679. pygeai/tests/snippets/lab/tools/set_parameters.py +33 -0
  680. pygeai/tests/snippets/lab/tools/update_tool.py +52 -0
  681. pygeai/tests/snippets/lab/use_cases/__init__.py +0 -0
  682. pygeai/tests/snippets/lab/use_cases/c_code_fixer_agent_flow.py +238 -0
  683. pygeai/tests/snippets/lab/use_cases/create_cli_expert.py +1640 -0
  684. pygeai/tests/snippets/lab/use_cases/create_lab_expert.py +4541 -0
  685. pygeai/tests/snippets/lab/use_cases/create_tool_headless_web_browser.py +133 -0
  686. pygeai/tests/snippets/lab/use_cases/create_web_designer.py +189 -0
  687. pygeai/tests/snippets/lab/use_cases/create_web_reader.py +185 -0
  688. pygeai/tests/snippets/lab/use_cases/file_summarizer_example.py +157 -0
  689. pygeai/tests/snippets/lab/use_cases/file_summarizer_example_2.py +157 -0
  690. pygeai/tests/snippets/lab/use_cases/update_cli_expert.py +1773 -0
  691. pygeai/tests/snippets/lab/use_cases/update_lab_expert.py +4541 -0
  692. pygeai/tests/snippets/lab/use_cases/update_web_designer.py +188 -0
  693. pygeai/tests/snippets/lab/use_cases/update_web_reader.py +195 -0
  694. pygeai/tests/snippets/lab/use_cases/update_web_reader_with_tool.py +210 -0
  695. pygeai/tests/snippets/migrate/__init__.py +45 -0
  696. pygeai/tests/snippets/migrate/agent_migration.py +110 -0
  697. pygeai/tests/snippets/migrate/assistant_migration.py +64 -0
  698. pygeai/tests/snippets/migrate/orchestrator_examples.py +179 -0
  699. pygeai/tests/snippets/migrate/process_migration.py +64 -0
  700. pygeai/tests/snippets/migrate/project_migration.py +42 -0
  701. pygeai/tests/snippets/migrate/tool_migration.py +64 -0
  702. pygeai/tests/snippets/organization/__init__.py +0 -0
  703. pygeai/tests/snippets/organization/add_project_member.py +10 -0
  704. pygeai/tests/snippets/organization/add_project_member_batch.py +44 -0
  705. pygeai/tests/snippets/organization/create_project.py +23 -0
  706. pygeai/tests/snippets/organization/delete_project.py +7 -0
  707. pygeai/tests/snippets/organization/export_request_data.py +7 -0
  708. pygeai/tests/snippets/organization/get_memberships.py +12 -0
  709. pygeai/tests/snippets/organization/get_organization_members.py +6 -0
  710. pygeai/tests/snippets/organization/get_project_data.py +7 -0
  711. pygeai/tests/snippets/organization/get_project_list.py +8 -0
  712. pygeai/tests/snippets/organization/get_project_members.py +6 -0
  713. pygeai/tests/snippets/organization/get_project_memberships.py +12 -0
  714. pygeai/tests/snippets/organization/get_project_roles.py +6 -0
  715. pygeai/tests/snippets/organization/get_project_tokens.py +7 -0
  716. pygeai/tests/snippets/organization/update_project.py +14 -0
  717. pygeai/tests/snippets/rerank/__init__.py +0 -0
  718. pygeai/tests/snippets/rerank/rerank_chunks.py +19 -0
  719. pygeai/tests/snippets/secrets/__init__.py +0 -0
  720. pygeai/tests/snippets/usage_limit/__init__.py +0 -0
  721. pygeai/tests/snippets/usage_limit/delete_usage_limit.py +16 -0
  722. pygeai/tests/snippets/usage_limit/get_all_usage_limit_from_organization.py +12 -0
  723. pygeai/tests/snippets/usage_limit/get_usage_limit_from_organization.py +11 -0
  724. pygeai/tests/snippets/usage_limit/get_usage_limit_from_project.py +13 -0
  725. pygeai/tests/snippets/usage_limit/set_usage_limit_organization.py +22 -0
  726. pygeai/tests/snippets/usage_limit/set_usage_limit_project.py +23 -0
  727. pygeai/tests/snippets/usage_limit/update_usage_limit_organization.py +23 -0
  728. pygeai/tests/snippets/usage_limit/update_usage_limit_project.py +24 -0
  729. pygeai/vendor/a2a/__init__.py +1 -0
  730. pygeai/vendor/a2a/auth/__init__.py +0 -0
  731. pygeai/vendor/a2a/auth/user.py +31 -0
  732. pygeai/vendor/a2a/client/__init__.py +19 -0
  733. pygeai/vendor/a2a/client/client.py +425 -0
  734. pygeai/vendor/a2a/client/errors.py +33 -0
  735. pygeai/vendor/a2a/client/helpers.py +22 -0
  736. pygeai/vendor/a2a/py.typed +0 -0
  737. pygeai/vendor/a2a/server/__init__.py +1 -0
  738. pygeai/vendor/a2a/server/agent_execution/__init__.py +18 -0
  739. pygeai/vendor/a2a/server/agent_execution/agent_executor.py +44 -0
  740. pygeai/vendor/a2a/server/agent_execution/context.py +155 -0
  741. pygeai/vendor/a2a/server/agent_execution/request_context_builder.py +20 -0
  742. pygeai/vendor/a2a/server/agent_execution/simple_request_context_builder.py +77 -0
  743. pygeai/vendor/a2a/server/apps/__init__.py +16 -0
  744. pygeai/vendor/a2a/server/apps/jsonrpc/__init__.py +16 -0
  745. pygeai/vendor/a2a/server/apps/jsonrpc/fastapi_app.py +88 -0
  746. pygeai/vendor/a2a/server/apps/jsonrpc/jsonrpc_app.py +426 -0
  747. pygeai/vendor/a2a/server/apps/jsonrpc/starlette_app.py +123 -0
  748. pygeai/vendor/a2a/server/context.py +23 -0
  749. pygeai/vendor/a2a/server/events/__init__.py +21 -0
  750. pygeai/vendor/a2a/server/events/event_consumer.py +149 -0
  751. pygeai/vendor/a2a/server/events/event_queue.py +156 -0
  752. pygeai/vendor/a2a/server/events/in_memory_queue_manager.py +85 -0
  753. pygeai/vendor/a2a/server/events/queue_manager.py +35 -0
  754. pygeai/vendor/a2a/server/request_handlers/__init__.py +20 -0
  755. pygeai/vendor/a2a/server/request_handlers/default_request_handler.py +435 -0
  756. pygeai/vendor/a2a/server/request_handlers/jsonrpc_handler.py +327 -0
  757. pygeai/vendor/a2a/server/request_handlers/request_handler.py +161 -0
  758. pygeai/vendor/a2a/server/request_handlers/response_helpers.py +133 -0
  759. pygeai/vendor/a2a/server/tasks/__init__.py +20 -0
  760. pygeai/vendor/a2a/server/tasks/inmemory_push_notifier.py +62 -0
  761. pygeai/vendor/a2a/server/tasks/inmemory_task_store.py +51 -0
  762. pygeai/vendor/a2a/server/tasks/push_notifier.py +25 -0
  763. pygeai/vendor/a2a/server/tasks/result_aggregator.py +151 -0
  764. pygeai/vendor/a2a/server/tasks/task_manager.py +253 -0
  765. pygeai/vendor/a2a/server/tasks/task_store.py +22 -0
  766. pygeai/vendor/a2a/server/tasks/task_updater.py +155 -0
  767. pygeai/vendor/a2a/types.py +1624 -0
  768. pygeai/vendor/a2a/utils/__init__.py +40 -0
  769. pygeai/vendor/a2a/utils/artifact.py +72 -0
  770. pygeai/vendor/a2a/utils/errors.py +69 -0
  771. pygeai/vendor/a2a/utils/helpers.py +176 -0
  772. pygeai/vendor/a2a/utils/message.py +83 -0
  773. pygeai/vendor/a2a/utils/task.py +57 -0
  774. pygeai/vendor/a2a/utils/telemetry.py +299 -0
  775. pygeai-0.6.0b15.dist-info/METADATA +205 -0
  776. pygeai-0.6.0b15.dist-info/RECORD +799 -0
  777. {pygeai-0.1.6.dist-info → pygeai-0.6.0b15.dist-info}/WHEEL +1 -1
  778. pygeai-0.6.0b15.dist-info/entry_points.txt +5 -0
  779. {pygeai-0.1.6.dist-info → pygeai-0.6.0b15.dist-info/licenses}/LICENSE +13 -1
  780. {pygeai-0.1.6.dist-info → pygeai-0.6.0b15.dist-info}/top_level.txt +0 -1
  781. docs/source/conf.py +0 -45
  782. pygeai/core/clients.py +0 -240
  783. pygeai/tests/core/test_clients.py +0 -49
  784. pygeai-0.1.6.dist-info/METADATA +0 -92
  785. pygeai-0.1.6.dist-info/RECORD +0 -65
  786. pygeai-0.1.6.dist-info/SOURCES.sync-conflict-20241223-145950-3QD4F42.txt +0 -41
  787. pygeai-0.1.6.dist-info/entry_points.txt +0 -2
  788. /pygeai/{agent → analytics}/__init__.py +0 -0
@@ -0,0 +1,4541 @@
1
+ from pygeai.lab.managers import AILabManager
2
+ from pygeai.lab.models import Agent, AgentData, Prompt, LlmConfig, Model, Sampling, PromptExample, PromptOutput
3
+ import uuid
4
+
5
+ GEAI_LAB_HELP = """\
6
+ The Lab
7
+ The Globant Enterprise AI Lab is a comprehensive framework designed to create, manage, and orchestrate autonomous AI agents capable of addressing complex tasks with minimal human intervention. It provides a structured environment for defining agents, their associated tools, reasoning strategies, and workflows, all integrated within a cohesive ecosystem. The PyGEAI SDK serves as the primary interface for developers to interact with the Lab, offering a Python-native experience through the lab module, which enables seamless management of the Lab’s resources and operations.
8
+
9
+ Overview
10
+ The Globant Enterprise AI Lab enables the creation of intelligent AI agents, from collaborative co-pilots to fully autonomous systems, capable of executing intricate tasks. Its modular design ensures flexibility, allowing developers to define agent behaviors, orchestrate collaborative workflows, and manage knowledge artifacts. The PyGEAI SDK streamlines these processes by providing an intuitive, Python-centric interface that abstracts the Lab’s underlying APIs, making it accessible to developers familiar with Python conventions.
11
+
12
+ The Lab’s core modules are:
13
+
14
+ Agents & Tools Repository: A centralized hub for defining and managing agents and their resources, such as skills, tools, and external API integrations.
15
+
16
+ Agentic Flows: A system for creating workflows that combine tasks, agents, and knowledge artifacts to achieve broader objectives.
17
+
18
+ Knowledge Base: A repository for storing and organizing artifacts (e.g., documents, data outputs) that agents consume or produce during workflows.
19
+
20
+ Agent Runtime: The execution environment where agents perform tasks, interact with artifacts, and respond to events within defined workflows.
21
+
22
+ Interacting with the Lab via PyGEAI SDK
23
+ The PyGEAI SDK’s lab module provides a streamlined interface for developers to engage with the Globant Enterprise AI Lab. Designed to align with Python conventions, it offers a command-line tool that facilitates interaction with the Lab’s resources, including agents, tools, reasoning strategies, processes, tasks, and runtime instances. The lab module supports a range of operations, ensuring developers can efficiently manage the Lab’s ecosystem.
24
+
25
+ ### Managing Agents
26
+
27
+ The lab module enables developers to define and manage AI agents within the Lab. Agents are entities configured with specific prompts, language models, and operational parameters to perform designated tasks. Through the lab module, developers can create agents with custom attributes, update their configurations, retrieve details, list available agents, publish revisions, share agents via links, or remove them as needed. This functionality allows for precise control over agent lifecycle and behavior within the Lab’s environment.
28
+
29
+ ### Configuring Tools
30
+
31
+ Tools extend agent capabilities by providing access to external APIs, built-in functions, or custom logic. The lab module supports the creation and management of tools, allowing developers to define tools with specific scopes (e.g., API-based or external), configure their parameters, and control their accessibility. Developers can list tools, retrieve tool details, update configurations, publish revisions, set parameters, or delete tools, ensuring tools are seamlessly integrated into the Lab’s workflows.
32
+
33
+ ### Defining Reasoning Strategies
34
+
35
+ Reasoning strategies guide how agents process information and make decisions. The lab module allows developers to create and manage these strategies, specifying system prompts and access scopes to tailor agent reasoning. Developers can list available strategies, retrieve details, update configurations, and ensure strategies align with project requirements, enhancing agent performance within the Lab.
36
+
37
+ ### Orchestrating Processes
38
+
39
+ Processes in the Lab define workflows that combine agents, tasks, and knowledge artifacts to achieve complex objectives. The lab module facilitates process management by enabling developers to create processes, define their structure (including activities, signals, and sequence flows), and update configurations. Developers can list processes, retrieve details, publish revisions, or delete processes, providing full control over workflow orchestration within the Lab.
40
+
41
+ ### Managing Tasks
42
+
43
+ Tasks are individual units of work within processes, assigned to agents for execution. The lab module supports task creation, allowing developers to specify task prompts, artifact types, and descriptions. Developers can list tasks, retrieve task details, update configurations, publish revisions, or delete tasks, ensuring tasks are effectively integrated into the Lab’s workflows.
44
+
45
+ ### Controlling Runtime Instances
46
+
47
+ The Lab’s runtime environment executes processes, where agents perform tasks and interact with artifacts. The lab module provides commands to manage runtime instances, enabling developers to start process instances, monitor their progress, retrieve instance details, access execution history, send signals to influence workflow, or abort instances as needed. This ensures dynamic control over the Lab’s operational execution.
48
+
49
+ ### Running Agents with the Runner
50
+
51
+ The Runner class in the lab module provides a direct interface for executing agent tasks asynchronously within the Lab’s runtime environment. It allows developers to run agents with flexible input formats—strings, ChatMessage, or ChatMessageList—and customizable LLM settings, enabling tailored interactions for testing or production use. The Runner simplifies agent execution by handling message processing and LLM configuration, returning a ProviderResponse object containing the agent’s response and metadata.
52
+
53
+ SDK Tools and Utilities
54
+ The PyGEAI SDK provides robust programmatic interfaces for interacting with the Globant Enterprise AI Lab, enabling developers to manage agents, tools, reasoning strategies, processes, tasks, and runtime instances directly within Python applications. Beyond the command-line interface, the SDK offers a high-level manager and low-level client classes, designed to integrate seamlessly into development workflows with structured, object-oriented access or flexible JSON-based interactions.
55
+
56
+ High-Level Interface: AILabManager
57
+ The AILabManager class serves as the primary high-level interface, offering a Pythonic, object-oriented approach to managing the Lab’s resources. It abstracts the underlying API complexity, mapping responses to structured Python objects such as Agent, Tool, ReasoningStrategy, AgenticProcess, Task, and ProcessInstance. This allows developers to work with strongly typed models, ensuring clarity and reducing errors when creating, updating, retrieving, or deleting Lab entities.
58
+
59
+ Agent Management: Create, update, retrieve, list, publish, share, or delete agents using methods like create_agent, update_agent, get_agent, and delete_agent. Agents are represented as Agent objects, encapsulating properties like name, prompts, and LLM configurations.
60
+
61
+ Tool Management: Define and manage tools with methods such as create_tool, update_tool, get_tool, list_tools, publish_tool_revision, and delete_tool. Tools are modeled as Tool objects, supporting API-based or custom configurations with parameters (ToolParameter).
62
+
63
+ Reasoning Strategies: Configure agent reasoning with create_reasoning_strategy, update_reasoning_strategy, get_reasoning_strategy, and list_reasoning_strategies. Strategies are represented as ReasoningStrategy objects, defining system prompts and access scopes.
64
+
65
+ Process Orchestration: Manage workflows through create_process, update_process, get_process, list_processes, publish_process_revision, and delete_process. Processes are encapsulated as AgenticProcess objects, detailing activities, signals, and sequence flows.
66
+
67
+ Task Management: Create and manage tasks with create_task, update_task, get_task, list_tasks, publish_task_revision, and delete_task. Tasks are modeled as Task objects, specifying prompts and artifact types.
68
+
69
+ Runtime Control: Start, monitor, and control process instances using start_instance, get_instance, list_process_instances, get_instance_history, send_user_signal, and abort_instance. Instances are represented as ProcessInstance objects, with execution details and thread information accessible via get_thread_information.
70
+
71
+ The AILabManager is initialized with an API key, base URL, and optional alias, providing a unified entry point for all Lab operations. Its methods handle error mapping (ErrorListResponse) and response validation, making it ideal for rapid development and integration into larger applications.
72
+
73
+ Low-Level Interface: Client Classes
74
+ For developers requiring fine-grained control or preferring to work directly with JSON responses, the SDK includes low-level client classes: AgentClient, ToolClient, ReasoningStrategyClient, and AgenticProcessClient. These clients interact with the Lab’s APIs without mapping responses to Python objects, returning raw JSON or text for maximum flexibility.
75
+
76
+ AgentClient: Supports operations like create_agent, update_agent, get_agent, list_agents, publish_agent_revision, create_sharing_link, and delete_agent. It handles agent-specific API endpoints, passing parameters like project ID, agent name, prompts, and LLM configurations as dictionaries.
77
+
78
+ ToolClient: Provides methods such as create_tool, update_tool, get_tool, list_tools, publish_tool_revision, get_parameter, set_parameter, and delete_tool. It manages tool configurations, including OpenAPI specifications and parameter lists, with validation for scopes and access levels.
79
+
80
+ ReasoningStrategyClient: Includes create_reasoning_strategy, update_reasoning_strategy, get_reasoning_strategy, and list_reasoning_strategies, allowing direct manipulation of strategy definitions like system prompts and localized descriptions.
81
+
82
+ AgenticProcessClient: Offers comprehensive process and task management with methods like create_process, update_process, get_process, list_processes, publish_process_revision, delete_process, create_task, update_task, get_task, list_tasks, publish_task_revision, delete_task, start_instance, get_instance, list_process_instances, get_instance_history, get_thread_information, send_user_signal, and abort_instance. It handles complex process structures and runtime operations in JSON format.
83
+
84
+ Each client is initialized with an API key and base URL, using a BaseClient for HTTP requests. They provide direct access to the Lab’s endpoints, enabling custom parsing or integration with external systems where object mapping is unnecessary.
85
+
86
+ Integration and Flexibility
87
+ Both the AILabManager and client classes are installable via pip install pygeai and support cross-platform development. The high-level AILabManager is suited for structured applications requiring type safety and ease of use, while the low-level clients cater to scenarios demanding raw API responses or custom workflows. Developers can combine these interfaces within the same project, leveraging AILabManager for rapid prototyping and clients for specialized tasks.
88
+
89
+ Data Models
90
+ The PyGEAI SDK provides Pydantic-based data models for interacting with the Globant Enterprise AI Lab, enabling developers to configure agents, tools, processes, tasks, and more. These models ensure type safety and API compatibility without requiring hardcoded field details that may change. Many models allow direct dictionary inputs for nested configurations, simplifying instantiation. This section describes each model’s purpose, provides examples of instantiation (via attributes and dictionaries), and notes key restrictions, keeping documentation maintainable and flexible.
91
+
92
+ Note
93
+
94
+ Models inherit from CustomBaseModel, a Pydantic BaseModel subclass, providing to_dict() for serialization.
95
+
96
+ FilterSettings
97
+ Purpose
98
+ Configures filters for querying Lab entities like agents or tools, supporting pagination and scope.
99
+
100
+ Usage Examples
101
+ Via Attributes:
102
+
103
+ from pygeai.lab.models import FilterSettings
104
+
105
+ filters = FilterSettings(id="agent-123", name="MyAgent", access_scope="private")
106
+ print(filters.to_dict())
107
+ # Output: Dictionary with filter settings
108
+ Via Dictionary:
109
+
110
+ from pygeai.lab.models import FilterSettings
111
+
112
+ filters = FilterSettings(**{
113
+ "id": "agent-123",
114
+ "name": "MyAgent",
115
+ "accessScope": "private"
116
+ })
117
+ print(filters.to_dict())
118
+ # Output: Dictionary with filter settings
119
+ Restrictions and Considerations
120
+ Most fields are optional for flexible queries.
121
+
122
+ Pagination requires non-negative integers.
123
+
124
+ Scope values must match API expectations (e.g., “public”, “private”).
125
+
126
+ Use dictionaries for quick filter setup in API calls.
127
+
128
+ Avoid over-specifying to ensure results.
129
+
130
+ Sampling
131
+ Purpose
132
+ Controls randomness in LLM token generation.
133
+
134
+ Usage Examples
135
+ Via Attributes:
136
+
137
+ from pygeai.lab.models import Sampling
138
+
139
+ sampling = Sampling(temperature=0.8, top_k=40, top_p=0.95)
140
+ print(sampling.to_dict())
141
+ # Output: {"temperature": 0.8, "topK": 40, "topP": 0.95}
142
+ Via Dictionary:
143
+
144
+ from pygeai.lab.models import Sampling
145
+
146
+ sampling = Sampling(**{
147
+ "temperature": 0.8,
148
+ "topK": 40,
149
+ "topP": 0.95
150
+ })
151
+ print(sampling.to_dict())
152
+ # Output: {"temperature": 0.8, "topK": 40, "topP": 0.95}
153
+ Restrictions and Considerations
154
+ All fields are required.
155
+
156
+ Temperature should range from 0.1 to 2.0.
157
+
158
+ Top-k and top-p need positive, reasonable values.
159
+
160
+ Dictionaries simplify sampling configuration.
161
+
162
+ Test settings to balance creativity and coherence.
163
+
164
+ LlmConfig
165
+ Purpose
166
+ Defines LLM settings, including token limits and sampling.
167
+
168
+ Usage Examples
169
+ Via Attributes:
170
+
171
+ from pygeai.lab.models import LlmConfig, Sampling
172
+
173
+ sampling = Sampling(temperature=0.7, top_k=50, top_p=0.9)
174
+ llm_config = LlmConfig(max_tokens=2048, timeout=30, sampling=sampling)
175
+ print(llm_config.to_dict())
176
+ # Output: Dictionary with LLM settings
177
+ Via Dictionary (with Sampling as dict):
178
+
179
+ from pygeai.lab.models import LlmConfig
180
+
181
+ llm_config = LlmConfig(**{
182
+ "maxTokens": 2048,
183
+ "timeout": 30,
184
+ "sampling": {
185
+ "temperature": 0.7,
186
+ "topK": 50,
187
+ "topP": 0.9
188
+ }
189
+ })
190
+ print(llm_config.to_dict())
191
+ # Output: Dictionary with LLM settings
192
+ Restrictions and Considerations
193
+ Core fields are mandatory.
194
+
195
+ Token limits depend on LLM capacity.
196
+
197
+ Timeout may be API-capped; use 0 carefully.
198
+
199
+ Accepts sampling as a dictionary for convenience.
200
+
201
+ Verify settings before scaling.
202
+
203
+ Model
204
+ Purpose
205
+ Customizes an LLM for an agent.
206
+
207
+ Usage Examples
208
+ Via Attributes:
209
+
210
+ from pygeai.lab.models import Model, LlmConfig, Sampling
211
+
212
+ sampling = Sampling(temperature=0.7, top_k=50, top_p=0.9)
213
+ llm_config = LlmConfig(max_tokens=2048, timeout=30, sampling=sampling)
214
+ model = Model(name="gpt-4", llm_config=llm_config)
215
+ print(model.to_dict())
216
+ # Output: Dictionary with model settings
217
+ Via Dictionary (with LlmConfig as dict):
218
+
219
+ from pygeai.lab.models import Model
220
+
221
+ model = Model(**{
222
+ "name": "gpt-4",
223
+ "llmConfig": {
224
+ "maxTokens": 2048,
225
+ "timeout": 30,
226
+ "sampling": {
227
+ "temperature": 0.7,
228
+ "topK": 50,
229
+ "topP": 0.9
230
+ }
231
+ }
232
+ })
233
+ print(model.to_dict())
234
+ # Output: Dictionary with model settings
235
+ Restrictions and Considerations
236
+ Name is required; must be Lab-supported.
237
+
238
+ Optional LLM config can be a dictionary.
239
+
240
+ Prompt, if used, should align with agent tasks.
241
+
242
+ Useful for flexible model assignments.
243
+
244
+ Check LLM compatibility.
245
+
246
+ PromptExample
247
+ Purpose
248
+ Provides input-output pairs for few-shot learning.
249
+
250
+ Usage Examples
251
+ Via Attributes:
252
+
253
+ from pygeai.lab.models import PromptExample
254
+
255
+ example = PromptExample(input_data="Summarize: [article]", output='{"summary": "AI news."}')
256
+ print(example.to_dict())
257
+ # Output: Dictionary with example data
258
+ Via Dictionary:
259
+
260
+ from pygeai.lab.models import PromptExample
261
+
262
+ example = PromptExample(**{
263
+ "inputData": "Summarize: [article]",
264
+ "output": '{"summary": "AI news."}'
265
+ })
266
+ print(example.to_dict())
267
+ # Output: Dictionary with example data
268
+ Restrictions and Considerations
269
+ Both fields are required; output must be JSON.
270
+
271
+ Keep examples concise and relevant.
272
+
273
+ Multiple examples improve accuracy.
274
+
275
+ Dictionaries simplify example setup.
276
+
277
+ Monitor token usage with examples.
278
+
279
+ PromptOutput
280
+ Purpose
281
+ Defines expected prompt outputs.
282
+
283
+ Usage Examples
284
+ Via Attributes:
285
+
286
+ from pygeai.lab.models import PromptOutput
287
+
288
+ output = PromptOutput(key="summary", description="Text summary.")
289
+ print(output.to_dict())
290
+ # Output: {"key": "summary", "description": "Text summary."}
291
+ Via Dictionary:
292
+
293
+ from pygeai.lab.models import PromptOutput
294
+
295
+ output = PromptOutput(**{
296
+ "key": "summary",
297
+ "description": "Text summary."
298
+ })
299
+ print(output.to_dict())
300
+ # Output: {"key": "summary", "description": "Text summary."}
301
+ Restrictions and Considerations
302
+ Key and description are required.
303
+
304
+ Keys must be unique per prompt.
305
+
306
+ Use clear descriptions for output format.
307
+
308
+ Dictionaries streamline output definitions.
309
+
310
+ Supports multiple outputs.
311
+
312
+ Prompt
313
+ Purpose
314
+ Configures an agent’s prompt behavior.
315
+
316
+ Usage Examples
317
+ Via Attributes:
318
+
319
+ from pygeai.lab.models import Prompt, PromptOutput, PromptExample
320
+
321
+ output = PromptOutput(key="summary", description="Text summary.")
322
+ example = PromptExample(input_data="Article: [content]", output='{"summary": "AI news."}')
323
+ prompt = Prompt(instructions="Summarize article.", inputs=["article"], outputs=[output], examples=[example])
324
+ print(prompt.to_dict())
325
+ # Output: Dictionary with prompt settings
326
+ Via Dictionary (with Outputs, Examples as dicts):
327
+
328
+ from pygeai.lab.models import Prompt
329
+
330
+ prompt = Prompt(**{
331
+ "instructions": "Summarize article.",
332
+ "inputs": ["article"],
333
+ "outputs": [{"key": "summary", "description": "Text summary."}],
334
+ "examples": [{"inputData": "Article: [content]", "output": '{"summary": "AI news."}'}]
335
+ })
336
+ print(prompt.to_dict())
337
+ # Output: Dictionary with prompt settings
338
+ Restrictions and Considerations
339
+ Instructions, inputs, and outputs are required.
340
+
341
+ Outputs need at least one entry.
342
+
343
+ Accepts outputs and examples as dictionaries.
344
+
345
+ Inputs must be unique.
346
+
347
+ Avoid unimplemented fields like context.
348
+
349
+ ModelList
350
+ Purpose
351
+ Holds multiple model configurations.
352
+
353
+ Usage Examples
354
+ Via Attributes:
355
+
356
+ from pygeai.lab.models import ModelList, Model
357
+
358
+ model = Model(name="gpt-4")
359
+ model_list = ModelList(models=[model])
360
+ print(model_list.to_dict())
361
+ # Output: List of model dictionaries
362
+ Via Dictionary (with Models as dicts):
363
+
364
+ from pygeai.lab.models import ModelList
365
+
366
+ model_list = ModelList(**{
367
+ "models": [
368
+ {"name": "gpt-4"},
369
+ {"name": "gpt-3.5"}
370
+ ]
371
+ })
372
+ print(model_list.to_dict())
373
+ # Output: List of model dictionaries
374
+ Restrictions and Considerations
375
+ Models collection is required; can be empty.
376
+
377
+ Accepts models as dictionaries.
378
+
379
+ Supports iteration and appending.
380
+
381
+ Ensure unique model names.
382
+
383
+ Simplifies bulk model setup.
384
+
385
+ AgentData
386
+ Purpose
387
+ Defines an agent’s core configuration.
388
+
389
+ Usage Examples
390
+ Via Attributes:
391
+
392
+ from pygeai.lab.models import AgentData, Prompt, PromptOutput, LlmConfig, Sampling, ModelList, Model
393
+
394
+ prompt = Prompt(instructions="Summarize.", inputs=["text"], outputs=[PromptOutput(key="summary", description="Summary.")])
395
+ sampling = Sampling(temperature=0.7, top_k=50, top_p=0.9)
396
+ llm_config = LlmConfig(max_tokens=2048, timeout=30, sampling=sampling)
397
+ model_list = ModelList(models=[Model(name="gpt-4")])
398
+ agent_data = AgentData(prompt=prompt, llm_config=llm_config, models=model_list)
399
+ print(agent_data.to_dict())
400
+ # Output: Dictionary with agent data
401
+ Via Dictionary (with Prompt, LlmConfig, Models as dicts):
402
+
403
+ from pygeai.lab.models import AgentData
404
+
405
+ agent_data = AgentData(**{
406
+ "prompt": {
407
+ "instructions": "Summarize.",
408
+ "inputs": ["text"],
409
+ "outputs": [{"key": "summary", "description": "Summary."}]
410
+ },
411
+ "llmConfig": {
412
+ "maxTokens": 2048,
413
+ "timeout": 30,
414
+ "sampling": {"temperature": 0.7, "topK": 50, "topP": 0.9}
415
+ },
416
+ "models": [{"name": "gpt-4"}]
417
+ })
418
+ print(agent_data.to_dict())
419
+ # Output: Dictionary with agent data
420
+ Restrictions and Considerations
421
+ Core components are required.
422
+
423
+ Accepts prompt, LLM config, and models as dictionaries.
424
+
425
+ Non-draft agents need at least one model.
426
+
427
+ Align settings with LLM capabilities.
428
+
429
+ Simplifies complex agent setups.
430
+
431
+ Agent
432
+ Purpose
433
+ Represents a complete agent with metadata.
434
+
435
+ Usage Examples
436
+ Via Attributes:
437
+
438
+ from pygeai.lab.models import Agent, AgentData, Prompt, PromptOutput, ModelList, Model
439
+
440
+ prompt = Prompt(instructions="Summarize.", inputs=["text"], outputs=[PromptOutput(key="summary", description="Summary.")])
441
+ model_list = ModelList(models=[Model(name="gpt-4")])
442
+ agent_data = AgentData(prompt=prompt, llm_config=LlmConfig(max_tokens=2048, timeout=30, sampling=Sampling(temperature=0.7, top_k=50, top_p=0.9)), models=model_list)
443
+ agent = Agent(name="SummaryAgent", access_scope="public", public_name="summary-agent", agent_data=agent_data)
444
+ print(agent.to_dict())
445
+ # Output: Dictionary with agent settings
446
+ Via Dictionary (with AgentData as dict):
447
+
448
+ from pygeai.lab.models import Agent
449
+
450
+ agent = Agent(**{
451
+ "name": "SummaryAgent",
452
+ "accessScope": "public",
453
+ "publicName": "summary-agent",
454
+ "agentData": {
455
+ "prompt": {
456
+ "instructions": "Summarize.",
457
+ "inputs": ["text"],
458
+ "outputs": [{"key": "summary", "description": "Summary."}]
459
+ },
460
+ "llmConfig": {
461
+ "maxTokens": 2048,
462
+ "timeout": 30,
463
+ "sampling": {"temperature": 0.7, "topK": 50, "topP": 0.9}
464
+ },
465
+ "models": [{"name": "gpt-4"}]
466
+ }
467
+ })
468
+ print(agent.to_dict())
469
+ # Output: Dictionary with agent settings
470
+ Restrictions and Considerations
471
+ Name is required; avoid special characters.
472
+
473
+ Accepts agent_data as a dictionary.
474
+
475
+ Public agents need valid public names.
476
+
477
+ Non-draft agents require full configuration.
478
+
479
+ API sets identifiers automatically.
480
+
481
+ AgentList
482
+ Purpose
483
+ Manages multiple agents, typically from API responses.
484
+
485
+ Usage Examples
486
+ Via Attributes:
487
+
488
+ from pygeai.lab.models import AgentList, Agent
489
+
490
+ agent = Agent(name="Agent1", access_scope="private")
491
+ agent_list = AgentList(agents=[agent])
492
+ print(agent_list.to_dict())
493
+ # Output: List of agent dictionaries
494
+ Via Dictionary (with Agents as dicts):
495
+
496
+ from pygeai.lab.models import AgentList
497
+
498
+ agent_list = AgentList(**{
499
+ "agents": [
500
+ {"name": "Agent1", "accessScope": "private"},
501
+ {"name": "Agent2", "accessScope": "public", "publicName": "agent-two"}
502
+ ]
503
+ })
504
+ print(agent_list.to_dict())
505
+ # Output: List of agent dictionaries
506
+ Restrictions and Considerations
507
+ Agents collection is required; can be empty.
508
+
509
+ Accepts agents as dictionaries.
510
+
511
+ Supports iteration and appending.
512
+
513
+ Useful for bulk agent management.
514
+
515
+ SharingLink
516
+ Purpose
517
+ Enables agent sharing via links.
518
+
519
+ Usage Examples
520
+ Via Attributes:
521
+
522
+ from pygeai.lab.models import SharingLink
523
+
524
+ link = SharingLink(agent_id="agent-123", api_token="xyz-token", shared_link="https://lab.globant.ai/share/agent-123")
525
+ print(link.to_dict())
526
+ # Output: Dictionary with link details
527
+ Via Dictionary:
528
+
529
+ from pygeai.lab.models import SharingLink
530
+
531
+ link = SharingLink(**{
532
+ "agentId": "agent-123",
533
+ "apiToken": "xyz-token",
534
+ "sharedLink": "https://lab.globant.ai/share/agent-123"
535
+ })
536
+ print(link.to_dict())
537
+ # Output: Dictionary with link details
538
+ Restrictions and Considerations
539
+ All fields are required, set by API.
540
+
541
+ Links must be valid URLs.
542
+
543
+ Secure tokens to prevent leaks.
544
+
545
+ Dictionaries simplify link creation.
546
+
547
+ ToolParameter
548
+ Purpose
549
+ Defines tool parameters.
550
+
551
+ Usage Examples
552
+ Via Attributes:
553
+
554
+ from pygeai.lab.models import ToolParameter
555
+
556
+ param = ToolParameter(key="api_key", data_type="String", description="API key.", is_required=True)
557
+ print(param.to_dict())
558
+ # Output: Dictionary with parameter details
559
+ Via Dictionary:
560
+
561
+ from pygeai.lab.models import ToolParameter
562
+
563
+ param = ToolParameter(**{
564
+ "key": "api_key",
565
+ "dataType": "String",
566
+ "description": "API key.",
567
+ "isRequired": True
568
+ })
569
+ print(param.to_dict())
570
+ # Output: Dictionary with parameter details
571
+ Restrictions and Considerations
572
+ Core fields are mandatory.
573
+
574
+ Data types must match API expectations.
575
+
576
+ Keys must be unique per tool.
577
+
578
+ Dictionaries streamline parameter setup.
579
+
580
+ ToolMessage
581
+ Purpose
582
+ Provides tool feedback messages.
583
+
584
+ Usage Examples
585
+ Via Attributes:
586
+
587
+ from pygeai.lab.models import ToolMessage
588
+
589
+ message = ToolMessage(description="Invalid key.", type="error")
590
+ print(message.to_dict())
591
+ # Output: {"description": "Invalid key.", "type": "error"}
592
+ Via Dictionary:
593
+
594
+ from pygeai.lab.models import ToolMessage
595
+
596
+ message = ToolMessage(**{
597
+ "description": "Invalid key.",
598
+ "type": "error"
599
+ })
600
+ print(message.to_dict())
601
+ # Output: {"description": "Invalid key.", "type": "error"}
602
+ Restrictions and Considerations
603
+ Both fields are required.
604
+
605
+ Types are typically “warning” or “error.”
606
+
607
+ Keep messages concise.
608
+
609
+ Dictionaries simplify message creation.
610
+
611
+ Tool
612
+ Purpose
613
+ Configures tools for agents.
614
+
615
+ Usage Examples
616
+ Via Attributes:
617
+
618
+ from pygeai.lab.models import Tool, ToolParameter
619
+
620
+ param = ToolParameter(key="api_key", data_type="String", description="API key.", is_required=True)
621
+ tool = Tool(name="WeatherTool", description="Fetches weather.", scope="api", parameters=[param])
622
+ print(tool.to_dict())
623
+ # Output: Dictionary with tool settings
624
+ Via Dictionary (with Parameters as dicts):
625
+
626
+ from pygeai.lab.models import Tool
627
+
628
+ tool = Tool(**{
629
+ "name": "WeatherTool",
630
+ "description": "Fetches weather.",
631
+ "scope": "api",
632
+ "parameters": [
633
+ {"key": "api_key", "dataType": "String", "description": "API key.", "isRequired": True}
634
+ ]
635
+ })
636
+ print(tool.to_dict())
637
+ # Output: Dictionary with tool settings
638
+ Restrictions and Considerations
639
+ Name and description are required.
640
+
641
+ Accepts parameters as dictionaries.
642
+
643
+ API tools need valid OpenAPI specs.
644
+
645
+ Public tools require valid public names.
646
+
647
+ Ensure unique parameter keys.
648
+
649
+ ToolList
650
+ Purpose
651
+ Manages multiple tools.
652
+
653
+ Usage Examples
654
+ Via Attributes:
655
+
656
+ from pygeai.lab.models import ToolList, Tool
657
+
658
+ tool = Tool(name="Tool1", description="Tool one.", scope="builtin")
659
+ tool_list = ToolList(tools=[tool])
660
+ print(tool_list.to_dict())
661
+ # Output: Dictionary with tool list
662
+ Via Dictionary (with Tools as dicts):
663
+
664
+ from pygeai.lab.models import ToolList
665
+
666
+ tool_list = ToolList(**{
667
+ "tools": [
668
+ {"name": "Tool1", "description": "Tool one.", "scope": "builtin"}
669
+ ]
670
+ })
671
+ print(tool_list.to_dict())
672
+ # Output: Dictionary with tool list
673
+ Restrictions and Considerations
674
+ Tools collection is required; can be empty.
675
+
676
+ Accepts tools as dictionaries.
677
+
678
+ Supports iteration and appending.
679
+
680
+ Simplifies bulk tool handling.
681
+
682
+ LocalizedDescription
683
+ Purpose
684
+ Provides multilingual strategy descriptions.
685
+
686
+ Usage Examples
687
+ Via Attributes:
688
+
689
+ from pygeai.lab.models import LocalizedDescription
690
+
691
+ desc = LocalizedDescription(language="english", description="Creative strategy.")
692
+ print(desc.to_dict())
693
+ # Output: {"language": "english", "description": "Creative strategy."}
694
+ Via Dictionary:
695
+
696
+ from pygeai.lab.models import LocalizedDescription
697
+
698
+ desc = LocalizedDescription(**{
699
+ "language": "english",
700
+ "description": "Creative strategy."
701
+ })
702
+ print(desc.to_dict())
703
+ # Output: {"language": "english", "description": "Creative strategy."}
704
+ Restrictions and Considerations
705
+ Both fields are required.
706
+
707
+ Use standard language names.
708
+
709
+ Dictionaries simplify descriptions.
710
+
711
+ Supports multiple languages.
712
+
713
+ ReasoningStrategy
714
+ Purpose
715
+ Guides agent reasoning behavior.
716
+
717
+ Usage Examples
718
+ Via Attributes:
719
+
720
+ from pygeai.lab.models import ReasoningStrategy, LocalizedDescription
721
+
722
+ desc = LocalizedDescription(language="english", description="Creative strategy.")
723
+ strategy = ReasoningStrategy(name="CreativeStrategy", access_scope="public", type="addendum", localized_descriptions=[desc])
724
+ print(strategy.to_dict())
725
+ # Output: Dictionary with strategy settings
726
+ Via Dictionary (with Descriptions as dicts):
727
+
728
+ from pygeai.lab.models import ReasoningStrategy
729
+
730
+ strategy = ReasoningStrategy(**{
731
+ "name": "CreativeStrategy",
732
+ "accessScope": "public",
733
+ "type": "addendum",
734
+ "localizedDescriptions": [
735
+ {"language": "english", "description": "Creative strategy."}
736
+ ]
737
+ })
738
+ print(strategy.to_dict())
739
+ # Output: Dictionary with strategy settings
740
+ Restrictions and Considerations
741
+ Name, scope, and type are required.
742
+
743
+ Accepts descriptions as dictionaries.
744
+
745
+ Scope and type depend on Lab values.
746
+
747
+ API sets identifiers.
748
+
749
+ ReasoningStrategyList
750
+ Purpose
751
+ Manages multiple reasoning strategies.
752
+
753
+ Usage Examples
754
+ Via Attributes:
755
+
756
+ from pygeai.lab.models import ReasoningStrategyList, ReasoningStrategy
757
+
758
+ strategy = ReasoningStrategy(name="Strategy1", access_scope="private", type="addendum")
759
+ strategy_list = ReasoningStrategyList(strategies=[strategy])
760
+ print(strategy_list.to_dict())
761
+ # Output: List of strategy dictionaries
762
+ Via Dictionary (with Strategies as dicts):
763
+
764
+ from pygeai.lab.models import ReasoningStrategyList
765
+
766
+ strategy_list = ReasoningStrategyList(**{
767
+ "strategies": [
768
+ {"name": "Strategy1", "accessScope": "private", "type": "addendum"}
769
+ ]
770
+ })
771
+ print(strategy_list.to_dict())
772
+ # Output: List of strategy dictionaries
773
+ Restrictions and Considerations
774
+ Strategies collection is required; can be empty.
775
+
776
+ Accepts strategies as dictionaries.
777
+
778
+ Supports iteration and appending.
779
+
780
+ KnowledgeBase
781
+ Purpose
782
+ Manages process artifacts.
783
+
784
+ Usage Examples
785
+ Via Attributes:
786
+
787
+ from pygeai.lab.models import KnowledgeBase
788
+
789
+ kb = KnowledgeBase(name="DocsKB", artifact_type_name=["document"])
790
+ print(kb.to_dict())
791
+ # Output: Dictionary with knowledge base settings
792
+ Via Dictionary:
793
+
794
+ from pygeai.lab.models import KnowledgeBase
795
+
796
+ kb = KnowledgeBase(**{
797
+ "name": "DocsKB",
798
+ "artifactTypeName": ["document"]
799
+ })
800
+ print(kb.to_dict())
801
+ # Output: Dictionary with knowledge base settings
802
+ Restrictions and Considerations
803
+ Name and artifact types are required.
804
+
805
+ Dictionaries simplify setup.
806
+
807
+ API sets identifiers.
808
+
809
+ Ensure valid artifact types.
810
+
811
+ AgenticActivity
812
+ Purpose
813
+ Links tasks and agents in processes.
814
+
815
+ Usage Examples
816
+ Via Attributes:
817
+
818
+ from pygeai.lab.models import AgenticActivity
819
+
820
+ activity = AgenticActivity(key="act1", name="Summarize", task_name="SummaryTask", agent_name="SummaryAgent", agent_revision_id=1)
821
+ print(activity.to_dict())
822
+ # Output: Dictionary with activity settings
823
+ Via Dictionary:
824
+
825
+ from pygeai.lab.models import AgenticActivity
826
+
827
+ activity = AgenticActivity(**{
828
+ "key": "act1",
829
+ "name": "Summarize",
830
+ "taskName": "SummaryTask",
831
+ "agentName": "SummaryAgent",
832
+ "agentRevisionId": 1
833
+ })
834
+ print(activity.to_dict())
835
+ # Output: Dictionary with activity settings
836
+ Restrictions and Considerations
837
+ Core fields are required.
838
+
839
+ Keys must be unique.
840
+
841
+ Dictionaries streamline activity setup.
842
+
843
+ Reference existing tasks and agents.
844
+
845
+ ArtifactSignal
846
+ Purpose
847
+ Triggers process actions via artifacts.
848
+
849
+ Usage Examples
850
+ Via Attributes:
851
+
852
+ from pygeai.lab.models import ArtifactSignal
853
+
854
+ signal = ArtifactSignal(key="sig1", name="DocSignal", handling_type="C", artifact_type_name=["document"])
855
+ print(signal.to_dict())
856
+ # Output: Dictionary with signal settings
857
+ Via Dictionary:
858
+
859
+ from pygeai.lab.models import ArtifactSignal
860
+
861
+ signal = ArtifactSignal(**{
862
+ "key": "sig1",
863
+ "name": "DocSignal",
864
+ "handlingType": "C",
865
+ "artifactTypeName": ["document"]
866
+ })
867
+ print(signal.to_dict())
868
+ # Output: Dictionary with signal settings
869
+ Restrictions and Considerations
870
+ All fields are required.
871
+
872
+ Keys must be unique.
873
+
874
+ Dictionaries simplify signal setup.
875
+
876
+ Handling types depend on Lab engine.
877
+
878
+ UserSignal
879
+ Purpose
880
+ Enables user-driven process signals.
881
+
882
+ Usage Examples
883
+ Via Attributes:
884
+
885
+ from pygeai.lab.models import UserSignal
886
+
887
+ signal = UserSignal(key="user1", name="UserInput")
888
+ print(signal.to_dict())
889
+ # Output: {"key": "user1", "name": "UserInput"}
890
+ Via Dictionary:
891
+
892
+ from pygeai.lab.models import UserSignal
893
+
894
+ signal = UserSignal(**{
895
+ "key": "user1",
896
+ "name": "UserInput"
897
+ })
898
+ print(signal.to_dict())
899
+ # Output: {"key": "user1", "name": "UserInput"}
900
+ Restrictions and Considerations
901
+ Both fields are required.
902
+
903
+ Keys must be unique.
904
+
905
+ Dictionaries simplify setup.
906
+
907
+ Use descriptive names.
908
+
909
+ Event
910
+ Purpose
911
+ Marks process start or end points.
912
+
913
+ Usage Examples
914
+ Via Attributes:
915
+
916
+ from pygeai.lab.models import Event
917
+
918
+ event = Event(key="start1", name="ProcessStart")
919
+ print(event.to_dict())
920
+ # Output: {"key": "start1", "name": "ProcessStart"}
921
+ Via Dictionary:
922
+
923
+ from pygeai.lab.models import Event
924
+
925
+ event = Event(**{
926
+ "key": "start1",
927
+ "name": "ProcessStart"
928
+ })
929
+ print(event.to_dict())
930
+ # Output: {"key": "start1", "name": "ProcessStart"}
931
+ Restrictions and Considerations
932
+ Both fields are required.
933
+
934
+ Keys must be unique.
935
+
936
+ Dictionaries simplify event setup.
937
+
938
+ Ensure flow connectivity.
939
+
940
+ SequenceFlow
941
+ Purpose
942
+ Connects process elements.
943
+
944
+ Usage Examples
945
+ Via Attributes:
946
+
947
+ from pygeai.lab.models import SequenceFlow
948
+
949
+ flow = SequenceFlow(key="flow1", source_key="start1", target_key="act1")
950
+ print(flow.to_dict())
951
+ # Output: Dictionary with flow settings
952
+ Via Dictionary:
953
+
954
+ from pygeai.lab.models import SequenceFlow
955
+
956
+ flow = SequenceFlow(**{
957
+ "key": "flow1",
958
+ "sourceKey": "start1",
959
+ "targetKey": "act1"
960
+ })
961
+ print(flow.to_dict())
962
+ # Output: Dictionary with flow settings
963
+ Restrictions and Considerations
964
+ All fields are required.
965
+
966
+ Keys must be unique.
967
+
968
+ Dictionaries simplify flow setup.
969
+
970
+ Reference valid elements.
971
+
972
+ Variable
973
+ Purpose
974
+ Stores dynamic process data.
975
+
976
+ Usage Examples
977
+ Via Attributes:
978
+
979
+ from pygeai.lab.models import Variable
980
+
981
+ var = Variable(key="input_text", value="Sample text")
982
+ print(var.to_dict())
983
+ # Output: {"key": "input_text", "value": "Sample text"}
984
+ Via Dictionary:
985
+
986
+ from pygeai.lab.models import Variable
987
+
988
+ var = Variable(**{
989
+ "key": "input_text",
990
+ "value": "Sample text"
991
+ })
992
+ print(var.to_dict())
993
+ # Output: {"key": "input_text", "value": "Sample text"}
994
+ Restrictions and Considerations
995
+ Both fields are required.
996
+
997
+ Keys should be unique.
998
+
999
+ Dictionaries simplify variable setup.
1000
+
1001
+ Values must be strings.
1002
+
1003
+ VariableList
1004
+ Purpose
1005
+ Manages process variables.
1006
+
1007
+ Usage Examples
1008
+ Via Attributes:
1009
+
1010
+ from pygeai.lab.models import VariableList, Variable
1011
+
1012
+ var = Variable(key="input_text", value="Sample text")
1013
+ var_list = VariableList(variables=[var])
1014
+ print(var_list.to_dict())
1015
+ # Output: List of variable dictionaries
1016
+ Via Dictionary (with Variables as dicts):
1017
+
1018
+ from pygeai.lab.models import VariableList
1019
+
1020
+ var_list = VariableList(**{
1021
+ "variables": [
1022
+ {"key": "input_text", "value": "Sample text"}
1023
+ ]
1024
+ })
1025
+ print(var_list.to_dict())
1026
+ # Output: List of variable dictionaries
1027
+ Restrictions and Considerations
1028
+ Variables collection is optional; defaults to empty.
1029
+
1030
+ Accepts variables as dictionaries.
1031
+
1032
+ Supports iteration and appending.
1033
+
1034
+ AgenticProcess
1035
+ Purpose
1036
+ Orchestrates process workflows.
1037
+
1038
+ Usage Examples
1039
+ Via Attributes:
1040
+
1041
+ from pygeai.lab.models import AgenticProcess, AgenticActivity, Event, SequenceFlow
1042
+
1043
+ activity = AgenticActivity(key="act1", name="Summarize", task_name="SummaryTask", agent_name="SummaryAgent", agent_revision_id=1)
1044
+ start_event = Event(key="start1", name="Start")
1045
+ flow = SequenceFlow(key="flow1", source_key="start1", target_key="act1")
1046
+ process = AgenticProcess(name="SummaryProcess", agentic_activities=[activity], start_event=start_event, sequence_flows=[flow])
1047
+ print(process.to_dict())
1048
+ # Output: Dictionary with process settings
1049
+ Via Dictionary (with Activities, Event, Flows as dicts):
1050
+
1051
+ from pygeai.lab.models import AgenticProcess
1052
+
1053
+ process = AgenticProcess(**{
1054
+ "name": "SummaryProcess",
1055
+ "agenticActivities": [
1056
+ {
1057
+ "key": "act1",
1058
+ "name": "Summarize",
1059
+ "taskName": "SummaryTask",
1060
+ "agentName": "SummaryAgent",
1061
+ "agentRevisionId": 1
1062
+ }
1063
+ ],
1064
+ "startEvent": {"key": "start1", "name": "Start"},
1065
+ "sequenceFlows": [
1066
+ {"key": "flow1", "sourceKey": "start1", "targetKey": "act1"}
1067
+ ]
1068
+ })
1069
+ print(process.to_dict())
1070
+ # Output: Dictionary with process settings
1071
+ Restrictions and Considerations
1072
+ Name is required; avoid special characters.
1073
+
1074
+ Accepts activities, events, and flows as dictionaries.
1075
+
1076
+ Flows must reference valid keys.
1077
+
1078
+ API sets identifiers.
1079
+
1080
+ Ensure valid process structure.
1081
+
1082
+ ArtifactType
1083
+ Purpose
1084
+ Defines task artifacts.
1085
+
1086
+ Usage Examples
1087
+ Via Attributes:
1088
+
1089
+ from pygeai.lab.models import ArtifactType
1090
+
1091
+ artifact = ArtifactType(name="document", usage_type="input")
1092
+ print(artifact.to_dict())
1093
+ # Output: Dictionary with artifact settings
1094
+ Via Dictionary:
1095
+
1096
+ from pygeai.lab.models import ArtifactType
1097
+
1098
+ artifact = ArtifactType(**{
1099
+ "name": "document",
1100
+ "usageType": "input"
1101
+ })
1102
+ print(artifact.to_dict())
1103
+ # Output: Dictionary with artifact settings
1104
+ Restrictions and Considerations
1105
+ Name and usage type are required.
1106
+
1107
+ Usage type is “input” or “output.”
1108
+
1109
+ Dictionaries simplify artifact setup.
1110
+
1111
+ Variable keys have length limits.
1112
+
1113
+ ArtifactTypeList
1114
+ Purpose
1115
+ Manages task artifact types.
1116
+
1117
+ Usage Examples
1118
+ Via Attributes:
1119
+
1120
+ from pygeai.lab.models import ArtifactTypeList, ArtifactType
1121
+
1122
+ artifact = ArtifactType(name="document", usage_type="input")
1123
+ artifact_list = ArtifactTypeList(artifact_types=[artifact])
1124
+ print(artifact_list.to_dict())
1125
+ # Output: List of artifact dictionaries
1126
+ Via Dictionary (with ArtifactTypes as dicts):
1127
+
1128
+ from pygeai.lab.models import ArtifactTypeList
1129
+
1130
+ artifact_list = ArtifactTypeList(**{
1131
+ "artifact_types": [
1132
+ {"name": "document", "usageType": "input"}
1133
+ ]
1134
+ })
1135
+ print(artifact_list.to_dict())
1136
+ # Output: List of artifact dictionaries
1137
+ Restrictions and Considerations
1138
+ Artifact types collection is optional; defaults to empty.
1139
+
1140
+ Accepts artifact types as dictionaries.
1141
+
1142
+ Supports iteration and appending.
1143
+
1144
+ Task
1145
+ Purpose
1146
+ Configures agent tasks.
1147
+
1148
+ Usage Examples
1149
+ Via Attributes:
1150
+
1151
+ from pygeai.lab.models import Task, Prompt, PromptOutput, ArtifactTypeList, ArtifactType
1152
+
1153
+ prompt = Prompt(instructions="Summarize.", inputs=["text"], outputs=[PromptOutput(key="summary", description="Summary.")])
1154
+ artifact = ArtifactType(name="document", usage_type="input")
1155
+ task = Task(name="SummaryTask", prompt_data=prompt, artifact_types=ArtifactTypeList(artifact_types=[artifact]))
1156
+ print(task.to_dict())
1157
+ # Output: Dictionary with task settings
1158
+ Via Dictionary (with Prompt, ArtifactTypes as dicts):
1159
+
1160
+ from pygeai.lab.models import Task
1161
+
1162
+ task = Task(**{
1163
+ "name": "SummaryTask",
1164
+ "promptData": {
1165
+ "instructions": "Summarize.",
1166
+ "inputs": ["text"],
1167
+ "outputs": [{"key": "summary", "description": "Summary."}]
1168
+ },
1169
+ "artifactTypes": [
1170
+ {"name": "document", "usageType": "input"}
1171
+ ]
1172
+ })
1173
+ print(task.to_dict())
1174
+ # Output: Dictionary with task settings
1175
+ Restrictions and Considerations
1176
+ Name is required; avoid special characters.
1177
+
1178
+ Accepts prompt and artifact types as dictionaries.
1179
+
1180
+ Artifact types must use valid usage types.
1181
+
1182
+ Prompt is optional but recommended.
1183
+
1184
+ AgenticProcessList
1185
+ Purpose
1186
+ Manages multiple processes.
1187
+
1188
+ Usage Examples
1189
+ Via Attributes:
1190
+
1191
+ from pygeai.lab.models import AgenticProcessList, AgenticProcess
1192
+
1193
+ process = AgenticProcess(name="Process1")
1194
+ process_list = AgenticProcessList(processes=[process])
1195
+ print(process_list.to_dict())
1196
+ # Output: Dictionary with process list
1197
+ Via Dictionary (with Processes as dicts):
1198
+
1199
+ from pygeai.lab.models import AgenticProcessList
1200
+
1201
+ process_list = AgenticProcessList(**{
1202
+ "processes": [
1203
+ {"name": "Process1"}
1204
+ ]
1205
+ })
1206
+ print(process_list.to_dict())
1207
+ # Output: Dictionary with process list
1208
+ Restrictions and Considerations
1209
+ Processes collection is required; can be empty.
1210
+
1211
+ Accepts processes as dictionaries.
1212
+
1213
+ Supports iteration and appending.
1214
+
1215
+ TaskList
1216
+ Purpose
1217
+ Manages multiple tasks.
1218
+
1219
+ Usage Examples
1220
+ Via Attributes:
1221
+
1222
+ from pygeai.lab.models import TaskList, Task
1223
+
1224
+ task = Task(name="Task1")
1225
+ task_list = TaskList(tasks=[task])
1226
+ print(task_list.to_dict())
1227
+ # Output: List of task dictionaries
1228
+ Via Dictionary (with Tasks as dicts):
1229
+
1230
+ from pygeai.lab.models import TaskList
1231
+
1232
+ task_list = TaskList(**{
1233
+ "tasks": [
1234
+ {"name": "Task1"}
1235
+ ]
1236
+ })
1237
+ print(task_list.to_dict())
1238
+ # Output: List of task dictionaries
1239
+ Restrictions and Considerations
1240
+ Tasks collection is required; can be empty.
1241
+
1242
+ Accepts tasks as dictionaries.
1243
+
1244
+ Supports iteration and appending.
1245
+
1246
+ ProcessInstance
1247
+ Purpose
1248
+ Tracks running process instances.
1249
+
1250
+ Usage Examples
1251
+ Via Attributes:
1252
+
1253
+ from pygeai.lab.models import ProcessInstance, AgenticProcess
1254
+
1255
+ process = AgenticProcess(name="SummaryProcess")
1256
+ instance = ProcessInstance(process=process, subject="Summary")
1257
+ print(instance.to_dict())
1258
+ # Output: Dictionary with instance settings
1259
+ Via Dictionary (with Process as dict):
1260
+
1261
+ from pygeai.lab.models import ProcessInstance
1262
+
1263
+ instance = ProcessInstance(**{
1264
+ "process": {"name": "SummaryProcess"},
1265
+ "subject": "Summary"
1266
+ })
1267
+ print(instance.to_dict())
1268
+ # Output: Dictionary with instance settings
1269
+ Restrictions and Considerations
1270
+ Process and subject are required.
1271
+
1272
+ Accepts process as a dictionary.
1273
+
1274
+ API sets identifiers.
1275
+
1276
+ Align variables with process needs.
1277
+
1278
+ ProcessInstanceList
1279
+ Purpose
1280
+ Manages multiple process instances.
1281
+
1282
+ Usage Examples
1283
+ Via Attributes:
1284
+
1285
+ from pygeai.lab.models import ProcessInstanceList, ProcessInstance, AgenticProcess
1286
+
1287
+ process = AgenticProcess(name="Process1")
1288
+ instance = ProcessInstance(process=process, subject="Instance1")
1289
+ instance_list = ProcessInstanceList(instances=[instance])
1290
+ print(instance_list.to_dict())
1291
+ # Output: List of instance dictionaries
1292
+ Via Dictionary (with Instances as dicts):
1293
+
1294
+ from pygeai.lab.models import ProcessInstanceList
1295
+
1296
+ instance_list = ProcessInstanceList(**{
1297
+ "instances": [
1298
+ {"process": {"name": "Process1"}, "subject": "Instance1"}
1299
+ ]
1300
+ })
1301
+ print(instance_list.to_dict())
1302
+ # Output: List of instance dictionaries
1303
+ Restrictions and Considerations
1304
+ Instances collection is required; can be empty.
1305
+
1306
+ Accepts instances as dictionaries.
1307
+
1308
+ Supports iteration and appending.
1309
+
1310
+ The Lab - Usage
1311
+ The Globant Enterprise AI Lab enables developers to create and manage AI agents, tools, tasks, and processes. The AILabManager class provides a high-level interface for these operations, while low-level clients (AgentClient, ToolClient, AgenticProcessClient) offer direct API access, and the geai ai-lab CLI provides command-line control. This section documents all Lab operations, grouped by resource type (Agents, Tools, Tasks, Processes), with examples for command-line, low-level, and high-level usage.
1312
+
1313
+ Agents
1314
+ Create Agent
1315
+ Creates a new AI agent in a specified project, defining its name, access scope, prompt instructions, LLM settings, and other configurations.
1316
+
1317
+ Command Line
1318
+ geai ai-lab create-agent \
1319
+ --project-id "2ca6883f-6778-40bb-bcc1-85451fb11107" \
1320
+ --name "Public Translator V2" \
1321
+ --access-scope "public" \
1322
+ --public-name "com.genexus.geai.public_translator" \
1323
+ --job-description "Translates" \
1324
+ --avatar-image "https://www.shareicon.net/data/128x128/2016/11/09/851442_logo_512x512.png" \
1325
+ --description "Agent that translates from any language to english." \
1326
+ --agent-data-prompt-instructions "the user will provide a text, you must return the same text translated to english" \
1327
+ --agent-data-prompt-input "text" \
1328
+ --agent-data-prompt-input "avoid slang indicator" \
1329
+ --agent-data-prompt-output '{"key": "translated_text", "description": "translated text, with slang or not depending on the indication. in plain text."}' \
1330
+ --agent-data-prompt-output '{"key": "summary", "description": "a summary in the original language of the text to be translated, also in plain text."}' \
1331
+ --agent-data-prompt-example '{"inputData": "opitiiiis mundo [no-slang]", "output": "{\"translated_text\":\"hello world\",\"Summary\":\"saludo\"}"}' \
1332
+ --agent-data-llm-max-tokens 5000 \
1333
+ --agent-data-llm-timeout 0 \
1334
+ --agent-data-llm-temperature 0.5 \
1335
+ --agent-data-model-name "gpt-4-turbo-preview" \
1336
+ --automatic-publish 0
1337
+ Low-Level Service Layer
1338
+ from pygeai.lab.agents.clients import AgentClient
1339
+
1340
+ client = AgentClient()
1341
+ response = client.create_agent(
1342
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1343
+ name="Public Translator V2",
1344
+ access_scope="public",
1345
+ public_name="com.genexus.geai.public_translator",
1346
+ job_description="Translates",
1347
+ avatar_image="https://www.shareicon.net/data/128x128/2016/11/09/851442_logo_512x512.png",
1348
+ description="Agent that translates from any language to english.",
1349
+ agent_data_prompt={
1350
+ "instructions": "the user will provide a text, you must return the same text translated to english",
1351
+ "inputs": ["text", "avoid slang indicator"],
1352
+ "outputs": [
1353
+ {"key": "translated_text", "description": "translated text, with slang or not depending on the indication. in plain text."},
1354
+ {"key": "summary", "description": "a summary in the original language of the text to be translated, also in plain text."}
1355
+ ],
1356
+ "examples": [
1357
+ {"inputData": "opitiiiis mundo [no-slang]", "output": "{\"translated_text\":\"hello world\",\"Summary\":\"saludo\"}"}
1358
+ ]
1359
+ },
1360
+ agent_data_llm_config={
1361
+ "maxTokens": 5000,
1362
+ "timeout": 0,
1363
+ "temperature": 0.5
1364
+ },
1365
+ agent_data_models=[{"name": "gpt-4-turbo-preview"}],
1366
+ automatic_publish=False
1367
+ )
1368
+ print(response)
1369
+ High-Level Service Layer
1370
+ from pygeai.lab.managers import AILabManager
1371
+ from pygeai.lab.models import Agent, AgentData, Prompt, PromptOutput, PromptExample, LlmConfig, ModelList, Model
1372
+
1373
+ manager = AILabManager()
1374
+
1375
+ prompt = Prompt(
1376
+ instructions="the user will provide a text, you must return the same text translated to english",
1377
+ inputs=["text", "avoid slang indicator"],
1378
+ outputs=[
1379
+ PromptOutput(key="translated_text", description="translated text, with slang or not depending on the indication. in plain text."),
1380
+ PromptOutput(key="summary", description="a summary in the original language of the text to be translated, also in plain text.")
1381
+ ],
1382
+ examples=[
1383
+ PromptExample(input_data="opitiiiis mundo [no-slang]", output="{\"translated_text\":\"hello world\",\"Summary\":\"saludo\"}")
1384
+ ]
1385
+ )
1386
+ llm_config = LlmConfig(max_tokens=5000, timeout=0, temperature=0.5)
1387
+ models = ModelList(models=[Model(name="gpt-4-turbo-preview")])
1388
+ agent_data = AgentData(prompt=prompt, llm_config=llm_config, models=models)
1389
+
1390
+ agent = Agent(
1391
+ name="Public Translator V2",
1392
+ access_scope="public",
1393
+ public_name="com.genexus.geai.public_translator",
1394
+ job_description="Translates",
1395
+ avatar_image="https://www.shareicon.net/data/128x128/2016/11/09/851442_logo_512x512.png",
1396
+ description="Agent that translates from any language to english.",
1397
+ agent_data=agent_data
1398
+ )
1399
+
1400
+ created_agent = manager.create_agent(
1401
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1402
+ agent=agent,
1403
+ automatic_publish=False
1404
+ )
1405
+ print(created_agent)
1406
+ Update Agent
1407
+ Updates an existing agent’s configuration, such as its name, prompt instructions, or LLM settings.
1408
+
1409
+ Command Line
1410
+ geai ai-lab update-agent \
1411
+ --project-id "2ca6883f-6778-40bb-bcc1-85451fb11107" \
1412
+ --agent-id "agent-123" \
1413
+ --name "Public Translator V3" \
1414
+ --description "Updated agent for translations." \
1415
+ --agent-data-prompt-instructions "the user provides text, translate it to English accurately" \
1416
+ --agent-data-llm-temperature 0.7 \
1417
+ --automatic-publish 0
1418
+ Low-Level Service Layer
1419
+ from pygeai.lab.agents.clients import AgentClient
1420
+
1421
+ client = AgentClient()
1422
+ response = client.update_agent(
1423
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1424
+ agent_id="agent-123",
1425
+ name="Public Translator V3",
1426
+ description="Updated agent for translations.",
1427
+ agent_data_prompt={
1428
+ "instructions": "the user provides text, translate it to English accurately"
1429
+ },
1430
+ agent_data_llm_config={
1431
+ "temperature": 0.7
1432
+ },
1433
+ automatic_publish=False
1434
+ )
1435
+ print(response)
1436
+ High-Level Service Layer
1437
+ from pygeai.lab.managers import AILabManager
1438
+ from pygeai.lab.models import Agent, AgentData, Prompt, LlmConfig
1439
+
1440
+ manager = AILabManager()
1441
+
1442
+ agent = Agent(
1443
+ name="Public Translator V3",
1444
+ description="Updated agent for translations.",
1445
+ agent_data=AgentData(
1446
+ prompt=Prompt(instructions="the user provides text, translate it to English accurately"),
1447
+ llm_config=LlmConfig(temperature=0.7)
1448
+ )
1449
+ )
1450
+
1451
+ updated_agent = manager.update_agent(
1452
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1453
+ agent_id="agent-123",
1454
+ agent=agent,
1455
+ automatic_publish=False
1456
+ )
1457
+ print(updated_agent)
1458
+ List Agents
1459
+ Retrieves a list of agents in a specified project, with optional filters for status, pagination, scope, and draft inclusion.
1460
+
1461
+ Command Line
1462
+ geai ai-lab list-agents \
1463
+ --project-id "2ca6883f-6778-40bb-bcc1-85451fb11107" \
1464
+ --status "active" \
1465
+ --allow-drafts 0 \
1466
+ --allow-external 1
1467
+ Low-Level Service Layer
1468
+ from pygeai.lab.agents.clients import AgentClient
1469
+
1470
+ client = AgentClient()
1471
+ response = client.list_agents(
1472
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1473
+ status="active",
1474
+ allow_drafts=False,
1475
+ allow_external=True
1476
+ )
1477
+ print(response)
1478
+ High-Level Service Layer
1479
+ from pygeai.lab.managers import AILabManager
1480
+ from pygeai.lab.models import FilterSettings
1481
+
1482
+ manager = AILabManager()
1483
+
1484
+ filters = FilterSettings(
1485
+ status="active",
1486
+ allow_drafts=False,
1487
+ allow_external=True
1488
+ )
1489
+ agent_list = manager.get_agent_list(
1490
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1491
+ filter_settings=filters
1492
+ )
1493
+ print(agent_list)
1494
+ Delete Agent
1495
+ Deletes an agent from a specified project by its ID.
1496
+
1497
+ Command Line
1498
+ geai ai-lab delete-agent \
1499
+ --project-id "2ca6883f-6778-40bb-bcc1-85451fb11107" \
1500
+ --agent-id "agent-123"
1501
+ Low-Level Service Layer
1502
+ from pygeai.lab.agents.clients import AgentClient
1503
+
1504
+ client = AgentClient()
1505
+ response = client.delete_agent(
1506
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1507
+ agent_id="agent-123"
1508
+ )
1509
+ print(response)
1510
+ High-Level Service Layer
1511
+ from pygeai.lab.managers import AILabManager
1512
+
1513
+ manager = AILabManager()
1514
+ response = manager.delete_agent(
1515
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1516
+ agent_id="agent-123"
1517
+ )
1518
+ print(response)
1519
+ Publish Agent Revision
1520
+ Publishes a revision of an agent, making it available for use.
1521
+
1522
+ Command Line
1523
+ geai ai-lab publish-agent-revision \
1524
+ --project-id "2ca6883f-6778-40bb-bcc1-85451fb11107" \
1525
+ --agent-id "agent-123"
1526
+ Low-Level Service Layer
1527
+ from pygeai.lab.agents.clients import AgentClient
1528
+
1529
+ client = AgentClient()
1530
+ response = client.publish_agent_revision(
1531
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1532
+ agent_id="agent-123"
1533
+ )
1534
+ print(response)
1535
+ High-Level Service Layer
1536
+ from pygeai.lab.managers import AILabManager
1537
+
1538
+ manager = AILabManager()
1539
+ response = manager.publish_agent_revision(
1540
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1541
+ agent_id="agent-123"
1542
+ )
1543
+ print(response)
1544
+ Tools
1545
+ Create Tool
1546
+ Creates a new tool in a specified project, defining its name, description, scope, and parameters for agent use.
1547
+
1548
+ Command Line
1549
+ geai ai-lab create-tool \
1550
+ --project-id "2ca6883f-6778-40bb-bcc1-85451fb11107" \
1551
+ --name "sample tool V3" \
1552
+ --description "a builtin tool that does something but really does nothing cos it does not exist." \
1553
+ --scope "builtin" \
1554
+ --parameter '{"key": "input", "dataType": "String", "description": "some input that the tool needs.", "isRequired": true}' \
1555
+ --parameter '{"key": "some_nonsensitive_id", "dataType": "String", "description": "Configuration that is static, in the sense that whenever the tool is used, the value for this parameter is configured here. The llm will not know about it.", "isRequired": true, "type": "config", "fromSecret": false, "value": "b001e30b4016001f5f76b9ae9215ac40"}' \
1556
+ --automatic-publish 0
1557
+ Low-Level Service Layer
1558
+ from pygeai.lab.tools.clients import ToolClient
1559
+
1560
+ client = ToolClient()
1561
+ response = client.create_tool(
1562
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1563
+ name="sample tool V3",
1564
+ description="a builtin tool that does something but really does nothing cos it does not exist.",
1565
+ scope="builtin",
1566
+ parameters=[
1567
+ {"key": "input", "dataType": "String", "description": "some input that the tool needs.", "isRequired": True},
1568
+ {"key": "some_nonsensitive_id", "dataType": "String", "description": "Configuration that is static, in the sense that whenever the tool is used, the value for this parameter is configured here. The llm will not know about it.", "isRequired": True, "type": "config", "fromSecret": False, "value": "b001e30b4016001f5f76b9ae9215ac40"}
1569
+ ],
1570
+ automatic_publish=False
1571
+ )
1572
+ print(response)
1573
+ High-Level Service Layer
1574
+ from pygeai.lab.managers import AILabManager
1575
+ from pygeai.lab.models import Tool, ToolParameter
1576
+
1577
+ manager = AILabManager()
1578
+
1579
+ tool = Tool(
1580
+ name="sample tool V3",
1581
+ description="a builtin tool that does something but really does nothing cos it does not exist.",
1582
+ scope="builtin",
1583
+ parameters=[
1584
+ ToolParameter(
1585
+ key="input",
1586
+ data_type="String",
1587
+ description="some input that the tool needs.",
1588
+ is_required=True
1589
+ ),
1590
+ ToolParameter(
1591
+ key="some_nonsensitive_id",
1592
+ data_type="String",
1593
+ description="Configuration that is static, in the sense that whenever the tool is used, the value for this parameter is configured here. The llm will not know about it.",
1594
+ is_required=True,
1595
+ type="config",
1596
+ from_secret=False,
1597
+ value="b001e30b4016001f5f76b9ae9215ac40"
1598
+ )
1599
+ ]
1600
+ )
1601
+
1602
+ created_tool = manager.create_tool(
1603
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1604
+ tool=tool,
1605
+ automatic_publish=False
1606
+ )
1607
+ print(created_tool)
1608
+ Update Tool
1609
+ Updates an existing tool’s configuration, such as its name, description, or parameters.
1610
+
1611
+ Command Line
1612
+ geai ai-lab update-tool \
1613
+ --project-id "2ca6883f-6778-40bb-bcc1-85451fb11107" \
1614
+ --tool-id "tool-456" \
1615
+ --name "sample tool V4" \
1616
+ --description "Updated builtin tool." \
1617
+ --scope "builtin" \
1618
+ --parameter '{"key": "input", "dataType": "String", "description": "updated input.", "isRequired": true}' \
1619
+ --automatic-publish 0
1620
+ Low-Level Service Layer
1621
+ from pygeai.lab.tools.clients import ToolClient
1622
+
1623
+ client = ToolClient()
1624
+ response = client.update_tool(
1625
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1626
+ tool_id="tool-456",
1627
+ name="sample tool V4",
1628
+ description="Updated builtin tool.",
1629
+ scope="builtin",
1630
+ parameters=[
1631
+ {"key": "input", "dataType": "String", "description": "updated input.", "isRequired": True}
1632
+ ],
1633
+ automatic_publish=False
1634
+ )
1635
+ print(response)
1636
+ High-Level Service Layer
1637
+ from pygeai.lab.managers import AILabManager
1638
+ from pygeai.lab.models import Tool, ToolParameter
1639
+
1640
+ manager = AILabManager()
1641
+
1642
+ tool = Tool(
1643
+ name="sample tool V4",
1644
+ description="Updated builtin tool.",
1645
+ scope="builtin",
1646
+ parameters=[
1647
+ ToolParameter(
1648
+ key="input",
1649
+ data_type="String",
1650
+ description="updated input.",
1651
+ is_required=True
1652
+ )
1653
+ ]
1654
+ )
1655
+
1656
+ updated_tool = manager.update_tool(
1657
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1658
+ tool_id="tool-456",
1659
+ tool=tool,
1660
+ automatic_publish=False
1661
+ )
1662
+ print(updated_tool)
1663
+ Delete Tool
1664
+ Deletes a tool from a specified project by its ID.
1665
+
1666
+ Command Line
1667
+ geai ai-lab delete-tool \
1668
+ --project-id "2ca6883f-6778-40bb-bcc1-85451fb11107" \
1669
+ --tool-id "tool-456"
1670
+ Low-Level Service Layer
1671
+ from pygeai.lab.tools.clients import ToolClient
1672
+
1673
+ client = ToolClient()
1674
+ response = client.delete_tool(
1675
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1676
+ tool_id="tool-456"
1677
+ )
1678
+ print(response)
1679
+ High-Level Service Layer
1680
+ from pygeai.lab.managers import AILabManager
1681
+
1682
+ manager = AILabManager()
1683
+ response = manager.delete_tool(
1684
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1685
+ tool_id="tool-456"
1686
+ )
1687
+ print(response)
1688
+ Publish Tool Revision
1689
+ Publishes a revision of a tool, making it available for use.
1690
+
1691
+ Command Line
1692
+ geai ai-lab publish-tool-revision \
1693
+ --project-id "2ca6883f-6778-40bb-bcc1-85451fb11107" \
1694
+ --tool-id "tool-456"
1695
+ Low-Level Service Layer
1696
+ from pygeai.lab.tools.clients import ToolClient
1697
+
1698
+ client = ToolClient()
1699
+ response = client.publish_tool_revision(
1700
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1701
+ tool_id="tool-456"
1702
+ )
1703
+ print(response)
1704
+ High-Level Service Layer
1705
+ from pygeai.lab.managers import AILabManager
1706
+
1707
+ manager = AILabManager()
1708
+ response = manager.publish_tool_revision(
1709
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1710
+ tool_id="tool-456"
1711
+ )
1712
+ print(response)
1713
+ Tasks
1714
+ Create Task
1715
+ Creates a new task in a specified project, defining its name, description, prompt configuration, and artifact types.
1716
+
1717
+ Command Line
1718
+ geai ai-lab create-task \
1719
+ --project-id "2ca6883f-6778-40bb-bcc1-85451fb11107" \
1720
+ --name "Sample v2" \
1721
+ --description "A simple task that requires no tools and define no prompt" \
1722
+ --title-template "Sample Task" \
1723
+ --automatic-publish 0
1724
+ Low-Level Service Layer
1725
+ from pygeai.lab.processes.clients import AgenticProcessClient
1726
+
1727
+ client = AgenticProcessClient()
1728
+ response = client.create_task(
1729
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1730
+ name="Sample v2",
1731
+ description="A simple task that requires no tools and define no prompt",
1732
+ title_template="Sample Task",
1733
+ prompt_data={},
1734
+ artifact_types=[],
1735
+ automatic_publish=False
1736
+ )
1737
+ print(response)
1738
+ High-Level Service Layer
1739
+ from pygeai.lab.managers import AILabManager
1740
+ from pygeai.lab.models import Task, Prompt, ArtifactTypeList
1741
+
1742
+ manager = AILabManager()
1743
+
1744
+ task = Task(
1745
+ name="Sample v2",
1746
+ description="A simple task that requires no tools and define no prompt",
1747
+ title_template="Sample Task",
1748
+ prompt_data=Prompt(),
1749
+ artifact_types=ArtifactTypeList(artifact_types=[])
1750
+ )
1751
+
1752
+ created_task = manager.create_task(
1753
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1754
+ task=task,
1755
+ automatic_publish=False
1756
+ )
1757
+ print(created_task)
1758
+ Update Task
1759
+ Updates an existing task’s configuration, such as its name, description, or prompt settings.
1760
+
1761
+ Command Line
1762
+ geai ai-lab update-task \
1763
+ --project-id "2ca6883f-6778-40bb-bcc1-85451fb11107" \
1764
+ --task-id "task-789" \
1765
+ --name "Sample v3" \
1766
+ --description "Updated simple task." \
1767
+ --title-template "Updated Sample Task" \
1768
+ --automatic-publish 0
1769
+ Low-Level Service Layer
1770
+ from pygeai.lab.processes.clients import AgenticProcessClient
1771
+
1772
+ client = AgenticProcessClient()
1773
+ response = client.update_task(
1774
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1775
+ task_id="task-789",
1776
+ name="Sample v3",
1777
+ description="Updated simple task.",
1778
+ title_template="Updated Sample Task",
1779
+ prompt_data={},
1780
+ artifact_types=[],
1781
+ automatic_publish=False
1782
+ )
1783
+ print(response)
1784
+ High-Level Service Layer
1785
+ from pygeai.lab.managers import AILabManager
1786
+ from pygeai.lab.models import Task, Prompt, ArtifactTypeList
1787
+
1788
+ manager = AILabManager()
1789
+
1790
+ task = Task(
1791
+ name="Sample v3",
1792
+ description="Updated simple task.",
1793
+ title_template="Updated Sample Task",
1794
+ prompt_data=Prompt(),
1795
+ artifact_types=ArtifactTypeList(artifact_types=[])
1796
+ )
1797
+
1798
+ updated_task = manager.update_task(
1799
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1800
+ task_id="task-789",
1801
+ task=task,
1802
+ automatic_publish=False
1803
+ )
1804
+ print(updated_task)
1805
+ Delete Task
1806
+ Deletes a task from a specified project by its ID.
1807
+
1808
+ Command Line
1809
+ geai ai-lab delete-task \
1810
+ --project-id "2ca6883f-6778-40bb-bcc1-85451fb11107" \
1811
+ --task-id "task-789"
1812
+ Low-Level Service Layer
1813
+ from pygeai.lab.processes.clients import AgenticProcessClient
1814
+
1815
+ client = AgenticProcessClient()
1816
+ response = client.delete_task(
1817
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1818
+ task_id="task-789"
1819
+ )
1820
+ print(response)
1821
+ High-Level Service Layer
1822
+ from pygeai.lab.managers import AILabManager
1823
+
1824
+ manager = AILabManager()
1825
+ response = manager.delete_task(
1826
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1827
+ task_id="task-789"
1828
+ )
1829
+ print(response)
1830
+ Publish Task Revision
1831
+ Publishes a revision of a task, making it available for use.
1832
+
1833
+ Command Line
1834
+ geai ai-lab publish-task-revision \
1835
+ --project-id "2ca6883f-6778-40bb-bcc1-85451fb11107" \
1836
+ --task-id "task-789"
1837
+ Low-Level Service Layer
1838
+ from pygeai.lab.processes.clients import AgenticProcessClient
1839
+
1840
+ client = AgenticProcessClient()
1841
+ response = client.publish_task_revision(
1842
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1843
+ task_id="task-789"
1844
+ )
1845
+ print(response)
1846
+ High-Level Service Layer
1847
+ from pygeai.lab.managers import AILabManager
1848
+
1849
+ manager = AILabManager()
1850
+ response = manager.publish_task_revision(
1851
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1852
+ task_id="task-789"
1853
+ )
1854
+ print(response)
1855
+ Processes
1856
+ Create Process
1857
+ Creates a new agentic process in a specified project, defining its workflow with activities, signals, events, and sequence flows.
1858
+
1859
+ Command Line
1860
+ geai ai-lab create-process \
1861
+ --project-id "2ca6883f-6778-40bb-bcc1-85451fb11107" \
1862
+ --key "product_def" \
1863
+ --name "Basic Process V4" \
1864
+ --description "This is a sample process" \
1865
+ --kb '{"name": "basic-sample", "artifactTypeName": ["sample-artifact"]}' \
1866
+ --agentic-activity '{"key": "activityOne", "name": "First Step", "taskName": "basic-task", "agentName": "sample-translator", "agentRevisionId": 0}' \
1867
+ --artifact-signal '{"key": "artifact.upload.1", "name": "artifact.upload", "handlingType": "C", "artifactTypeName": ["sample-artifact"]}' \
1868
+ --user-signal '{"key": "signal_done", "name": "process-completed"}' \
1869
+ --start-event '{"key": "artifact.upload.1", "name": "artifact.upload"}' \
1870
+ --end-event '{"key": "end", "name": "Done"}' \
1871
+ --sequence-flow '{"key": "step1", "sourceKey": "artifact.upload.1", "targetKey": "activityOne"}' \
1872
+ --sequence-flow '{"key": "step2", "sourceKey": "activityOne", "targetKey": "signal_done"}' \
1873
+ --sequence-flow '{"key": "stepEnd", "sourceKey": "signal_done", "targetKey": "end"}' \
1874
+ --automatic-publish 0
1875
+ Low-Level Service Layer
1876
+ from pygeai.lab.processes.clients import AgenticProcessClient
1877
+
1878
+ client = AgenticProcessClient()
1879
+ response = client.create_process(
1880
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1881
+ key="product_def",
1882
+ name="Basic Process V4",
1883
+ description="This is a sample process",
1884
+ kb={"name": "basic-sample", "artifactTypeName": ["sample-artifact"]},
1885
+ agentic_activities=[
1886
+ {"key": "activityOne", "name": "First Step", "taskName": "basic-task", "agentName": "sample-translator", "agentRevisionId": 0}
1887
+ ],
1888
+ artifact_signals=[
1889
+ {"key": "artifact.upload.1", "name": "artifact.upload", "handlingType": "C", "artifactTypeName": ["sample-artifact"]}
1890
+ ],
1891
+ user_signals=[
1892
+ {"key": "signal_done", "name": "process-completed"}
1893
+ ],
1894
+ start_event={"key": "artifact.upload.1", "name": "artifact.upload"},
1895
+ end_event={"key": "end", "name": "Done"},
1896
+ sequence_flows=[
1897
+ {"key": "step1", "sourceKey": "artifact.upload.1", "targetKey": "activityOne"},
1898
+ {"key": "step2", "sourceKey": "activityOne", "targetKey": "signal_done"},
1899
+ {"key": "stepEnd", "sourceKey": "signal_done", "targetKey": "end"}
1900
+ ],
1901
+ automatic_publish=False
1902
+ )
1903
+ print(response)
1904
+ High-Level Service Layer
1905
+ from pygeai.lab.managers import AILabManager
1906
+ from pygeai.lab.models import AgenticProcess, KnowledgeBase, AgenticActivity, ArtifactSignal, UserSignal, Event, SequenceFlow
1907
+
1908
+ manager = AILabManager()
1909
+
1910
+ process = AgenticProcess(
1911
+ key="product_def",
1912
+ name="Basic Process V4",
1913
+ description="This is a sample process",
1914
+ kb=KnowledgeBase(name="basic-sample", artifact_type_name=["sample-artifact"]),
1915
+ agentic_activities=[
1916
+ AgenticActivity(
1917
+ key="activityOne",
1918
+ name="First Step",
1919
+ task_name="basic-task",
1920
+ agent_name="sample-translator",
1921
+ agent_revision_id=0
1922
+ )
1923
+ ],
1924
+ artifact_signals=[
1925
+ ArtifactSignal(
1926
+ key="artifact.upload.1",
1927
+ name="artifact.upload",
1928
+ handling_type="C",
1929
+ artifact_type_name=["sample-artifact"]
1930
+ )
1931
+ ],
1932
+ user_signals=[
1933
+ UserSignal(key="signal_done", name="process-completed")
1934
+ ],
1935
+ start_event=Event(key="artifact.upload.1", name="artifact.upload"),
1936
+ end_event=Event(key="end", name="Done"),
1937
+ sequence_flows=[
1938
+ SequenceFlow(key="step1", source_key="artifact.upload.1", target_key="activityOne"),
1939
+ SequenceFlow(key="step2", source_key="activityOne", target_key="signal_done"),
1940
+ SequenceFlow(key="stepEnd", source_key="signal_done", target_key="end")
1941
+ ]
1942
+ )
1943
+
1944
+ created_process = manager.create_process(
1945
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1946
+ process=process,
1947
+ automatic_publish=False
1948
+ )
1949
+ print(created_process)
1950
+ Update Process
1951
+ Updates an existing process’s configuration, such as its name, description, or workflow components.
1952
+
1953
+ Command Line
1954
+ geai ai-lab update-process \
1955
+ --project-id "2ca6883f-6778-40bb-bcc1-85451fb11107" \
1956
+ --process-id "process-101" \
1957
+ --key "product_def" \
1958
+ --name "Basic Process V5" \
1959
+ --description "Updated sample process" \
1960
+ --kb '{"name": "basic-sample", "artifactTypeName": ["sample-artifact"]}' \
1961
+ --automatic-publish 0
1962
+ Low-Level Service Layer
1963
+ from pygeai.lab.processes.clients import AgenticProcessClient
1964
+
1965
+ client = AgenticProcessClient()
1966
+ response = client.update_process(
1967
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1968
+ process_id="process-101",
1969
+ key="product_def",
1970
+ name="Basic Process V5",
1971
+ description="Updated sample process",
1972
+ kb={"name": "basic-sample", "artifactTypeName": ["sample-artifact"]},
1973
+ agentic_activities=[],
1974
+ artifact_signals=[],
1975
+ user_signals=[],
1976
+ start_event={},
1977
+ end_event={},
1978
+ sequence_flows=[],
1979
+ automatic_publish=False
1980
+ )
1981
+ print(response)
1982
+ High-Level Service Layer
1983
+ from pygeai.lab.managers import AILabManager
1984
+ from pygeai.lab.models import AgenticProcess, KnowledgeBase
1985
+
1986
+ manager = AILabManager()
1987
+
1988
+ process = AgenticProcess(
1989
+ key="product_def",
1990
+ name="Basic Process V5",
1991
+ description="Updated sample process",
1992
+ kb=KnowledgeBase(name="basic-sample", artifact_type_name=["sample-artifact"])
1993
+ )
1994
+
1995
+ updated_process = manager.update_process(
1996
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
1997
+ process_id="process-101",
1998
+ process=process,
1999
+ automatic_publish=False
2000
+ )
2001
+ print(updated_process)
2002
+ Delete Process
2003
+ Deletes a process from a specified project by its ID.
2004
+
2005
+ Command Line
2006
+ geai ai-lab delete-process \
2007
+ --project-id "2ca6883f-6778-40bb-bcc1-85451fb11107" \
2008
+ --process-id "process-101"
2009
+ Low-Level Service Layer
2010
+ from pygeai.lab.processes.clients import AgenticProcessClient
2011
+
2012
+ client = AgenticProcessClient()
2013
+ response = client.delete_process(
2014
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
2015
+ process_id="process-101"
2016
+ )
2017
+ print(response)
2018
+ High-Level Service Layer
2019
+ from pygeai.lab.managers import AILabManager
2020
+
2021
+ manager = AILabManager()
2022
+ response = manager.delete_process(
2023
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
2024
+ process_id="process-101"
2025
+ )
2026
+ print(response)
2027
+ Publish Process Revision
2028
+ Publishes a revision of a process, making it available for use.
2029
+
2030
+ Command Line
2031
+ geai ai-lab publish-process-revision \
2032
+ --project-id "2ca6883f-6778-40bb-bcc1-85451fb11107" \
2033
+ --process-id "process-101"
2034
+ Low-Level Service Layer
2035
+ from pygeai.lab.processes.clients import AgenticProcessClient
2036
+
2037
+ client = AgenticProcessClient()
2038
+ response = client.publish_process_revision(
2039
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
2040
+ process_id="process-101"
2041
+ )
2042
+ print(response)
2043
+ High-Level Service Layer
2044
+ from pygeai.lab.managers import AILabManager
2045
+
2046
+ manager = AILabManager()
2047
+ response = manager.publish_process_revision(
2048
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
2049
+ process_id="process-101"
2050
+ )
2051
+ print(response)
2052
+
2053
+ Working with the GEAI Lab using the CLI
2054
+ The geai ai-lab command-line interface (CLI) allows users to interact with the Globant Enterprise AI (GEAI) Lab to manage agents, tools, reasoning strategies, processes, tasks, and process instances. This guide provides step-by-step instructions for performing common operations using CLI commands.
2055
+
2056
+ Table of Contents
2057
+
2058
+ Prerequisites
2059
+
2060
+ Managing Agents
2061
+
2062
+ Managing Tools
2063
+
2064
+ Managing Reasoning Strategies
2065
+
2066
+ Managing Processes
2067
+
2068
+ Managing Tasks
2069
+
2070
+ Managing Process Instances
2071
+
2072
+ Complete Example Workflow
2073
+
2074
+ Prerequisites
2075
+ CLI Installation: Ensure the geai CLI is installed. Contact your GEAI administrator for installation instructions.
2076
+
2077
+ Authentication: Obtain your project ID and API token from the GEAI platform.
2078
+
2079
+ Environment: A terminal with access to the geai command, typically on Linux, macOS, or Windows (via WSL or similar).
2080
+
2081
+ Set the project ID as an environment variable for convenience:
2082
+
2083
+ export PROJECT_ID="2ca6883f-6778-40bb-bcc1-85451fb11107"
2084
+ Managing Agents
2085
+ Agents are AI entities that perform tasks based on prompts and LLM configurations.
2086
+
2087
+ ### List Agents
2088
+
2089
+ Retrieve a list of agents with filtering options.
2090
+
2091
+ geai ai-lab list-agents \
2092
+ --project-id "$PROJECT_ID" \
2093
+ --status "active" \
2094
+ --access-scope "public" \
2095
+ --allow-drafts 0 \
2096
+ --allow-external 1
2097
+ Example Output:
2098
+
2099
+ - Name: Public Translator V2, ID: f2a160ed-67b3-481d-a822-778cd520f499, Status: active
2100
+ - Name: Jarvis, ID: f9a744ed-84c0-4afa-bee6-c679320a996d, Status: active
2101
+ ### Create a Public Agent
2102
+
2103
+ Create a public agent with detailed configurations.
2104
+
2105
+ geai ai-lab create-agent \
2106
+ --project-id "$PROJECT_ID" \
2107
+ --name "Public Translator V2" \
2108
+ --access-scope "public" \
2109
+ --public-name "com.genexus.geai.public_translator" \
2110
+ --job-description "Translates" \
2111
+ --avatar-image "https://www.shareicon.net/data/128x128/2016/11/09/851442_logo_512x512.png" \
2112
+ --description "Agent that translates from any language to English." \
2113
+ --agent-data-prompt-instructions "the user will provide a text, you must return the same text translated to English" \
2114
+ --agent-data-prompt-input "text" \
2115
+ --agent-data-prompt-input "avoid slang indicator" \
2116
+ --agent-data-prompt-output '{"key": "translated_text", "description": "translated text, with slang or not depending on the indication. in plain text."}' \
2117
+ --agent-data-prompt-output '{"key": "summary", "description": "a summary in the original language of the text to be translated, also in plain text."}' \
2118
+ --agent-data-prompt-example '{"inputData": "opitiiiis mundo [no-slang]", "output": "{\"translated_text\":\"hello world\",\"summary\":\"saludo\"}"}' \
2119
+ --agent-data-prompt-example '{"inputData": "esto es una prueba pincheguey [keep-slang]", "output": "{\"translated_text\":\"this is a test pal\",\"summary\":\"prueba\"}"}' \
2120
+ --agent-data-llm-max-tokens 5000 \
2121
+ --agent-data-llm-timeout 0 \
2122
+ --agent-data-llm-temperature 0.5 \
2123
+ --agent-data-llm-top-k 0 \
2124
+ --agent-data-llm-top-p 0 \
2125
+ --agent-data-model-name "gpt-4-turbo-preview" \
2126
+ --automatic-publish 0
2127
+ ### Create a Private Agent
2128
+
2129
+ Create a private agent with automatic publication.
2130
+
2131
+ geai ai-lab create-agent \
2132
+ --project-id "$PROJECT_ID" \
2133
+ --name "Private Translator V4" \
2134
+ --access-scope "private" \
2135
+ --public-name "com.genexus.geai.private_translatorv4" \
2136
+ --job-description "Text Translation Service" \
2137
+ --avatar-image "https://www.shareicon.net/data/128x128/2016/11/09/851443_logo_512x512.png" \
2138
+ --description "Agent that translates text from any language to English for private use." \
2139
+ --agent-data-prompt-instructions "The user provides a text; return it translated to English based on slang preference." \
2140
+ --agent-data-prompt-input "text" \
2141
+ --agent-data-prompt-input "slang preference (optional)" \
2142
+ --agent-data-prompt-output '{"key": "translated_text", "description": "translated text to English, with or without slang based on preference, in plain text."}' \
2143
+ --agent-data-prompt-output '{"key": "summary", "description": "a short summary in the original language of the input text, in plain text."}' \
2144
+ --agent-data-prompt-example '{"inputData": "hola amigos [no-slang]", "output": "{\"translated_text\":\"hello friends\",\"summary\":\"saludo\"}"}' \
2145
+ --agent-data-prompt-example '{"inputData": "qué onda carnal [keep-slang]", "output": "{\"translated_text\":\"what’s up bro\",\"summary\":\"saludo informal\"}"}' \
2146
+ --agent-data-llm-max-tokens 6000 \
2147
+ --agent-data-llm-timeout 0 \
2148
+ --agent-data-llm-temperature 0.7 \
2149
+ --agent-data-llm-top-k 0 \
2150
+ --agent-data-llm-top-p 0 \
2151
+ --agent-data-model-name "gpt-4o" \
2152
+ --automatic-publish 1
2153
+ ### Get Agent Information
2154
+
2155
+ Retrieve details for a specific agent.
2156
+
2157
+ geai ai-lab get-agent \
2158
+ --project-id "$PROJECT_ID" \
2159
+ --agent-id "f2a160ed-67b3-481d-a822-778cd520f499"
2160
+ Example Output:
2161
+
2162
+ Name: Public Translator V2
2163
+ ID: f2a160ed-67b3-481d-a822-778cd520f499
2164
+ Description: Agent that translates from any language to English.
2165
+ Access Scope: public
2166
+ ### Update an Agent
2167
+
2168
+ Update an existing agent’s properties.
2169
+
2170
+ geai ai-lab update-agent \
2171
+ --project-id "$PROJECT_ID" \
2172
+ --agent-id "f64ba214-152b-4dd4-be0d-2920da415f5d" \
2173
+ --name "Private Translator V4" \
2174
+ --access-scope "private" \
2175
+ --public-name "com.genexus.geai.private_translatorv4" \
2176
+ --job-description "Enhanced Text Translation Service" \
2177
+ --avatar-image "https://www.shareicon.net/data/128x128/2016/11/09/851443_logo_512x512.png" \
2178
+ --description "Updated agent that translates text from any language to English for private use with improved accuracy." \
2179
+ --agent-data-prompt-instructions "The user provides a text; return it translated to English based on slang preference, ensuring natural phrasing." \
2180
+ --agent-data-prompt-input "text" \
2181
+ --agent-data-prompt-input "slang preference (optional)" \
2182
+ --agent-data-prompt-output '{"key": "translated_text", "description": "translated text to English, with or without slang based on preference, in plain text."}' \
2183
+ --agent-data-prompt-output '{"key": "summary", "description": "a concise summary in the original language of the input text, in plain text."}' \
2184
+ --agent-data-prompt-example '{"inputData": "hola amigos [no-slang]", "output": "{\"translated_text\":\"hello friends\",\"summary\":\"saludo\"}"}' \
2185
+ --agent-data-prompt-example '{"inputData": "qué pasa compa [keep-slang]", "output": "{\"translated_text\":\"what’s good buddy\",\"summary\":\"saludo informal\"}"}' \
2186
+ --agent-data-llm-max-tokens 6500 \
2187
+ --agent-data-llm-timeout 0 \
2188
+ --agent-data-llm-temperature 0.8 \
2189
+ --agent-data-llm-top-k 0 \
2190
+ --agent-data-llm-top-p 0 \
2191
+ --agent-data-model-name "gpt-4o" \
2192
+ --automatic-publish 1 \
2193
+ --upsert 0
2194
+ ### Create a Sharing Link
2195
+
2196
+ Generate a sharing link for an agent.
2197
+
2198
+ geai ai-lab create-sharing-link \
2199
+ --project-id "$PROJECT_ID" \
2200
+ --agent-id "9716a0a1-5eab-4cc9-a611-fa2c3237c511"
2201
+ Example Output:
2202
+
2203
+ Shared Link: https://geai.example.com/share/9716a0a1-5eab-4cc9-a611-fa2c3237c511
2204
+ ### Delete an Agent
2205
+
2206
+ Remove an agent from the project.
2207
+
2208
+ geai ai-lab delete-agent \
2209
+ --project-id "$PROJECT_ID" \
2210
+ --agent-id "db43884b-4e6c-4fa5-ad28-952d4eaeffc2"
2211
+ Managing Tools
2212
+ Tools extend agent capabilities with external APIs or built-in functions.
2213
+
2214
+ ### List Tools
2215
+
2216
+ Retrieve a list of tools with filtering options.
2217
+
2218
+ geai ai-lab list-tools \
2219
+ --project-id "$PROJECT_ID" \
2220
+ --access-scope "public" \
2221
+ --scope "api" \
2222
+ --count "100" \
2223
+ --allow-drafts 1 \
2224
+ --allow-external 1
2225
+ Example Output:
2226
+
2227
+ - Name: gdrive_create_docs_post, ID: 04f217f0-3797-4848-afd9-823108553576
2228
+ - Name: create_image_post, ID: 0a29f983-536f-4065-862b-3d46edaf9181
2229
+ ### Create a Tool
2230
+
2231
+ Create a built-in tool with parameters.
2232
+
2233
+ geai ai-lab create-tool \
2234
+ --project-id "$PROJECT_ID" \
2235
+ --name "sample tool V3" \
2236
+ --description "A builtin tool that does something but really does nothing." \
2237
+ --scope "builtin" \
2238
+ --parameter '{"key": "input", "dataType": "String", "description": "some input that the tool needs.", "isRequired": true}' \
2239
+ --parameter '{"key": "some_nonsensitive_id", "dataType": "String", "description": "Configuration that is static.", "isRequired": true, "type": "config", "fromSecret": false, "value": "b001e30b4016001f5f76b9ae9215ac40"}' \
2240
+ --parameter '{"key": "api_token", "dataType": "String", "description": "Configuration that is sensitive.", "isRequired": true, "type": "config", "fromSecret": true, "value": "0cd84dc7-f3f5-4a03-9288-cdfd8d72fde1"}' \
2241
+ --automatic-publish 0
2242
+ ### Get Tool Information
2243
+
2244
+ Retrieve details for a specific tool.
2245
+
2246
+ geai ai-lab get-tool \
2247
+ --project-id "$PROJECT_ID" \
2248
+ --tool-id "04f217f0-3797-4848-afd9-823108553576"
2249
+ Example Output:
2250
+
2251
+ Name: gdrive_create_docs_post
2252
+ ID: 04f217f0-3797-4848-afd9-823108553576
2253
+ Description: Create a new Google Docs document.
2254
+ ### Update a Tool
2255
+
2256
+ Update an API-based tool with OpenAPI specification.
2257
+
2258
+ geai ai-lab update-tool \
2259
+ --project-id "$PROJECT_ID" \
2260
+ --tool-id "04f217f0-3797-4848-afd9-823108553576" \
2261
+ --name "saia_models_get" \
2262
+ --description "Get all LLM models" \
2263
+ --scope "api" \
2264
+ --parameter '{"key": "Authorization", "dataType": "String", "description": "token with which you are going to connect to SAIA", "isRequired": true, "type": "config", "fromSecret": false, "value": "Bearer default_thRMVCZCV5i1-dI0s-1FR76RbjfFBCWRZbTA4PyL1FWI7h108OVg8i2a2Flf8esvlkqpgCz2pRND3cPVMqPUg9eiHyJZcg--gARu1ACSQrLfFagvQV1DUs7vImZFdERFbyyf567t867PzlkBM9k7lhiT_KNtJZKdxB8KHmKbtR8="}' \
2265
+ --open-api-json '{"openapi": "3.0.0", "info": {"title": "LLM Providers API", "version": "2.0.0", "description": "API to retrieve information about models provided by OpenAI."}, "servers": [{"url": "https://api.beta.saia.ai", "description": "Production Server"}], "paths": {"/v2/llm/providers/openai/models": {"get": {"summary": "Retrieve models from OpenAI", "operationId": "saia_models", "description": "Fetches a list of available models along with their properties and configurations.", "responses": {"200": {"description": "Successful response with a list of models.", "content": {"application/json": {"schema": {"type": "object", "properties": {"models": {"type": "array", "items": {"type": "object", "properties": {"contextWindow": {"type": "integer", "description": "Maximum context window size for the model."}, "fullName": {"type": "string", "description": "Full name of the model."}, "id": {"type": "string", "format": "uuid", "description": "Unique identifier of the model."}, "isCustom": {"type": "boolean", "description": "Indicates whether the model is custom."}, "maxOutputTokens": {"type": "integer", "description": "Maximum number of output tokens the model can generate."}, "name": {"type": "string", "description": "Name of the model."}, "priority": {"type": "integer", "description": "Priority level of the model."}, "properties": {"type": "array", "items": {"type": "object", "properties": {"id": {"type": "string", "format": "uuid", "description": "Unique identifier for the property."}, "name": {"type": "string", "description": "Name of the property."}, "type": {"type": "string", "description": "Data type of the property (e.g., Boolean, String)."}, "value": {"type": "string", "description": "Value of the property."}}}}}, "type": {"type": "string", "description": "Type of the model (e.g., Chat)."}}}}}}}}}, "security": [{"bearerAuth": []}]}}}}' \
2266
+ --automatic-publish 1
2267
+ ### Publish a Tool Revision
2268
+
2269
+ Publish a specific revision of a tool.
2270
+
2271
+ geai ai-lab publish-tool-revision \
2272
+ --project-id "$PROJECT_ID" \
2273
+ --tool-id "ada1665f-ecea-4635-b2cd-d614756b83a4" \
2274
+ --revision "2"
2275
+ ### Get Tool Parameters
2276
+
2277
+ Retrieve parameters for a tool.
2278
+
2279
+ geai ai-lab get-parameter \
2280
+ --project-id "$PROJECT_ID" \
2281
+ --tool-public-name "sample_tool_V3" \
2282
+ --revision "0" \
2283
+ --version "0" \
2284
+ --allow-drafts 1
2285
+ Example Output:
2286
+
2287
+ - Key: input, Description: some input that the tool needs HERE., Required: true
2288
+ - Key: api_token, Description: API token for authentication, Required: true
2289
+ ### Set Tool Parameters
2290
+
2291
+ Update parameters for a tool.
2292
+
2293
+ geai ai-lab set-parameter \
2294
+ --project-id "$PROJECT_ID" \
2295
+ --tool-public-name "sample_tool_V3" \
2296
+ --parameter '{"key": "input", "dataType": "String", "description": "some input that the tool needs HERE.", "isRequired": true}' \
2297
+ --parameter '{"key": "api_token", "dataType": "String", "description": "API token for authentication", "isRequired": true, "type": "config", "fromSecret": true, "value": "0cd84dc7-f3f5-4a03-9288-cdfd8d72fde1"}'
2298
+ ### Delete a Tool
2299
+
2300
+ Remove a tool from the project.
2301
+
2302
+ geai ai-lab delete-tool \
2303
+ --project-id "$PROJECT_ID" \
2304
+ --tool-id "ada1665f-ecea-4635-b2cd-d614756b83a4"
2305
+ Managing Reasoning Strategies
2306
+ Reasoning strategies define how agents process information.
2307
+
2308
+ ### List Reasoning Strategies
2309
+
2310
+ Retrieve a list of reasoning strategies.
2311
+
2312
+ geai ai-lab list-reasoning-strategies \
2313
+ --start "0" \
2314
+ --count "50" \
2315
+ --allow-external 1 \
2316
+ --access-scope "public"
2317
+ Example Output:
2318
+
2319
+ - Name: RSName2, Access Scope: public
2320
+ - Name: test1, Access Scope: public
2321
+ ### Create a Reasoning Strategy
2322
+
2323
+ Create a reasoning strategy with localized descriptions.
2324
+
2325
+ geai ai-lab create-reasoning-strategy \
2326
+ --project-id "$PROJECT_ID" \
2327
+ --name "RSName2" \
2328
+ --system-prompt "Let's think step by step." \
2329
+ --access-scope "private" \
2330
+ --type "addendum" \
2331
+ --localized-description '{"language": "spanish", "description": "RSName spanish description"}' \
2332
+ --localized-description '{"language": "english", "description": "RSName english description"}' \
2333
+ --localized-description '{"language": "japanese", "description": "RSName japanese description"}' \
2334
+ --automatic-publish 1
2335
+ ### Update a Reasoning Strategy
2336
+
2337
+ Update an existing reasoning strategy.
2338
+
2339
+ geai ai-lab update-reasoning-strategy \
2340
+ --project-id "$PROJECT_ID" \
2341
+ --reasoning-strategy-id "50832dd9-1b69-4842-9349-de993a86661e" \
2342
+ --name "test1" \
2343
+ --system-prompt "Let's think step by step." \
2344
+ --access-scope "private" \
2345
+ --type "addendum" \
2346
+ --automatic-publish 0 \
2347
+ --upsert 1
2348
+ ### Get a Reasoning Strategy
2349
+
2350
+ Retrieve details for a specific reasoning strategy.
2351
+
2352
+ geai ai-lab get-reasoning-strategy \
2353
+ --project-id "$PROJECT_ID" \
2354
+ --reasoning-strategy-name "test1"
2355
+ Example Output:
2356
+
2357
+ Name: test1
2358
+ System Prompt: Let's think step by step.
2359
+ Access Scope: private
2360
+ Managing Processes
2361
+ Processes define workflows involving agents, tasks, and events.
2362
+
2363
+ ### Create a Process
2364
+
2365
+ Create a process with agentic activities and signals.
2366
+
2367
+ geai ai-lab create-process \
2368
+ --project-id "$PROJECT_ID" \
2369
+ --key "product_def" \
2370
+ --name "Basic Process V4" \
2371
+ --description "This is a sample process" \
2372
+ --kb '{"name": "basic-sample", "artifactTypeName": ["sample-artifact"]}' \
2373
+ --agentic-activity '{"key": "activityOne", "name": "First Step", "taskName": "basic-task", "agentName": "sample-translator", "agentRevisionId": 0}' \
2374
+ --artifact-signal '{"key": "artifact.upload.1", "name": "artifact.upload", "handlingType": "C", "artifactTypeName": ["sample-artifact"]}' \
2375
+ --user-signal '{"key": "signal_done", "name": "process-completed"}' \
2376
+ --start-event '{"key": "artifact.upload.1", "name": "artifact.upload"}' \
2377
+ --end-event '{"key": "end", "name": "Done"}' \
2378
+ --sequence-flow '{"key": "step1", "sourceKey": "artifact.upload.1", "targetKey": "activityOne"}' \
2379
+ --sequence-flow '{"key": "step2", "sourceKey": "activityOne", "targetKey": "signal_done"}' \
2380
+ --sequence-flow '{"key": "stepEnd", "sourceKey": "signal_done", "targetKey": "end"}' \
2381
+ --automatic-publish 0
2382
+ ### Ensure Task Exists
2383
+
2384
+ Create a task required for the process.
2385
+
2386
+ geai ai-lab create-task \
2387
+ --project-id "$PROJECT_ID" \
2388
+ --name "basic-task" \
2389
+ --description "Basic task for process" \
2390
+ --title-template "Basic Task" \
2391
+ --automatic-publish 1
2392
+ ### Update a Process
2393
+
2394
+ Update an existing process.
2395
+
2396
+ geai ai-lab update-process \
2397
+ --project-id "$PROJECT_ID" \
2398
+ --process-id "cf64f4b2-7f39-4294-94e4-5d441229b441" \
2399
+ --name "Basic Process V3" \
2400
+ --kb '{"name": "basic-sample", "artifactTypeName": ["sample-artifact"]}' \
2401
+ --agentic-activity '{"key": "activityOne", "name": "First Step", "taskName": "basic-task", "agentName": "sample-translator", "agentRevisionId": 0}' \
2402
+ --automatic-publish 0 \
2403
+ --upsert 0
2404
+ ### Get a Process
2405
+
2406
+ Retrieve process details by ID or name.
2407
+
2408
+ geai ai-lab get-process \
2409
+ --project-id "$PROJECT_ID" \
2410
+ --process-id "e8f34673-dd66-4eb2-8d91-886ba0e1da69" \
2411
+ --revision "0" \
2412
+ --version 0 \
2413
+ --allow-drafts 1
2414
+ Example Output:
2415
+
2416
+ Name: Basic Process V4
2417
+ ID: e8f34673-dd66-4eb2-8d91-886ba0e1da69
2418
+ Description: This is a sample process
2419
+ ### List Processes
2420
+
2421
+ Retrieve a list of processes.
2422
+
2423
+ geai ai-lab list-processes \
2424
+ --project-id "$PROJECT_ID" \
2425
+ --start "0" \
2426
+ --count "100" \
2427
+ --allow-draft 1
2428
+ Example Output:
2429
+
2430
+ - Name: Basic Process V4, ID: e8f34673-dd66-4eb2-8d91-886ba0e1da69
2431
+ - Name: Basic Process V3, ID: cf64f4b2-7f39-4294-94e4-5d441229b441
2432
+ ### Publish a Process Revision
2433
+
2434
+ Publish a specific revision of a process.
2435
+
2436
+ geai ai-lab publish-process-revision \
2437
+ --project-id "$PROJECT_ID" \
2438
+ --process-id "325e69db-1ae6-4266-82fb-114a2051b708" \
2439
+ --revision "1"
2440
+ ### Delete a Process
2441
+
2442
+ Remove a process from the project.
2443
+
2444
+ geai ai-lab delete-process \
2445
+ --project-id "$PROJECT_ID" \
2446
+ --process-id "e8f34673-dd66-4eb2-8d91-886ba0e1da69"
2447
+ Managing Tasks
2448
+ Tasks define specific actions within processes.
2449
+
2450
+ ### Create a Task
2451
+
2452
+ Create a task with minimal configuration.
2453
+
2454
+ geai ai-lab create-task \
2455
+ --project-id "$PROJECT_ID" \
2456
+ --name "Sample v2" \
2457
+ --description "A simple task that requires no tools and defines no prompt" \
2458
+ --title-template "Sample Task" \
2459
+ --automatic-publish 0
2460
+ ### List Tasks
2461
+
2462
+ Retrieve a list of tasks.
2463
+
2464
+ geai ai-lab list-tasks \
2465
+ --project-id "$PROJECT_ID" \
2466
+ --start "0" \
2467
+ --count "50" \
2468
+ --allow-drafts 1
2469
+ Example Output:
2470
+
2471
+ - Name: Sample v2, ID: 70143b97-8e52-460f-b4cc-c48405a38cff
2472
+ - Name: basic-task, ID: <task-id>
2473
+ ### Get a Task
2474
+
2475
+ Retrieve details for a specific task.
2476
+
2477
+ geai ai-lab get-task \
2478
+ --project-id "$PROJECT_ID" \
2479
+ --task-id "70143b97-8e52-460f-b4cc-c48405a38cff"
2480
+ Example Output:
2481
+
2482
+ Name: Sample v2
2483
+ ID: 70143b97-8e52-460f-b4cc-c48405a38cff
2484
+ Description: A simple task that requires no tools and defines no prompt
2485
+ ### Update a Task
2486
+
2487
+ Update an existing task.
2488
+
2489
+ geai ai-lab update-task \
2490
+ --project-id "$PROJECT_ID" \
2491
+ --task-id "70143b97-8e52-460f-b4cc-c48405a38cff" \
2492
+ --name "Sample v2 Updated" \
2493
+ --description "Updated description" \
2494
+ --title-template "Updated Sample Task" \
2495
+ --automatic-publish 1 \
2496
+ --upsert 0
2497
+ ### Publish a Task Revision
2498
+
2499
+ Publish a specific revision of a task.
2500
+
2501
+ geai ai-lab publish-task-revision \
2502
+ --project-id "$PROJECT_ID" \
2503
+ --task-id "70143b97-8e52-460f-b4cc-c48405a38cff" \
2504
+ --revision "1"
2505
+ ### Delete a Task
2506
+
2507
+ Remove a task from the project.
2508
+
2509
+ geai ai-lab delete-task \
2510
+ --project-id "$PROJECT_ID" \
2511
+ --task-id "70143b97-8e52-460f-b4cc-c48405a38cff"
2512
+ Managing Process Instances
2513
+ Process instances represent running workflows.
2514
+
2515
+ ### Start a Process Instance
2516
+
2517
+ Start a new instance of a process.
2518
+
2519
+ geai ai-lab start-instance \
2520
+ --project-id "$PROJECT_ID" \
2521
+ --process-name "Basic Process V2" \
2522
+ --subject "should we talk about the weather?" \
2523
+ --variables '[{"key": "location", "value": "Paris"}]'
2524
+ Example Output:
2525
+
2526
+ Instance ID: <instance-id>
2527
+ Status: active
2528
+ ### List Process Instances
2529
+
2530
+ Retrieve a list of process instances.
2531
+
2532
+ geai ai-lab list-processes-instances \
2533
+ --project-id "$PROJECT_ID" \
2534
+ --process-id "e8f34673-dd66-4eb2-8d91-886ba0e1da69" \
2535
+ --is-active 1 \
2536
+ --start "0" \
2537
+ --count "10"
2538
+ Example Output:
2539
+
2540
+ - Instance ID: <instance-id>, Status: active, Subject: should we talk about the weather?
2541
+ ### Get a Process Instance
2542
+
2543
+ Retrieve details for a specific instance.
2544
+
2545
+ geai ai-lab get-instance \
2546
+ --project-id "$PROJECT_ID" \
2547
+ --instance-id "<instance-id>"
2548
+ Example Output:
2549
+
2550
+ Instance ID: <instance-id>
2551
+ Process: Basic Process V2
2552
+ Subject: should we talk about the weather?
2553
+ ### Get Instance History
2554
+
2555
+ Retrieve the history of a process instance.
2556
+
2557
+ geai ai-lab get-instance-history \
2558
+ --project-id "$PROJECT_ID" \
2559
+ --instance-id "<instance-id>"
2560
+ Example Output:
2561
+
2562
+ - Event: Started, Timestamp: 2025-04-15T10:00:00Z
2563
+ - Event: Artifact Uploaded, Timestamp: 2025-04-15T10:01:00Z
2564
+ ### Send a User Signal
2565
+
2566
+ Send a signal to a running process instance.
2567
+
2568
+ geai ai-lab send-user-signal \
2569
+ --project-id "$PROJECT_ID" \
2570
+ --instance-id "<instance-id>" \
2571
+ --signal-name "approval"
2572
+ ### Abort a Process Instance
2573
+
2574
+ Stop a running process instance.
2575
+
2576
+ geai ai-lab abort-instance \
2577
+ --project-id "$PROJECT_ID" \
2578
+ --instance-id "<instance-id>"
2579
+ Complete Example Workflow
2580
+ This example demonstrates creating an agent, a task, a process, and starting an instance.
2581
+
2582
+ Create an Agent:
2583
+
2584
+ geai ai-lab create-agent \
2585
+ --project-id "$PROJECT_ID" \
2586
+ --name "sample-translator" \
2587
+ --description "Translator agent for processes" \
2588
+ --access-scope "public" \
2589
+ --automatic-publish 1
2590
+ Create a Task:
2591
+
2592
+ geai ai-lab create-task \
2593
+ --project-id "$PROJECT_ID" \
2594
+ --name "basic-task" \
2595
+ --description "Basic task for process" \
2596
+ --title-template "Basic Task" \
2597
+ --automatic-publish 1
2598
+ Create a Process:
2599
+
2600
+ geai ai-lab create-process \
2601
+ --project-id "$PROJECT_ID" \
2602
+ --key "product_def" \
2603
+ --name "Basic Process V4" \
2604
+ --description "This is a sample process" \
2605
+ --kb '{"name": "basic-sample", "artifactTypeName": ["sample-artifact"]}' \
2606
+ --agentic-activity '{"key": "activityOne", "name": "First Step", "taskName": "basic-task", "agentName": "sample-translator", "agentRevisionId": 0}' \
2607
+ --artifact-signal '{"key": "artifact.upload.1", "name": "artifact.upload", "handlingType": "C", "artifactTypeName": ["sample-artifact"]}' \
2608
+ --user-signal '{"key": "signal_done", "name": "process-completed"}' \
2609
+ --start-event '{"key": "artifact.upload.1", "name": "artifact.upload"}' \
2610
+ --end-event '{"key": "end", "name": "Done"}' \
2611
+ --sequence-flow '{"key": "step1", "sourceKey": "artifact.upload.1", "targetKey": "activityOne"}' \
2612
+ --sequence-flow '{"key": "step2", "sourceKey": "activityOne", "targetKey": "signal_done"}' \
2613
+ --sequence-flow '{"key": "stepEnd", "sourceKey": "signal_done", "targetKey": "end"}' \
2614
+ --automatic-publish 1
2615
+ Start a Process Instance:
2616
+
2617
+ geai ai-lab start-instance \
2618
+ --project-id "$PROJECT_ID" \
2619
+ --process-name "Basic Process V4" \
2620
+ --subject "should we talk about the weather?" \
2621
+ --variables '[{"key": "location", "value": "Paris"}]'
2622
+
2623
+ GEAI CLI - AI Lab - Spec Command Documentation
2624
+ Name
2625
+ geai - Command Line Interface for Globant Enterprise AI
2626
+
2627
+ Synopsis
2628
+ geai spec <subcommand> --[flag] [flag.arg]
2629
+ Description
2630
+ The geai spec command is a utility within the Globant Enterprise AI (GEAI) CLI, designed to load components (agents, tools, tasks, and agentic processes) into the AI Lab from JSON specification files. It supports the following subcommands:
2631
+
2632
+ help (or h): Displays help text for the geai spec command.
2633
+
2634
+ load-agent (or la): Loads agent(s) from a JSON specification file.
2635
+
2636
+ load-tool (or lt): Loads tool(s) from a JSON specification file.
2637
+
2638
+ load-task (or ltask): Loads task(s) from a JSON specification file.
2639
+
2640
+ load-agentic-process (or lap): Loads agentic process(es) from a JSON specification file.
2641
+
2642
+ Each subcommand accepts specific options to configure the loading process, such as project ID (specified as a UUID), file path, and publication settings.
2643
+
2644
+ Subcommands and Options
2645
+ The following subcommands are available under geai spec:
2646
+
2647
+ help
2648
+ Aliases: help, h
2649
+
2650
+ Description: Displays help text describing the geai spec command and its subcommands.
2651
+
2652
+ Options: None
2653
+
2654
+ Usage:
2655
+
2656
+ geai spec help
2657
+ load-agent
2658
+ Aliases: load-agent, la
2659
+
2660
+ Description: Loads one or more agent specifications from a JSON file into the AI Lab for a specified project, identified by a UUID.
2661
+
2662
+ Options:
2663
+
2664
+ Usage:
2665
+
2666
+ geai spec load-agent --project-id 123e4567-e89b-12d3-a456-426614174000 --file agent.json --automatic-publish 0
2667
+ load-tool
2668
+ Aliases: load-tool, lt
2669
+
2670
+ Description: Loads one or more tool specifications from a JSON file into the AI Lab for a specified project, identified by a UUID.
2671
+
2672
+ Options:
2673
+
2674
+ Usage:
2675
+
2676
+ geai spec load-tool --pid 987fcdeb-1a2b-3c4d-5e6f-7890abcd1234 -f tool.json --ap 1
2677
+ load-task
2678
+ Aliases: load-task, ltask
2679
+
2680
+ Description: Loads one or more task specifications from a JSON file into the AI Lab for a specified project, identified by a UUID.
2681
+
2682
+ Options:
2683
+
2684
+ Usage:
2685
+
2686
+ geai spec load-task --pid 456e7890-f1a2-4b3c-5d6e-8901bcde2345 -f task.json --ap 0
2687
+ load-agentic-process
2688
+ Aliases: load-agentic-process, lap
2689
+
2690
+ Description: Loads one or more agentic process specifications from a JSON file into the AI Lab for a specified project, identified by a UUID.
2691
+
2692
+ Options:
2693
+
2694
+ Usage:
2695
+
2696
+ geai spec load-agentic-process --project-id 789a0bcd-2e3f-5c4d-6e7f-9012cdef3456 -f process.json --ap 1
2697
+ Usage Examples
2698
+ Below are example commands demonstrating the usage of geai spec subcommands, using UUIDs for project IDs.
2699
+
2700
+ Example 1: Display Help
2701
+
2702
+ Display the help text for the geai spec command.
2703
+
2704
+ geai spec help
2705
+ Output (example):
2706
+
2707
+ geai spec - Command Line Interface for Globant Enterprise AI
2708
+ Usage: geai spec <subcommand> --[flag] [flag.arg]
2709
+ Subcommands:
2710
+ help, h Display help text
2711
+ load-agent, la Load agent from JSON specification
2712
+ load-tool, lt Load tool from JSON specification
2713
+ load-task, ltask Load task from JSON specification
2714
+ load-agentic-process, lap Load agentic process from JSON specification
2715
+ ...
2716
+ Example 2: Load a Single Agent
2717
+
2718
+ Load an agent from a JSON file into project with UUID 123e4567-e89b-12d3-a456-426614174000 as a draft.
2719
+
2720
+ geai spec load-agent --project-id 123e4567-e89b-12d3-a456-426614174000 --file agent.json --automatic-publish 0
2721
+ Output (example):
2722
+
2723
+ Created agent detail:
2724
+ <agent details>
2725
+ Example 3: Load and Publish a Tool
2726
+
2727
+ Load a tool from a JSON file into project with UUID 987fcdeb-1a2b-3c4d-5e6f-7890abcd1234 and publish it.
2728
+
2729
+ geai spec load-tool --pid 987fcdeb-1a2b-3c4d-5e6f-7890abcd1234 -f tool.json --ap 1
2730
+ Output (example):
2731
+
2732
+ Created tool detail:
2733
+ <tool details>
2734
+ Example 4: Load a Task
2735
+
2736
+ Load a task from a JSON file into project with UUID 456e7890-f1a2-4b3c-5d6e-8901bcde2345 as a draft.
2737
+
2738
+ geai spec load-task --pid 456e7890-f1a2-4b3c-5d6e-8901bcde2345 -f task.json --ap 0
2739
+ Output (example):
2740
+
2741
+ Created task detail:
2742
+ <task details>
2743
+ Example 5: Load and Publish an Agentic Process
2744
+
2745
+ Load an agentic process from a JSON file into project with UUID 789a0bcd-2e3f-5c4d-6e7f-9012cdef3456 and publish it.
2746
+
2747
+ geai spec load-agentic-process --project-id 789a0bcd-2e3f-5c4d-6e7f-9012cdef3456 -f process.json --ap 1
2748
+ Output (example):
2749
+
2750
+ Created agentic process detail:
2751
+ <process details>
2752
+ Example 6: Missing File Path (Error Case)
2753
+
2754
+ Attempt to load a task without specifying the file path.
2755
+
2756
+ geai spec load-task --pid 456e7890-f1a2-4b3c-5d6e-8901bcde2345 --ap 0
2757
+ Output:
2758
+
2759
+ Error: Cannot load task definition without specifying path to JSON file.
2760
+ JSON Specification Formats
2761
+ The load-agent, load-tool, load-task, and load-agentic-process subcommands expect JSON files containing agent, tool, task, or agentic process specifications, respectively. The JSON file can contain a single specification (object) or multiple specifications (array).
2762
+
2763
+ Agent Specification Example
2764
+
2765
+ Below is an example of a single agent specification for a “Public Translator V2x” agent.
2766
+
2767
+ {
2768
+ "name": "Public Translator V2x",
2769
+ "accessScope": "private",
2770
+ "publicName": "com.genexus.geai.public_translator_v2x",
2771
+ "jobDescription": "Translates",
2772
+ "avatarImage": "https://www.shareicon.net/data/128x128/2016/11/09/851442_logo_512x512.png",
2773
+ "description": "Agent that translates from any language to english.",
2774
+ "agentData": {
2775
+ "prompt": {
2776
+ "instructions": "the user will provide a text, you must return the same text translated to english",
2777
+ "inputs": ["text", "avoid slang indicator"],
2778
+ "outputs": [
2779
+ {
2780
+ "key": "translated_text",
2781
+ "description": "translated text, with slang or not depending on the indication. in plain text."
2782
+ },
2783
+ {
2784
+ "key": "summary",
2785
+ "description": "a summary in the original language of the text to be translated, also in plain text."
2786
+ }
2787
+ ],
2788
+ "examples": [
2789
+ {
2790
+ "inputData": "opitiiiis mundo [no-slang]",
2791
+ "output": "{\"translated_text\":\"hello world\",\"summary\":\"saludo\"}"
2792
+ },
2793
+ {
2794
+ "inputData": "esto es una prueba pincheguey [keep-slang]",
2795
+ "output": "{\"translated_text\":\"this is a test pal\",\"summary\":\"prueba\"}"
2796
+ }
2797
+ ]
2798
+ },
2799
+ "llmConfig": {
2800
+ "maxTokens": 5000,
2801
+ "timeout": 0,
2802
+ "sampling": {
2803
+ "temperature": 0.5,
2804
+ "topK": 0,
2805
+ "topP": 0
2806
+ }
2807
+ },
2808
+ "models": [
2809
+ { "name": "gpt-4-turbo-preview" }
2810
+ ]
2811
+ }
2812
+ }
2813
+ Tool Specification Example
2814
+
2815
+ Below is an example of a single tool specification for a “Weather Forecaster” tool.
2816
+
2817
+ {
2818
+ "name": "Weather Forecaster",
2819
+ "description": "A builtin tool that provides weather forecasts based on location and date.",
2820
+ "scope": "builtin",
2821
+ "parameters": [
2822
+ {
2823
+ "key": "location_date",
2824
+ "dataType": "String",
2825
+ "description": "Location and date for the weather forecast (e.g., 'New York, 2025-05-22').",
2826
+ "isRequired": true
2827
+ },
2828
+ {
2829
+ "key": "forecast_type",
2830
+ "dataType": "String",
2831
+ "description": "Type of forecast (e.g., daily, hourly), configured statically.",
2832
+ "isRequired": true,
2833
+ "type": "config",
2834
+ "fromSecret": false,
2835
+ "value": "daily"
2836
+ },
2837
+ {
2838
+ "key": "weather_api_key",
2839
+ "dataType": "String",
2840
+ "description": "API key for accessing the weather service, stored in secret manager.",
2841
+ "isRequired": true,
2842
+ "type": "config",
2843
+ "fromSecret": true,
2844
+ "value": "6f7a8b9c-0d1e-2f3a-4b5c-6d7e8f9a0b1c"
2845
+ }
2846
+ ]
2847
+ }
2848
+ Task Specification Example
2849
+
2850
+ Below is an example of a single task specification for an “Email Review v1” task.
2851
+
2852
+ {
2853
+ "name": "Email Review v1",
2854
+ "description": "A simple task to review and categorize email content, requiring no tools or prompts.",
2855
+ "titleTemplate": "Email Review Task"
2856
+ }
2857
+ Agentic Process Specification Example
2858
+
2859
+ Below is an example of a single agentic process specification for a “Content Moderation Process.”
2860
+
2861
+ {
2862
+ "key": "content_moderation_proc",
2863
+ "name": "Content Moderation Process",
2864
+ "description": "A process to review and moderate user-generated content for compliance.",
2865
+ "kb": {
2866
+ "name": "content-moderation-kb",
2867
+ "artifactTypeName": ["content-artifact"]
2868
+ },
2869
+ "agenticActivities": [
2870
+ {
2871
+ "key": "moderate_content",
2872
+ "name": "Moderate Content",
2873
+ "taskName": "content-moderation-task",
2874
+ "agentName": "content-moderator",
2875
+ "agentRevisionId": 0
2876
+ }
2877
+ ],
2878
+ "artifactSignals": [
2879
+ {
2880
+ "key": "artifact.content.upload.1",
2881
+ "name": "content.upload",
2882
+ "handlingType": "C",
2883
+ "artifactTypeName": ["content-artifact"]
2884
+ }
2885
+ ],
2886
+ "userSignals": [
2887
+ {
2888
+ "key": "signal_content_done",
2889
+ "name": "content-moderation-completed"
2890
+ }
2891
+ ],
2892
+ "startEvent": {
2893
+ "key": "artifact.content.upload.1",
2894
+ "name": "content.upload"
2895
+ },
2896
+ "endEvent": {
2897
+ "key": "end",
2898
+ "name": "Done"
2899
+ },
2900
+ "sequenceFlows": [
2901
+ {
2902
+ "key": "step1",
2903
+ "sourceKey": "artifact.content.upload.1",
2904
+ "targetKey": "moderate_content"
2905
+ },
2906
+ {
2907
+ "key": "step2",
2908
+ "sourceKey": "moderate_content",
2909
+ "targetKey": "signal_content_done"
2910
+ },
2911
+ {
2912
+ "key": "stepEnd",
2913
+ "sourceKey": "signal_content_done",
2914
+ "targetKey": "end"
2915
+ }
2916
+ ]
2917
+ }
2918
+ Error Handling
2919
+ The geai spec subcommands may raise the following errors:
2920
+
2921
+ MissingRequirementException: - Triggered if required options (--project-id or --file) are not provided. - Example: Cannot load task definition without specifying path to JSON file.
2922
+
2923
+ File Loading Errors: - Invalid or inaccessible JSON files will cause errors during loading, logged and displayed to stderr.
2924
+
2925
+ Parsing Errors: - Malformed JSON specifications may fail during parsing, with errors output to stderr.
2926
+
2927
+ Notes
2928
+ The project_id must be a valid UUID (e.g., 123e4567-e89b-12d3-a456-426614174000).
2929
+
2930
+ JSON files must conform to the expected format for agents, tools, tasks, or agentic processes, as shown in the examples above.
2931
+
2932
+ The automatic_publish option (0 or 1) determines whether the component is created as a draft or published immediately.
2933
+
2934
+ Ensure the project UUID exists in the AI Lab and the JSON file path is valid before running the command.
2935
+
2936
+ Multiple components can be loaded from a single JSON file if it contains an array of specifications.
2937
+
2938
+ from typing import Union, Optional, List
2939
+
2940
+ from pygeai.core.base.mappers import ResponseMapper
2941
+ from pygeai.core.base.responses import ErrorListResponse, EmptyResponse
2942
+ from pygeai.core.handlers import ErrorHandler
2943
+ from pygeai.lab.agents.clients import AgentClient
2944
+ from pygeai.lab.agents.mappers import AgentMapper
2945
+ from pygeai.lab.models import FilterSettings, Agent, AgentList, SharingLink, Tool, ToolList, ToolParameter, \
2946
+ ReasoningStrategyList, ReasoningStrategy, AgenticProcess, AgenticProcessList, ProcessInstanceList, Task, TaskList, \
2947
+ ProcessInstance, Variable, VariableList, KnowledgeBase, KnowledgeBaseList, JobList
2948
+ from pygeai.lab.processes.clients import AgenticProcessClient
2949
+ from pygeai.lab.processes.mappers import AgenticProcessMapper, ProcessInstanceMapper, TaskMapper, KnowledgeBaseMapper, \
2950
+ JobMapper
2951
+ from pygeai.lab.strategies.clients import ReasoningStrategyClient
2952
+ from pygeai.lab.strategies.mappers import ReasoningStrategyMapper
2953
+ from pygeai.lab.tools.clients import ToolClient
2954
+ from pygeai.lab.tools.mappers import ToolMapper
2955
+
2956
+
2957
+ class AILabManager:
2958
+
2959
+ def __init__(self, api_key: str = None, base_url: str = None, alias: str = "default"):
2960
+ self.__agent_client = AgentClient(api_key=api_key, base_url=base_url, alias=alias)
2961
+ self.__tool_client = ToolClient(api_key=api_key, base_url=base_url, alias=alias)
2962
+ self.__reasoning_strategy_client = ReasoningStrategyClient(api_key=api_key, base_url=base_url, alias=alias)
2963
+ self.__process_client = AgenticProcessClient(api_key=api_key, base_url=base_url, alias=alias)
2964
+
2965
+ def get_agent_list(
2966
+ self,
2967
+ project_id: str,
2968
+ filter_settings: FilterSettings = None
2969
+ ) -> AgentList:
2970
+ '''
2971
+ Retrieves a list of agents for a given project based on filter settings.
2972
+
2973
+ This method queries the agent client to fetch a list of agents associated with the specified
2974
+ project ID, applying the provided filter settings. If the response contains errors, it maps
2975
+ them to an `ErrorListResponse`. Otherwise, it maps the response to an `AgentList`.
2976
+
2977
+ :param project_id: str - The ID of the project to retrieve agents for.
2978
+ :param filter_settings: FilterSettings - The filter settings to apply to the agent list query.
2979
+ Includes fields such as status, start, count, access_scope, allow_drafts, and allow_external.
2980
+ :return: Union[AgentList, ErrorListResponse] - An `AgentList` containing the retrieved agents
2981
+ if successful, or an `ErrorListResponse` if the API returns errors.
2982
+ '''
2983
+ if not filter_settings:
2984
+ filter_settings = FilterSettings()
2985
+
2986
+ response_data = self.__agent_client.list_agents(
2987
+ project_id=project_id,
2988
+ status=filter_settings.status,
2989
+ start=filter_settings.start,
2990
+ count=filter_settings.count,
2991
+ access_scope=filter_settings.access_scope,
2992
+ allow_drafts=filter_settings.allow_drafts,
2993
+ allow_external=filter_settings.allow_external
2994
+ )
2995
+ if ErrorHandler.has_errors(response_data):
2996
+ result = ErrorHandler.extract_error(response_data)
2997
+ else:
2998
+ result = AgentMapper.map_to_agent_list(response_data)
2999
+
3000
+ return result
3001
+
3002
+ def create_agent(
3003
+ self,
3004
+ project_id: str,
3005
+ agent: Agent,
3006
+ automatic_publish: bool = False
3007
+ ) -> Union[Agent, ErrorListResponse]:
3008
+ '''
3009
+ Creates a new agent in the specified project using the provided agent configuration.
3010
+
3011
+ This method sends a request to the agent client to create an agent based on the attributes
3012
+ of the provided `Agent` object. If the response contains errors, it maps them to an
3013
+ `ErrorListResponse`. Otherwise, it maps the response to an `Agent` object.
3014
+
3015
+ :param project_id: str - Unique identifier of the project where the agent will be created.
3016
+ :param agent: Agent - The agent configuration object containing all necessary details,
3017
+ including name, access scope, public name, job description, avatar image, description,
3018
+ and agent data (prompt, LLM config, and models).
3019
+ :param automatic_publish: bool - Whether to automatically publish the agent after creation.
3020
+ Defaults to False.
3021
+ :return: Union[Agent, ErrorListResponse] - An `Agent` object representing the created agent
3022
+ if successful, or an `ErrorListResponse` if the API returns errors.
3023
+ '''
3024
+ response_data = self.__agent_client.create_agent(
3025
+ project_id=project_id,
3026
+ name=agent.name,
3027
+ access_scope=agent.access_scope,
3028
+ public_name=agent.public_name,
3029
+ job_description=agent.job_description,
3030
+ avatar_image=agent.avatar_image,
3031
+ description=agent.description,
3032
+ agent_data_prompt=agent.agent_data.prompt.to_dict() if agent.agent_data is not None else None,
3033
+ agent_data_llm_config=agent.agent_data.llm_config.to_dict() if agent.agent_data is not None else None,
3034
+ agent_data_models=agent.agent_data.models.to_dict() if agent.agent_data is not None else None,
3035
+ agent_data_resource_pools=agent.agent_data.resource_pools.to_dict() if agent.agent_data and agent.agent_data.resource_pools else None,
3036
+ automatic_publish=automatic_publish
3037
+ )
3038
+ if ErrorHandler.has_errors(response_data):
3039
+ result = ErrorHandler.extract_error(response_data)
3040
+ else:
3041
+ result = AgentMapper.map_to_agent(response_data)
3042
+
3043
+ return result
3044
+
3045
+ def update_agent(
3046
+ self,
3047
+ project_id: str,
3048
+ agent: Agent,
3049
+ automatic_publish: bool = False,
3050
+ upsert: bool = False
3051
+ ) -> Union[Agent, ErrorListResponse]:
3052
+ '''
3053
+ Updates an existing agent in the specified project using the provided agent configuration.
3054
+
3055
+ This method sends a request to the agent client to update an agent identified by `agent_id`
3056
+ (or `agent.id` if not provided) based on the attributes of the provided `Agent` object.
3057
+ It can optionally publish the agent automatically or perform an upsert if the agent doesn’t exist.
3058
+ If the response contains errors, it maps them to an `ErrorListResponse`. Otherwise, it maps
3059
+ the response to an `Agent` object.
3060
+
3061
+ :param project_id: str - Unique identifier of the project where the agent resides.
3062
+ :param agent: Agent - The agent configuration object containing updated details,
3063
+ including id, name, access scope, public name, job description, avatar image, description,
3064
+ and agent data (prompt, LLM config, and models).
3065
+ :param automatic_publish: bool - Whether to automatically publish the agent after updating.
3066
+ Defaults to False.
3067
+ :param upsert: bool - Whether to insert the agent if it does not exist (upsert) instead of
3068
+ just updating. Defaults to False.
3069
+ :return: Union[Agent, ErrorListResponse] - An `Agent` object representing the updated agent
3070
+ if successful, or an `ErrorListResponse` if the API returns errors.
3071
+ :raises ValueError: If neither `agent_id` nor `agent.id` is provided.
3072
+ '''
3073
+ response_data = self.__agent_client.update_agent(
3074
+ project_id=project_id,
3075
+ agent_id=agent.id,
3076
+ name=agent.name,
3077
+ access_scope=agent.access_scope,
3078
+ public_name=agent.public_name,
3079
+ job_description=agent.job_description,
3080
+ avatar_image=agent.avatar_image,
3081
+ description=agent.description,
3082
+ agent_data_prompt=agent.agent_data.prompt.to_dict() if agent.agent_data is not None else None,
3083
+ agent_data_llm_config=agent.agent_data.llm_config.to_dict() if agent.agent_data is not None else None,
3084
+ agent_data_models=agent.agent_data.models.to_dict() if agent.agent_data is not None else None,
3085
+ automatic_publish=automatic_publish,
3086
+ upsert=upsert
3087
+ )
3088
+ if ErrorHandler.has_errors(response_data):
3089
+ result = ErrorHandler.extract_error(response_data)
3090
+ else:
3091
+ result = AgentMapper.map_to_agent(response_data)
3092
+
3093
+ return result
3094
+
3095
+ def get_agent(
3096
+ self,
3097
+ project_id: str,
3098
+ agent_id: str,
3099
+ filter_settings: Optional[FilterSettings] = None
3100
+ ) -> Union[Agent, ErrorListResponse]:
3101
+ '''
3102
+ Retrieves details of a specific agent from the specified project.
3103
+
3104
+ This method sends a request to the agent client to retrieve an agent identified by `agent_id`
3105
+ from the specified project. Optional filter settings can be provided to specify the revision,
3106
+ version, and whether to allow drafts. If the response contains errors, it maps them to an
3107
+ `ErrorListResponse`. Otherwise, it maps the response to an `Agent` object.
3108
+
3109
+ :param project_id: str - Unique identifier of the project where the agent resides.
3110
+ :param agent_id: str - Unique identifier of the agent to retrieve.
3111
+ :param filter_settings: FilterSettings, optional - Settings to filter the agent retrieval,
3112
+ including revision (defaults to "0"), version (defaults to 0), and allow_drafts (defaults to True).
3113
+ :return: Union[Agent, ErrorListResponse] - An `Agent` object representing the retrieved agent
3114
+ if successful, or an `ErrorListResponse` if the API returns errors.
3115
+ '''
3116
+ if filter_settings is None:
3117
+ filter_settings = FilterSettings(
3118
+ revision="0",
3119
+ version="0",
3120
+ allow_drafts=True
3121
+ )
3122
+
3123
+ response_data = self.__agent_client.get_agent(
3124
+ project_id=project_id,
3125
+ agent_id=agent_id,
3126
+ revision=filter_settings.revision,
3127
+ version=filter_settings.version,
3128
+ allow_drafts=filter_settings.allow_drafts
3129
+ )
3130
+ if ErrorHandler.has_errors(response_data):
3131
+ result = ErrorHandler.extract_error(response_data)
3132
+ else:
3133
+ result = AgentMapper.map_to_agent(response_data)
3134
+
3135
+ return result
3136
+
3137
+ def create_sharing_link(
3138
+ self,
3139
+ project_id: str,
3140
+ agent_id: str
3141
+ ) -> Union[SharingLink, ErrorListResponse]:
3142
+ '''
3143
+ Creates a sharing link for a specific agent in the specified project.
3144
+
3145
+ This method sends a request to the agent client to create a sharing link for the agent
3146
+ identified by `agent_id` in the specified project. If the response contains errors, it maps
3147
+ them to an `ErrorListResponse`. Otherwise, it maps the response to a `SharingLink` object.
3148
+
3149
+ :param project_id: str - Unique identifier of the project where the agent resides.
3150
+ :param agent_id: str - Unique identifier of the agent for which to create a sharing link.
3151
+ :return: Union[SharingLink, ErrorListResponse] - A `SharingLink` object representing the
3152
+ sharing link details if successful, or an `ErrorListResponse` if the API returns errors.
3153
+ '''
3154
+ response_data = self.__agent_client.create_sharing_link(
3155
+ project_id=project_id,
3156
+ agent_id=agent_id
3157
+ )
3158
+ if ErrorHandler.has_errors(response_data):
3159
+ result = ErrorHandler.extract_error(response_data)
3160
+ else:
3161
+ result = AgentMapper.map_to_sharing_link(response_data)
3162
+
3163
+ return result
3164
+
3165
+ def publish_agent_revision(
3166
+ self,
3167
+ project_id: str,
3168
+ agent_id: str,
3169
+ revision: str
3170
+ ) -> Union[Agent, ErrorListResponse]:
3171
+ '''
3172
+ Publishes a specific revision of an agent in the specified project.
3173
+
3174
+ This method sends a request to the agent client to publish the specified revision of the agent
3175
+ identified by `agent_id` in the specified project. If the response contains errors, it maps
3176
+ them to an `ErrorListResponse`. Otherwise, it maps the response to an `Agent` object
3177
+ representing the published agent.
3178
+
3179
+ :param project_id: str - Unique identifier of the project where the agent resides.
3180
+ :param agent_id: str - Unique identifier of the agent to publish.
3181
+ :param revision: str - Revision of the agent to publish.
3182
+ :return: Union[Agent, ErrorListResponse] - An `Agent` object representing the published agent
3183
+ if successful, or an `ErrorListResponse` if the API returns errors.
3184
+ '''
3185
+ response_data = self.__agent_client.publish_agent_revision(
3186
+ project_id=project_id,
3187
+ agent_id=agent_id,
3188
+ revision=revision
3189
+ )
3190
+ if ErrorHandler.has_errors(response_data):
3191
+ result = ErrorHandler.extract_error(response_data)
3192
+ else:
3193
+ result = AgentMapper.map_to_agent(response_data)
3194
+
3195
+ return result
3196
+
3197
+ def delete_agent(
3198
+ self,
3199
+ project_id: str,
3200
+ agent_id: str
3201
+ ) -> Union[EmptyResponse, ErrorListResponse]:
3202
+ '''
3203
+ Deletes a specific agent from the specified project.
3204
+
3205
+ This method sends a request to the agent client to delete the agent identified by `agent_id`
3206
+ from the specified project. Returns True if the deletion is successful (indicated by an
3207
+ empty response or success confirmation), or an `ErrorListResponse` if the API returns errors.
3208
+
3209
+ :param project_id: str - Unique identifier of the project where the agent resides.
3210
+ :param agent_id: str - Unique identifier of the agent to delete.
3211
+ :return: Union[EmptyResponse, ErrorListResponse] - EmptyResponse if the agent was deleted successfully,
3212
+ or an `ErrorListResponse` if the API returns errors.
3213
+ '''
3214
+ response_data = self.__agent_client.delete_agent(
3215
+ project_id=project_id,
3216
+ agent_id=agent_id
3217
+ )
3218
+ if ErrorHandler.has_errors(response_data):
3219
+ result = ErrorHandler.extract_error(response_data)
3220
+ else:
3221
+ response_data = response_data if response_data else "Agent deleted successfully"
3222
+ result = ResponseMapper.map_to_empty_response(response_data)
3223
+
3224
+ return result
3225
+
3226
+ def create_tool(
3227
+ self,
3228
+ project_id: str,
3229
+ tool: Tool,
3230
+ automatic_publish: bool = False
3231
+ ) -> Union[Tool, ErrorListResponse]:
3232
+ '''
3233
+ Creates a new tool in the specified project using the provided tool configuration.
3234
+
3235
+ This method sends a request to the tool client to create a tool based on the attributes
3236
+ of the provided `Tool` object, including name, description, scope, access_scope, public_name,
3237
+ icon, open_api, open_api_json, report_events, and parameters. If the response contains errors,
3238
+ it maps them to an `ErrorListResponse`. Otherwise, it maps the response to a `Tool` object.
3239
+
3240
+ :param project_id: str - Unique identifier of the project where the tool will be created.
3241
+ :param tool: Tool - The tool configuration object containing name, description, scope,
3242
+ access_scope, public_name, icon, open_api, open_api_json, report_events, and parameters.
3243
+ Optional fields (e.g., id, access_scope) are included if set in the `Tool` object.
3244
+ :param automatic_publish: bool - Whether to automatically publish the tool after creation.
3245
+ Defaults to False.
3246
+ :return: Union[Tool, ErrorListResponse] - A `Tool` object representing the created tool
3247
+ if successful, or an `ErrorListResponse` if the API returns errors.
3248
+ '''
3249
+ parameters = [param.to_dict() for param in tool.parameters] if tool.parameters else []
3250
+
3251
+ response_data = self.__tool_client.create_tool(
3252
+ project_id=project_id,
3253
+ name=tool.name,
3254
+ description=tool.description,
3255
+ scope=tool.scope,
3256
+ access_scope=tool.access_scope,
3257
+ public_name=tool.public_name,
3258
+ icon=tool.icon,
3259
+ open_api=tool.open_api,
3260
+ open_api_json=tool.open_api_json,
3261
+ report_events=tool.report_events,
3262
+ parameters=parameters,
3263
+ automatic_publish=automatic_publish
3264
+ )
3265
+ if ErrorHandler.has_errors(response_data):
3266
+ result = ErrorHandler.extract_error(response_data)
3267
+ else:
3268
+ result = ToolMapper.map_to_tool(response_data)
3269
+
3270
+ return result
3271
+
3272
+ def update_tool(
3273
+ self,
3274
+ project_id: str,
3275
+ tool: Tool,
3276
+ automatic_publish: bool = False,
3277
+ upsert: bool = False
3278
+ ) -> Union[Tool, ErrorListResponse]:
3279
+ '''
3280
+ Updates an existing tool in the specified project or upserts it if specified.
3281
+
3282
+ This method sends a request to the tool client to update a tool identified by `tool.id`
3283
+ based on the attributes of the provided `Tool` object, including name, description, scope,
3284
+ access_scope, public_name, icon, open_api, open_api_json, report_events, and parameters.
3285
+ It can optionally publish the tool automatically or perform an upsert if the tool doesn’t exist.
3286
+ If the response contains errors, it maps them to an `ErrorListResponse`. Otherwise, it maps
3287
+ the response to a `Tool` object.
3288
+
3289
+ :param project_id: str - Unique identifier of the project where the tool resides.
3290
+ :param tool: Tool - The tool configuration object containing updated details, including
3291
+ id, name, description, scope, access_scope, public_name, icon, open_api, open_api_json,
3292
+ report_events, and parameters.
3293
+ :param automatic_publish: bool - Whether to automatically publish the tool after updating.
3294
+ Defaults to False.
3295
+ :param upsert: bool - Whether to insert the tool if it does not exist (upsert) instead of
3296
+ just updating. Defaults to False.
3297
+ :return: Union[Tool, ErrorListResponse] - A `Tool` object representing the updated tool
3298
+ if successful, or an `ErrorListResponse` if the API returns errors.
3299
+ '''
3300
+ parameters = [param.to_dict() for param in tool.parameters] if tool.parameters else []
3301
+
3302
+ response_data = self.__tool_client.update_tool(
3303
+ project_id=project_id,
3304
+ tool_id=tool.id,
3305
+ name=tool.name,
3306
+ description=tool.description,
3307
+ scope=tool.scope,
3308
+ access_scope=tool.access_scope,
3309
+ public_name=tool.public_name,
3310
+ icon=tool.icon,
3311
+ open_api=tool.open_api,
3312
+ open_api_json=tool.open_api_json,
3313
+ report_events=tool.report_events,
3314
+ parameters=parameters,
3315
+ automatic_publish=automatic_publish,
3316
+ upsert=upsert
3317
+ )
3318
+
3319
+ if ErrorHandler.has_errors(response_data):
3320
+ result = ErrorHandler.extract_error(response_data)
3321
+ else:
3322
+ result = ToolMapper.map_to_tool(response_data)
3323
+
3324
+ return result
3325
+
3326
+ def get_tool(
3327
+ self,
3328
+ project_id: str,
3329
+ tool_id: str,
3330
+ filter_settings: Optional[FilterSettings] = None
3331
+ ) -> Union[Tool, ErrorListResponse]:
3332
+ '''
3333
+ Retrieves details of a specific tool from the specified project.
3334
+
3335
+ This method sends a request to the tool client to retrieve a tool identified by `tool_id`
3336
+ from the specified project. Optional filter settings can be provided to specify the revision,
3337
+ version, and whether to allow drafts. If the response contains errors, it maps them to an
3338
+ `ErrorListResponse`. Otherwise, it maps the response to a `Tool` object.
3339
+
3340
+ :param project_id: str - Unique identifier of the project where the tool resides.
3341
+ :param tool_id: str - Unique identifier of the tool to retrieve.
3342
+ :param filter_settings: FilterSettings, optional - Settings to filter the tool retrieval,
3343
+ including revision (defaults to "0"), version (defaults to "0"), and allow_drafts (defaults to True).
3344
+ :return: Union[Tool, ErrorListResponse] - A `Tool` object representing the retrieved tool
3345
+ if successful, or an `ErrorListResponse` if the API returns errors.
3346
+ '''
3347
+ if filter_settings is None:
3348
+ filter_settings = FilterSettings(
3349
+ revision="0",
3350
+ version="0",
3351
+ allow_drafts=True
3352
+ )
3353
+
3354
+ response_data = self.__tool_client.get_tool(
3355
+ project_id=project_id,
3356
+ tool_id=tool_id,
3357
+ revision=filter_settings.revision,
3358
+ version=filter_settings.version,
3359
+ allow_drafts=filter_settings.allow_drafts
3360
+ )
3361
+
3362
+ if ErrorHandler.has_errors(response_data):
3363
+ result = ErrorHandler.extract_error(response_data)
3364
+ else:
3365
+ result = ToolMapper.map_to_tool(response_data)
3366
+
3367
+ return result
3368
+
3369
+ def delete_tool(
3370
+ self,
3371
+ project_id: str,
3372
+ tool_id: Optional[str] = None,
3373
+ tool_name: Optional[str] = None
3374
+ ) -> Union[EmptyResponse, ErrorListResponse]:
3375
+ '''
3376
+ Deletes a specific tool from the specified project.
3377
+
3378
+ This method sends a request to the tool client to delete the tool identified by either
3379
+ `tool_id` or `tool_name`. Returns an `EmptyResponse` if the deletion is successful,
3380
+ or an `ErrorListResponse` if the API returns errors.
3381
+
3382
+ :param project_id: str - Unique identifier of the project where the tool resides.
3383
+ :param tool_id: str, optional - Unique identifier of the tool to delete.
3384
+ :param tool_name: str, optional - Name of the tool to delete.
3385
+ :return: Union[EmptyResponse, ErrorListResponse] - `EmptyResponse` if the tool was deleted successfully,
3386
+ or an `ErrorListResponse` if the API returns errors.
3387
+ :raises ValueError: If neither tool_id nor tool_name is provided.
3388
+ '''
3389
+ if not (tool_id or tool_name):
3390
+ raise ValueError("Either tool_id or tool_name must be provided.")
3391
+
3392
+ response_data = self.__tool_client.delete_tool(
3393
+ project_id=project_id,
3394
+ tool_id=tool_id,
3395
+ tool_name=tool_name
3396
+ )
3397
+
3398
+ if ErrorHandler.has_errors(response_data):
3399
+ result = ErrorHandler.extract_error(response_data)
3400
+ else:
3401
+ response_data = response_data if response_data else "Tool deleted successfully"
3402
+ result = ResponseMapper.map_to_empty_response(response_data)
3403
+
3404
+ return result
3405
+
3406
+ def list_tools(
3407
+ self,
3408
+ project_id: str,
3409
+ filter_settings: Optional[FilterSettings] = None
3410
+ ) -> Union[ToolList, ErrorListResponse]:
3411
+ '''
3412
+ Retrieves a list of tools associated with the specified project.
3413
+
3414
+ This method queries the tool client to fetch a list of tools for the given project ID,
3415
+ applying the specified filter settings. If the response contains errors, it maps them to an
3416
+ `ErrorListResponse`. Otherwise, it maps the response to a `ToolList` object using `ToolMapper`.
3417
+
3418
+ :param project_id: str - Unique identifier of the project.
3419
+ :param filter_settings: FilterSettings, optional - Settings to filter the tool list query,
3420
+ including id (defaults to ""), count (defaults to "100"), access_scope (defaults to "public"),
3421
+ allow_drafts (defaults to True), scope (defaults to "api"), and allow_external (defaults to True).
3422
+ :return: Union[ToolList, ErrorListResponse] - A `ToolList` object containing the retrieved tools
3423
+ if successful, or an `ErrorListResponse` if the API returns errors.
3424
+ '''
3425
+ if filter_settings is None:
3426
+ filter_settings = FilterSettings(
3427
+ id="",
3428
+ count="100",
3429
+ access_scope="public",
3430
+ allow_drafts=True,
3431
+ scope="api",
3432
+ allow_external=True
3433
+ )
3434
+
3435
+ response_data = self.__tool_client.list_tools(
3436
+ project_id=project_id,
3437
+ id=filter_settings.id,
3438
+ count=filter_settings.count,
3439
+ access_scope=filter_settings.access_scope,
3440
+ allow_drafts=filter_settings.allow_drafts,
3441
+ scope=filter_settings.scope,
3442
+ allow_external=filter_settings.allow_external
3443
+ )
3444
+
3445
+ if ErrorHandler.has_errors(response_data):
3446
+ result = ErrorHandler.extract_error(response_data)
3447
+ else:
3448
+ result = ToolMapper.map_to_tool_list(response_data)
3449
+
3450
+ return result
3451
+
3452
+ def publish_tool_revision(
3453
+ self,
3454
+ project_id: str,
3455
+ tool_id: str,
3456
+ revision: str
3457
+ ) -> Union[Tool, ErrorListResponse]:
3458
+ '''
3459
+ Publishes a specific revision of a tool in the specified project.
3460
+
3461
+ This method sends a request to the tool client to publish the specified revision of the tool
3462
+ identified by `tool_id`. If the response contains errors, it maps them to an `ErrorListResponse`.
3463
+ Otherwise, it maps the response to a `Tool` object representing the published tool.
3464
+
3465
+ :param project_id: str - Unique identifier of the project where the tool resides.
3466
+ :param tool_id: str - Unique identifier of the tool to publish.
3467
+ :param revision: str - Revision of the tool to publish.
3468
+ :return: Union[Tool, ErrorListResponse] - A `Tool` object representing the published tool
3469
+ if successful, or an `ErrorListResponse` if the API returns errors.
3470
+ '''
3471
+ response_data = self.__tool_client.publish_tool_revision(
3472
+ project_id=project_id,
3473
+ tool_id=tool_id,
3474
+ revision=revision
3475
+ )
3476
+
3477
+ if ErrorHandler.has_errors(response_data):
3478
+ result = ErrorHandler.extract_error(response_data)
3479
+ else:
3480
+ result = ToolMapper.map_to_tool(response_data)
3481
+
3482
+ return result
3483
+
3484
+ def get_parameter(
3485
+ self,
3486
+ project_id: str,
3487
+ tool_id: Optional[str] = None,
3488
+ tool_public_name: Optional[str] = None,
3489
+ filter_settings: Optional[FilterSettings] = None
3490
+ ) -> Union[List[ToolParameter], ErrorListResponse]:
3491
+ '''
3492
+ Retrieves details of parameters for a specific tool in the specified project.
3493
+
3494
+ This method sends a request to the tool client to retrieve parameters for a tool identified
3495
+ by either `tool_id` or `tool_public_name`. Optional filter settings can specify revision,
3496
+ version, and whether to allow drafts. If the response contains errors, it maps them to an
3497
+ `ErrorListResponse`. Otherwise, it maps the response to a list of `ToolParameter` objects.
3498
+
3499
+ :param project_id: str - Unique identifier of the project.
3500
+ :param tool_id: str, optional - Unique identifier of the tool whose parameters are to be retrieved.
3501
+ :param tool_public_name: str, optional - Public name of the tool whose parameters are to be retrieved.
3502
+ :param filter_settings: FilterSettings, optional - Settings to filter the parameter retrieval,
3503
+ including revision (defaults to "0"), version (defaults to "0"), and allow_drafts (defaults to True).
3504
+ :return: Union[List[ToolParameter], ErrorListResponse] - A list of `ToolParameter` objects if successful,
3505
+ or an `ErrorListResponse` if the API returns errors.
3506
+ :raises ValueError: If neither tool_id nor tool_public_name is provided.
3507
+ '''
3508
+ if not (tool_id or tool_public_name):
3509
+ raise ValueError("Either tool_id or tool_public_name must be provided.")
3510
+
3511
+ if filter_settings is None:
3512
+ filter_settings = FilterSettings(
3513
+ revision="0",
3514
+ version="0",
3515
+ allow_drafts=True
3516
+ )
3517
+
3518
+ response_data = self.__tool_client.get_parameter(
3519
+ project_id=project_id,
3520
+ tool_id=tool_id,
3521
+ tool_public_name=tool_public_name,
3522
+ revision=filter_settings.revision,
3523
+ version=filter_settings.version,
3524
+ allow_drafts=filter_settings.allow_drafts
3525
+ )
3526
+
3527
+ if ErrorHandler.has_errors(response_data):
3528
+ result = ErrorHandler.extract_error(response_data)
3529
+ else:
3530
+ result = ToolMapper.map_to_parameter_list(response_data)
3531
+
3532
+ return result
3533
+
3534
+ def set_parameter(
3535
+ self,
3536
+ project_id: str,
3537
+ tool_id: Optional[str] = None,
3538
+ tool_public_name: Optional[str] = None,
3539
+ parameters: List[ToolParameter] = None
3540
+ ) -> Union[Tool, ErrorListResponse]:
3541
+ '''
3542
+ Sets or updates parameters for a specific tool in the specified project.
3543
+
3544
+ This method sends a request to the tool client to set parameters for a tool identified by
3545
+ either `tool_id` or `tool_public_name`. If the response contains errors, it maps them to an
3546
+ `ErrorListResponse`. Otherwise, it maps the response to a `Tool` object.
3547
+
3548
+ :param project_id: str - Unique identifier of the project.
3549
+ :param tool_id: str, optional - Unique identifier of the tool whose parameters are to be set.
3550
+ :param tool_public_name: str, optional - Public name of the tool whose parameters are to be set.
3551
+ :param parameters: List[ToolParameter] - List of parameter objects defining the tool's parameters.
3552
+ :return: Union[Tool, ErrorListResponse] - A `Tool` object representing the updated tool if successful,
3553
+ or an `ErrorListResponse` if the API returns errors.
3554
+ :raises ValueError: If neither tool_id nor tool_public_name is provided, or if parameters is None or empty.
3555
+ '''
3556
+ if not (tool_id or tool_public_name):
3557
+ raise ValueError("Either tool_id or tool_public_name must be provided.")
3558
+ if not parameters:
3559
+ raise ValueError("Parameters list must be provided and non-empty.")
3560
+
3561
+ params_dict = [param.to_dict() for param in parameters]
3562
+
3563
+ response_data = self.__tool_client.set_parameter(
3564
+ project_id=project_id,
3565
+ tool_id=tool_id,
3566
+ tool_public_name=tool_public_name,
3567
+ parameters=params_dict
3568
+ )
3569
+
3570
+ if ErrorHandler.has_errors(response_data):
3571
+ result = ErrorHandler.extract_error(response_data)
3572
+ else:
3573
+ result = ResponseMapper.map_to_empty_response(response_data)
3574
+
3575
+ return result
3576
+
3577
+ def list_reasoning_strategies(
3578
+ self,
3579
+ filter_settings: Optional[FilterSettings] = None
3580
+ ) -> Union[ReasoningStrategyList, ErrorListResponse]:
3581
+ if filter_settings is None:
3582
+ filter_settings = FilterSettings(
3583
+ start="0",
3584
+ count="100",
3585
+ allow_external=True,
3586
+ access_scope="public"
3587
+ )
3588
+
3589
+ response_data = self.__reasoning_strategy_client.list_reasoning_strategies(
3590
+ name=filter_settings.name or "",
3591
+ start=filter_settings.start,
3592
+ count=filter_settings.count,
3593
+ allow_external=filter_settings.allow_external,
3594
+ access_scope=filter_settings.access_scope
3595
+ )
3596
+
3597
+ if ErrorHandler.has_errors(response_data):
3598
+ result = ErrorHandler.extract_error(response_data)
3599
+ else:
3600
+ result = ReasoningStrategyMapper.map_to_reasoning_strategy_list(response_data)
3601
+
3602
+ return result
3603
+
3604
+ def create_reasoning_strategy(
3605
+ self,
3606
+ project_id: str,
3607
+ strategy: ReasoningStrategy,
3608
+ automatic_publish: bool = False
3609
+ ) -> Union[ReasoningStrategy, ErrorListResponse]:
3610
+ response_data = self.__reasoning_strategy_client.create_reasoning_strategy(
3611
+ project_id=project_id,
3612
+ name=strategy.name,
3613
+ system_prompt=strategy.system_prompt,
3614
+ access_scope=strategy.access_scope,
3615
+ strategy_type=strategy.type,
3616
+ localized_descriptions=[desc.to_dict() for desc in strategy.localized_descriptions],
3617
+ automatic_publish=automatic_publish
3618
+ )
3619
+
3620
+ if ErrorHandler.has_errors(response_data):
3621
+ result = ErrorHandler.extract_error(response_data)
3622
+ else:
3623
+ result = ReasoningStrategyMapper.map_to_reasoning_strategy(response_data)
3624
+
3625
+ return result
3626
+
3627
+ def update_reasoning_strategy(
3628
+ self,
3629
+ project_id: str,
3630
+ strategy: ReasoningStrategy,
3631
+ automatic_publish: bool = False,
3632
+ upsert: bool = False
3633
+ ) -> Union[ReasoningStrategy, ErrorListResponse]:
3634
+ response_data = self.__reasoning_strategy_client.update_reasoning_strategy(
3635
+ project_id=project_id,
3636
+ reasoning_strategy_id=strategy.id,
3637
+ name=strategy.name,
3638
+ system_prompt=strategy.system_prompt,
3639
+ access_scope=strategy.access_scope,
3640
+ strategy_type=strategy.type,
3641
+ localized_descriptions=[desc.to_dict() for desc in strategy.localized_descriptions],
3642
+ automatic_publish=automatic_publish,
3643
+ upsert=upsert
3644
+ )
3645
+
3646
+ if ErrorHandler.has_errors(response_data):
3647
+ result = ErrorHandler.extract_error(response_data)
3648
+ else:
3649
+ result = ReasoningStrategyMapper.map_to_reasoning_strategy(response_data)
3650
+
3651
+ return result
3652
+
3653
+ def get_reasoning_strategy(
3654
+ self,
3655
+ project_id: str,
3656
+ reasoning_strategy_id: Optional[str] = None,
3657
+ reasoning_strategy_name: Optional[str] = None
3658
+ ) -> Union[ReasoningStrategy, ErrorListResponse]:
3659
+ if not (reasoning_strategy_id or reasoning_strategy_name):
3660
+ raise ValueError("Either reasoning_strategy_id or reasoning_strategy_name must be provided.")
3661
+
3662
+ response_data = self.__reasoning_strategy_client.get_reasoning_strategy(
3663
+ project_id=project_id,
3664
+ reasoning_strategy_id=reasoning_strategy_id,
3665
+ reasoning_strategy_name=reasoning_strategy_name
3666
+ )
3667
+
3668
+ if ErrorHandler.has_errors(response_data):
3669
+ result = ErrorHandler.extract_error(response_data)
3670
+ else:
3671
+ result = ReasoningStrategyMapper.map_to_reasoning_strategy(response_data)
3672
+
3673
+ return result
3674
+
3675
+ def create_process(
3676
+ self,
3677
+ project_id: str,
3678
+ process: AgenticProcess,
3679
+ automatic_publish: bool = False
3680
+ ) -> Union[AgenticProcess, ErrorListResponse]:
3681
+ '''
3682
+ Creates a new process in the specified project.
3683
+
3684
+ :param project_id: str - Unique identifier of the project.
3685
+ :param process: AgenticProcess - The process configuration to create.
3686
+ :param automatic_publish: bool - Whether to publish the process after creation. Defaults to False.
3687
+ :return: Union[AgenticProcess, ErrorListResponse] - The created process if successful, or an error response.
3688
+ '''
3689
+ response_data = self.__process_client.create_process(
3690
+ project_id=project_id,
3691
+ key=process.key,
3692
+ name=process.name,
3693
+ description=process.description,
3694
+ kb=process.kb.to_dict(),
3695
+ agentic_activities=[activity.to_dict() for activity in process.agentic_activities] if process.agentic_activities else None,
3696
+ artifact_signals=[signal.to_dict() for signal in process.artifact_signals] if process.artifact_signals else None,
3697
+ user_signals=[signal.to_dict() for signal in process.user_signals] if process.user_signals else None,
3698
+ start_event=process.start_event.to_dict(),
3699
+ end_event=process.end_event.to_dict(),
3700
+ sequence_flows=[flow.to_dict() for flow in process.sequence_flows] if process.sequence_flows else None,
3701
+ variables=[variable.to_dict() for variable in process.variables] if process.variables else None,
3702
+ automatic_publish=automatic_publish
3703
+ )
3704
+
3705
+ if ErrorHandler.has_errors(response_data):
3706
+ result = ErrorHandler.extract_error(response_data)
3707
+ else:
3708
+ result = AgenticProcessMapper.map_to_agentic_process(response_data)
3709
+
3710
+ return result
3711
+
3712
+ def update_process(
3713
+ self,
3714
+ project_id: str,
3715
+ process: AgenticProcess,
3716
+ automatic_publish: bool = False,
3717
+ upsert: bool = False
3718
+ ) -> Union[AgenticProcess, ErrorListResponse]:
3719
+ '''
3720
+ Updates an existing process in the specified project or upserts it if specified.
3721
+
3722
+ :param project_id: str - Unique identifier of the project.
3723
+ :param process: AgenticProcess - The process configuration to update.
3724
+ :param automatic_publish: bool - Whether to publish the process after updating. Defaults to False.
3725
+ :param upsert: bool - Whether to insert the process if it does not exist. Defaults to False.
3726
+ :return: Union[AgenticProcess, ErrorListResponse] - The updated process if successful, or an error response.
3727
+ '''
3728
+ response_data = self.__process_client.update_process(
3729
+ project_id=project_id,
3730
+ process_id=process.id,
3731
+ name=process.name,
3732
+ key=process.key,
3733
+ description=process.description,
3734
+ kb=process.kb.to_dict(),
3735
+ agentic_activities=[activity.to_dict() for activity in process.agentic_activities] if process.agentic_activities else None,
3736
+ artifact_signals=[signal.to_dict() for signal in process.artifact_signals] if process.artifact_signals else None,
3737
+ user_signals=[signal.to_dict() for signal in process.user_signals] if process.user_signals else None,
3738
+ start_event=process.start_event.to_dict(),
3739
+ end_event=process.end_event.to_dict(),
3740
+ sequence_flows=[flow.to_dict() for flow in process.sequence_flows] if process.sequence_flows else None,
3741
+ variables=[variable.to_dict() for variable in process.variables] if process.variables else None,
3742
+ automatic_publish=automatic_publish,
3743
+ upsert=upsert
3744
+ )
3745
+
3746
+ if ErrorHandler.has_errors(response_data):
3747
+ result = ErrorHandler.extract_error(response_data)
3748
+ else:
3749
+ result = AgenticProcessMapper.map_to_agentic_process(response_data)
3750
+
3751
+ return result
3752
+
3753
+ def get_process(
3754
+ self,
3755
+ project_id: str,
3756
+ process_id: Optional[str] = None,
3757
+ process_name: Optional[str] = None,
3758
+ filter_settings: Optional[FilterSettings] = None
3759
+ ) -> Union[AgenticProcess, ErrorListResponse]:
3760
+ '''
3761
+ Retrieves details of a specific process in the specified project.
3762
+
3763
+ :param project_id: str - Unique identifier of the project.
3764
+ :param process_id: Optional[str] - Unique identifier of the process to retrieve. Defaults to None.
3765
+ :param process_name: Optional[str] - Name of the process to retrieve. Defaults to None.
3766
+ :param filter_settings: Optional[FilterSettings] - Settings to filter the process retrieval (revision, version, allow_drafts).
3767
+ :return: Union[AgenticProcess, ErrorListResponse] - The retrieved process if successful, or an error response.
3768
+ :raises ValueError: If neither process_id nor process_name is provided.
3769
+ '''
3770
+ if not (process_id or process_name):
3771
+ raise ValueError("Either process_id or process_name must be provided.")
3772
+
3773
+ filter_settings = filter_settings or FilterSettings(revision="0", version="0", allow_drafts=True)
3774
+ response_data = self.__process_client.get_process(
3775
+ project_id=project_id,
3776
+ process_id=process_id,
3777
+ process_name=process_name,
3778
+ revision=filter_settings.revision,
3779
+ version=filter_settings.version,
3780
+ allow_drafts=filter_settings.allow_drafts
3781
+ )
3782
+
3783
+ if ErrorHandler.has_errors(response_data):
3784
+ result = ErrorHandler.extract_error(response_data)
3785
+ else:
3786
+ result = AgenticProcessMapper.map_to_agentic_process(response_data)
3787
+
3788
+ return result
3789
+
3790
+ def list_processes(
3791
+ self,
3792
+ project_id: str,
3793
+ filter_settings: Optional[FilterSettings] = None
3794
+ ) -> Union[AgenticProcessList, ErrorListResponse]:
3795
+ '''
3796
+ Retrieves a list of processes in the specified project.
3797
+
3798
+ :param project_id: str - Unique identifier of the project.
3799
+ :param filter_settings: Optional[FilterSettings] - Settings to filter the process list (id, name, status, start, count, allow_drafts).
3800
+ :return: Union[AgenticProcessList, ErrorListResponse] - The list of processes if successful, or an error response.
3801
+ '''
3802
+ filter_settings = filter_settings or FilterSettings(start="0", count="100", allow_drafts=True)
3803
+ response_data = self.__process_client.list_processes(
3804
+ project_id=project_id,
3805
+ id=filter_settings.id,
3806
+ name=filter_settings.name,
3807
+ status=filter_settings.status,
3808
+ start=filter_settings.start,
3809
+ count=filter_settings.count,
3810
+ allow_draft=filter_settings.allow_drafts
3811
+ )
3812
+
3813
+ if ErrorHandler.has_errors(response_data):
3814
+ result = ErrorHandler.extract_error(response_data)
3815
+ else:
3816
+ result = AgenticProcessMapper.map_to_agentic_process_list(response_data)
3817
+
3818
+ return result
3819
+
3820
+ def list_process_instances(
3821
+ self,
3822
+ project_id: str,
3823
+ process_id: str,
3824
+ filter_settings: Optional[FilterSettings] = None
3825
+ ) -> Union[ProcessInstanceList, ErrorListResponse]:
3826
+ '''
3827
+ Retrieves a list of process instances for a specific process in the specified project.
3828
+
3829
+ :param project_id: str - Unique identifier of the project.
3830
+ :param process_id: str - Unique identifier of the process to list instances for.
3831
+ :param filter_settings: Optional[FilterSettings] - Settings to filter the instance list (is_active, start, count).
3832
+ :return: Union[ProcessInstanceList, ErrorListResponse] - The list of process instances if successful, or an error response.
3833
+ '''
3834
+ filter_settings = filter_settings or FilterSettings(start="0", count="10", is_active=True)
3835
+ response_data = self.__process_client.list_process_instances(
3836
+ project_id=project_id,
3837
+ process_id=process_id,
3838
+ is_active=filter_settings.is_active,
3839
+ start=filter_settings.start,
3840
+ count=filter_settings.count
3841
+ )
3842
+
3843
+ if ErrorHandler.has_errors(response_data):
3844
+ result = ErrorHandler.extract_error(response_data)
3845
+ else:
3846
+ result = ProcessInstanceMapper.map_to_process_instance_list(response_data)
3847
+
3848
+ return result
3849
+
3850
+ def delete_process(
3851
+ self,
3852
+ project_id: str,
3853
+ process_id: Optional[str] = None,
3854
+ process_name: Optional[str] = None
3855
+ ) -> Union[EmptyResponse, ErrorListResponse]:
3856
+ '''
3857
+ Deletes a specific process in the specified project.
3858
+
3859
+ :param project_id: str - Unique identifier of the project.
3860
+ :param process_id: Optional[str] - Unique identifier of the process to delete. Defaults to None.
3861
+ :param process_name: Optional[str] - Name of the process to delete. Defaults to None.
3862
+ :return: Union[EmptyResponse, ErrorListResponse] - Empty response if successful, or an error response.
3863
+ :raises ValueError: If neither process_id nor process_name is provided.
3864
+ '''
3865
+ if not (process_id or process_name):
3866
+ raise ValueError("Either process_id or process_name must be provided.")
3867
+
3868
+ response_data = self.__process_client.delete_process(
3869
+ project_id=project_id,
3870
+ process_id=process_id,
3871
+ process_name=process_name
3872
+ )
3873
+
3874
+ if ErrorHandler.has_errors(response_data):
3875
+ result = ErrorHandler.extract_error(response_data)
3876
+ else:
3877
+ result = ResponseMapper.map_to_empty_response(response_data or "Process deleted successfully")
3878
+
3879
+ return result
3880
+
3881
+ def publish_process_revision(
3882
+ self,
3883
+ project_id: str,
3884
+ process_id: Optional[str] = None,
3885
+ process_name: Optional[str] = None,
3886
+ revision: str = None
3887
+ ) -> Union[AgenticProcess, ErrorListResponse]:
3888
+ '''
3889
+ Publishes a specific revision of a process in the specified project.
3890
+
3891
+ :param project_id: str - Unique identifier of the project.
3892
+ :param process_id: Optional[str] - Unique identifier of the process to publish. Defaults to None.
3893
+ :param process_name: Optional[str] - Name of the process to publish. Defaults to None.
3894
+ :param revision: str - Revision of the process to publish. Defaults to None.
3895
+ :return: Union[AgenticProcess, ErrorListResponse] - The published process if successful, or an error response.
3896
+ :raises ValueError: If neither process_id nor process_name is provided, or if revision is not specified.
3897
+ '''
3898
+ if not (process_id or process_name) or not revision:
3899
+ raise ValueError("Either process_id or process_name and revision must be provided.")
3900
+
3901
+ response_data = self.__process_client.publish_process_revision(
3902
+ project_id=project_id,
3903
+ process_id=process_id,
3904
+ process_name=process_name,
3905
+ revision=revision
3906
+ )
3907
+
3908
+ if ErrorHandler.has_errors(response_data):
3909
+ result = ErrorHandler.extract_error(response_data)
3910
+ else:
3911
+ result = AgenticProcessMapper.map_to_agentic_process(response_data)
3912
+
3913
+ return result
3914
+
3915
+ def create_task(
3916
+ self,
3917
+ project_id: str,
3918
+ task: Task,
3919
+ automatic_publish: bool = False
3920
+ ) -> Union[Task, ErrorListResponse]:
3921
+ '''
3922
+ Creates a new task in the specified project.
3923
+
3924
+ :param project_id: str - Unique identifier of the project where the task will be created.
3925
+ :param task: Task - The task configuration to create, including name (required), description,
3926
+ title_template, id, prompt_data, and artifact_types. Optional fields are included if set.
3927
+ :param automatic_publish: bool - Whether to publish the task after creation. Defaults to False.
3928
+ :return: Union[Task, ErrorListResponse] - The created task if successful, or an error response.
3929
+ '''
3930
+ response_data = self.__process_client.create_task(
3931
+ project_id=project_id,
3932
+ name=task.name,
3933
+ description=task.description,
3934
+ title_template=task.title_template,
3935
+ id=task.id,
3936
+ prompt_data=task.prompt_data.to_dict() if task.prompt_data else None,
3937
+ artifact_types=task.artifact_types.to_dict() if task.artifact_types else None,
3938
+ automatic_publish=automatic_publish
3939
+ )
3940
+
3941
+ if ErrorHandler.has_errors(response_data):
3942
+ result = ErrorHandler.extract_error(response_data)
3943
+ else:
3944
+ result = TaskMapper.map_to_task(response_data)
3945
+
3946
+ return result
3947
+
3948
+ def get_task(
3949
+ self,
3950
+ project_id: str,
3951
+ task_id: Optional[str] = None,
3952
+ task_name: Optional[str] = None
3953
+ ) -> Union[Task, ErrorListResponse]:
3954
+ '''
3955
+ Retrieves details of a specific task in the specified project.
3956
+
3957
+ :param project_id: str - Unique identifier of the project.
3958
+ :param task_id: Optional[str] - Unique identifier of the task to retrieve. Defaults to None.
3959
+ :param task_name: Optional[str] - Name of the task to retrieve. Defaults to None.
3960
+ :return: Union[Task, ErrorListResponse] - The retrieved task if successful, or an error response.
3961
+ :raises ValueError: If neither task_id nor task_name is provided.
3962
+ '''
3963
+ if not (task_id or task_name):
3964
+ raise ValueError("Either task_id or task_name must be provided.")
3965
+
3966
+ response_data = self.__process_client.get_task(
3967
+ project_id=project_id,
3968
+ task_id=task_id,
3969
+ task_name=task_name
3970
+ )
3971
+
3972
+ if ErrorHandler.has_errors(response_data):
3973
+ result = ErrorHandler.extract_error(response_data)
3974
+ else:
3975
+ result = TaskMapper.map_to_task(response_data)
3976
+
3977
+ return result
3978
+
3979
+ def list_tasks(
3980
+ self,
3981
+ project_id: str,
3982
+ filter_settings: Optional[FilterSettings] = None
3983
+ ) -> Union[TaskList, ErrorListResponse]:
3984
+ '''
3985
+ Retrieves a list of tasks in the specified project.
3986
+
3987
+ :param project_id: str - Unique identifier of the project.
3988
+ :param filter_settings: Optional[FilterSettings] - Settings to filter the task list (id, start, count, allow_drafts).
3989
+ :return: Union[TaskList, ErrorListResponse] - The list of tasks if successful, or an error response.
3990
+ '''
3991
+ filter_settings = filter_settings or FilterSettings(start="0", count="100", allow_drafts=True)
3992
+ response_data = self.__process_client.list_tasks(
3993
+ project_id=project_id,
3994
+ id=filter_settings.id,
3995
+ start=filter_settings.start,
3996
+ count=filter_settings.count,
3997
+ allow_drafts=filter_settings.allow_drafts
3998
+ )
3999
+
4000
+ if ErrorHandler.has_errors(response_data):
4001
+ result = ErrorHandler.extract_error(response_data)
4002
+ else:
4003
+ result = TaskMapper.map_to_task_list(response_data)
4004
+
4005
+ return result
4006
+
4007
+ def update_task(
4008
+ self,
4009
+ project_id: str,
4010
+ task: Task,
4011
+ automatic_publish: bool = False,
4012
+ upsert: bool = False
4013
+ ) -> Union[Task, ErrorListResponse]:
4014
+ '''
4015
+ Updates an existing task in the specified project or upserts it if specified.
4016
+
4017
+ :param project_id: str - Unique identifier of the project where the task resides.
4018
+ :param task: Task - The task configuration to update, including id (required), name, description,
4019
+ title_template, prompt_data, and artifact_types. Optional fields are included if set.
4020
+ :param automatic_publish: bool - Whether to publish the task after updating. Defaults to False.
4021
+ :param upsert: bool - Whether to insert the task if it does not exist. Defaults to False.
4022
+ :return: Union[Task, ErrorListResponse] - The updated task if successful, or an error response.
4023
+ :raises ValueError: If task.id is not provided.
4024
+ '''
4025
+ if not task.id:
4026
+ raise ValueError("Task ID must be provided for update.")
4027
+
4028
+ response_data = self.__process_client.update_task(
4029
+ project_id=project_id,
4030
+ task_id=task.id,
4031
+ name=task.name,
4032
+ description=task.description,
4033
+ title_template=task.title_template,
4034
+ id=task.id,
4035
+ prompt_data=task.prompt_data.to_dict() if task.prompt_data else None,
4036
+ artifact_types=task.artifact_types.to_dict() if task.artifact_types else None,
4037
+ automatic_publish=automatic_publish,
4038
+ upsert=upsert
4039
+ )
4040
+
4041
+ if ErrorHandler.has_errors(response_data):
4042
+ result = ErrorHandler.extract_error(response_data)
4043
+ else:
4044
+ result = TaskMapper.map_to_task(response_data)
4045
+
4046
+ return result
4047
+
4048
+ def delete_task(
4049
+ self,
4050
+ project_id: str,
4051
+ task_id: Optional[str] = None,
4052
+ task_name: Optional[str] = None
4053
+ ) -> Union[EmptyResponse, ErrorListResponse]:
4054
+ '''
4055
+ Deletes a specific task in the specified project.
4056
+
4057
+ :param project_id: str - Unique identifier of the project.
4058
+ :param task_id: Optional[str] - Unique identifier of the task to delete. Defaults to None.
4059
+ :param task_name: Optional[str] - Name of the task to delete. Defaults to None.
4060
+ :return: Union[EmptyResponse, ErrorListResponse] - Empty response if successful, or an error response.
4061
+ :raises ValueError: If neither task_id nor task_name is provided.
4062
+ '''
4063
+ if not (task_id or task_name):
4064
+ raise ValueError("Either task_id or task_name must be provided.")
4065
+
4066
+ response_data = self.__process_client.delete_task(
4067
+ project_id=project_id,
4068
+ task_id=task_id,
4069
+ task_name=task_name
4070
+ )
4071
+
4072
+ if ErrorHandler.has_errors(response_data):
4073
+ result = ErrorHandler.extract_error(response_data)
4074
+ else:
4075
+ result = ResponseMapper.map_to_empty_response(response_data or "Task deleted successfully")
4076
+
4077
+ return result
4078
+
4079
+ def publish_task_revision(
4080
+ self,
4081
+ project_id: str,
4082
+ task_id: Optional[str] = None,
4083
+ task_name: Optional[str] = None,
4084
+ revision: str = None
4085
+ ) -> Union[Task, ErrorListResponse]:
4086
+ '''
4087
+ Publishes a specific revision of a task in the specified project.
4088
+
4089
+ :param project_id: str - Unique identifier of the project.
4090
+ :param task_id: Optional[str] - Unique identifier of the task to publish. Defaults to None.
4091
+ :param task_name: Optional[str] - Name of the task to publish. Defaults to None.
4092
+ :param revision: str - Revision of the task to publish. Defaults to None.
4093
+ :return: Union[Task, ErrorListResponse] - The published task if successful, or an error response.
4094
+ :raises ValueError: If neither task_id nor task_name is provided, or if revision is not specified.
4095
+ '''
4096
+ if not (task_id or task_name) or not revision:
4097
+ raise ValueError("Either task_id or task_name and revision must be provided.")
4098
+
4099
+ response_data = self.__process_client.publish_task_revision(
4100
+ project_id=project_id,
4101
+ task_id=task_id,
4102
+ task_name=task_name,
4103
+ revision=revision
4104
+ )
4105
+
4106
+ if ErrorHandler.has_errors(response_data):
4107
+ result = ErrorHandler.extract_error(response_data)
4108
+ else:
4109
+ result = TaskMapper.map_to_task(response_data)
4110
+
4111
+ return result
4112
+
4113
+ def start_instance(
4114
+ self,
4115
+ project_id: str,
4116
+ process_name: str,
4117
+ subject: Optional[str] = None,
4118
+ variables: Optional[List[Variable] | VariableList] = None
4119
+ ) -> Union[ProcessInstance, ErrorListResponse]:
4120
+ '''
4121
+ Starts a new process instance in the specified project.
4122
+
4123
+ :param project_id: str - Unique identifier of the project.
4124
+ :param process_name: str - Name of the process to start an instance for.
4125
+ :param subject: Optional[str] - Subject of the process instance. Defaults to None.
4126
+ :param variables: Optional[List[dict]] - List of variables for the instance. Defaults to None.
4127
+ :return: Union[StartInstanceResponse, ErrorListResponse] - The started instance if successful, or an error response.
4128
+ '''
4129
+ if not isinstance(variables, VariableList):
4130
+ variables = VariableList(variables=variables)
4131
+
4132
+ response_data = self.__process_client.start_instance(
4133
+ project_id=project_id,
4134
+ process_name=process_name,
4135
+ subject=subject,
4136
+ variables=variables.to_dict()
4137
+ )
4138
+
4139
+ if ErrorHandler.has_errors(response_data):
4140
+ result = ErrorHandler.extract_error(response_data)
4141
+ else:
4142
+ result = ProcessInstanceMapper.map_to_process_instance(response_data)
4143
+
4144
+ return result
4145
+
4146
+ def abort_instance(
4147
+ self,
4148
+ project_id: str,
4149
+ instance_id: str
4150
+ ) -> Union[EmptyResponse, ErrorListResponse]:
4151
+ '''
4152
+ Aborts a specific process instance in the specified project.
4153
+
4154
+ :param project_id: str - Unique identifier of the project.
4155
+ :param instance_id: str - Unique identifier of the instance to abort.
4156
+ :return: Union[EmptyResponse, ErrorListResponse] - Empty response if successful, or an error response.
4157
+ :raises ValueError: If instance_id is not provided.
4158
+ '''
4159
+ if not instance_id:
4160
+ raise ValueError("Instance ID must be provided.")
4161
+
4162
+ response_data = self.__process_client.abort_instance(
4163
+ project_id=project_id,
4164
+ instance_id=instance_id
4165
+ )
4166
+
4167
+ if ErrorHandler.has_errors(response_data):
4168
+ result = ErrorHandler.extract_error(response_data)
4169
+ else:
4170
+ result = ResponseMapper.map_to_empty_response(response_data or "Instance aborted successfully")
4171
+
4172
+ return result
4173
+
4174
+ def get_instance(
4175
+ self,
4176
+ project_id: str,
4177
+ instance_id: str
4178
+ ) -> Union[ProcessInstance, ErrorListResponse]:
4179
+ '''
4180
+ Retrieves details of a specific process instance in the specified project.
4181
+
4182
+ :param project_id: str - Unique identifier of the project.
4183
+ :param instance_id: str - Unique identifier of the instance to retrieve.
4184
+ :return: Union[ProcessInstance, ErrorListResponse] - The retrieved instance if successful, or an error response.
4185
+ :raises ValueError: If instance_id is not provided.
4186
+ '''
4187
+ if not instance_id:
4188
+ raise ValueError("Instance ID must be provided.")
4189
+
4190
+ response_data = self.__process_client.get_instance(
4191
+ project_id=project_id,
4192
+ instance_id=instance_id
4193
+ )
4194
+ if ErrorHandler.has_errors(response_data):
4195
+ result = ErrorHandler.extract_error(response_data)
4196
+ else:
4197
+ result = ProcessInstanceMapper.map_to_process_instance(response_data)
4198
+
4199
+ return result
4200
+
4201
+ def get_instance_history(
4202
+ self,
4203
+ project_id: str,
4204
+ instance_id: str
4205
+ ) -> Union[dict, ErrorListResponse]:
4206
+ '''
4207
+ Retrieves the history of a specific process instance in the specified project.
4208
+
4209
+ :param project_id: str - Unique identifier of the project.
4210
+ :param instance_id: str - Unique identifier of the instance to retrieve history for.
4211
+ :return: Union[dict, ErrorListResponse] - The instance history if successful, or an error response.
4212
+ :raises ValueError: If instance_id is not provided.
4213
+ '''
4214
+ if not instance_id:
4215
+ raise ValueError("Instance ID must be provided.")
4216
+
4217
+ response_data = self.__process_client.get_instance_history(
4218
+ project_id=project_id,
4219
+ instance_id=instance_id
4220
+ )
4221
+
4222
+ if ErrorHandler.has_errors(response_data):
4223
+ result = ErrorHandler.extract_error(response_data)
4224
+ else:
4225
+ result = response_data
4226
+
4227
+ return result
4228
+
4229
+ def get_thread_information(
4230
+ self,
4231
+ project_id: str,
4232
+ thread_id: str
4233
+ ) -> Union[dict, ErrorListResponse]:
4234
+ '''
4235
+ Retrieves information about a specific thread in the specified project.
4236
+
4237
+ :param project_id: str - Unique identifier of the project.
4238
+ :param thread_id: str - Unique identifier of the thread to retrieve information for.
4239
+ :return: Union[dict, ErrorListResponse] - The thread information if successful, or an error response.
4240
+ :raises ValueError: If thread_id is not provided.
4241
+ '''
4242
+ if not thread_id:
4243
+ raise ValueError("Thread ID must be provided.")
4244
+
4245
+ response_data = self.__process_client.get_thread_information(
4246
+ project_id=project_id,
4247
+ thread_id=thread_id
4248
+ )
4249
+
4250
+ if ErrorHandler.has_errors(response_data):
4251
+ result = ErrorHandler.extract_error(response_data)
4252
+ else:
4253
+ result = response_data
4254
+
4255
+ return result
4256
+
4257
+ def send_user_signal(
4258
+ self,
4259
+ project_id: str,
4260
+ instance_id: str,
4261
+ signal_name: str
4262
+ ) -> Union[EmptyResponse, ErrorListResponse]:
4263
+ '''
4264
+ Sends a user signal to a specific process instance in the specified project.
4265
+
4266
+ :param project_id: str - Unique identifier of the project.
4267
+ :param instance_id: str - Unique identifier of the instance to send the signal to.
4268
+ :param signal_name: str - Name of the user signal to send.
4269
+ :return: Union[EmptyResponse, ErrorListResponse] - Empty response if successful, or an error response.
4270
+ :raises ValueError: If instance_id or signal_name is not provided.
4271
+ '''
4272
+ if not instance_id or not signal_name:
4273
+ raise ValueError("Instance ID and signal name must be provided.")
4274
+
4275
+ response_data = self.__process_client.send_user_signal(
4276
+ project_id=project_id,
4277
+ instance_id=instance_id,
4278
+ signal_name=signal_name
4279
+ )
4280
+
4281
+ if ErrorHandler.has_errors(response_data):
4282
+ result = ErrorHandler.extract_error(response_data)
4283
+ else:
4284
+ result = ResponseMapper.map_to_empty_response(response_data or "Signal sent successfully")
4285
+
4286
+ return result
4287
+
4288
+ def create_knowledge_base(
4289
+ self,
4290
+ project_id: str,
4291
+ knowledge_base: KnowledgeBase,
4292
+ ) -> Union[KnowledgeBase, ErrorListResponse]:
4293
+ '''
4294
+ Creates a new knowledge base in the specified project using the provided configuration.
4295
+
4296
+ This method sends a request to the process client to create a knowledge base based on
4297
+ the attributes of the provided `KnowledgeBase` object. If the response contains errors, it
4298
+ maps them to an `ErrorListResponse`. Otherwise, it maps the response to a `KnowledgeBase` object.
4299
+
4300
+ :param project_id: str - Unique identifier of the project where the knowledge base will be created.
4301
+ :param knowledge_base: KnowledgeBase - The knowledge base configuration object containing name
4302
+ and artifact type names.
4303
+ :return: Union[KnowledgeBase, ErrorListResponse] - A `KnowledgeBase` object representing the created
4304
+ knowledge base if successful, or an `ErrorListResponse` if the API returns errors.
4305
+ '''
4306
+ response_data = self.__process_client.create_kb(
4307
+ project_id=project_id,
4308
+ name=knowledge_base.name,
4309
+ artifacts=knowledge_base.artifacts if knowledge_base.artifacts else None,
4310
+ metadata=knowledge_base.metadata if knowledge_base.metadata else None
4311
+ )
4312
+ if ErrorHandler.has_errors(response_data):
4313
+ result = ErrorHandler.extract_error(response_data)
4314
+ else:
4315
+ result = KnowledgeBaseMapper.map_to_knowledge_base(response_data)
4316
+
4317
+ return result
4318
+
4319
+ def list_knowledge_bases(
4320
+ self,
4321
+ project_id: str,
4322
+ name: Optional[str] = None,
4323
+ start: Optional[int] = 0,
4324
+ count: Optional[int] = 10
4325
+ ) -> Union[KnowledgeBaseList, ErrorListResponse]:
4326
+ '''
4327
+ Retrieves a list of knowledge bases for the specified project.
4328
+
4329
+ This method queries the process client to fetch a list of knowledge bases associated
4330
+ with the specified project ID, applying optional filters for name and pagination. If the
4331
+ response contains errors, it maps them to an `ErrorListResponse`. Otherwise, it maps the
4332
+ response to a `KnowledgeBaseList`.
4333
+
4334
+ :param project_id: str - Unique identifier of the project to retrieve knowledge bases for.
4335
+ :param name: Optional[str] - Name filter to narrow down the list of knowledge bases.
4336
+ :param start: Optional[int] - Starting index for pagination, defaults to 0.
4337
+ :param count: Optional[int] - Number of knowledge bases to return, defaults to 10.
4338
+ :return: Union[KnowledgeBaseList, ErrorListResponse] - A `KnowledgeBaseList` containing the
4339
+ retrieved knowledge bases if successful, or an `ErrorListResponse` if the API returns errors.
4340
+ '''
4341
+ response_data = self.__process_client.list_kbs(
4342
+ project_id=project_id,
4343
+ name=name,
4344
+ start=start,
4345
+ count=count
4346
+ )
4347
+ if ErrorHandler.has_errors(response_data):
4348
+ result = ErrorHandler.extract_error(response_data)
4349
+ else:
4350
+ result = KnowledgeBaseMapper.map_to_knowledge_base_list(response_data)
4351
+
4352
+ return result
4353
+
4354
+ def get_knowledge_base(
4355
+ self,
4356
+ project_id: str,
4357
+ kb_name: Optional[str] = None,
4358
+ kb_id: Optional[str] = None
4359
+ ) -> Union[KnowledgeBase, ErrorListResponse]:
4360
+ '''
4361
+ Retrieves details of a specific knowledge base from the specified project.
4362
+
4363
+ This method sends a request to the process client to retrieve a knowledge base
4364
+ identified by either `kb_name` or `kb_id`. If the response contains errors, it maps them to
4365
+ an `ErrorListResponse`. Otherwise, it maps the response to a `KnowledgeBase` object.
4366
+
4367
+ :param project_id: str - Unique identifier of the project where the knowledge base resides.
4368
+ :param kb_name: Optional[str] - Name of the knowledge base to retrieve.
4369
+ :param kb_id: Optional[str] - Unique identifier of the knowledge base to retrieve.
4370
+ :return: Union[KnowledgeBase, ErrorListResponse] - A `KnowledgeBase` object representing the
4371
+ retrieved knowledge base if successful, or an `ErrorListResponse` if the API returns errors.
4372
+ :raises ValueError: If neither `kb_name` nor `kb_id` is provided.
4373
+ '''
4374
+ if not (kb_name or kb_id):
4375
+ raise ValueError("Either kb_name or kb_id must be provided.")
4376
+
4377
+ response_data = self.__process_client.get_kb(
4378
+ project_id=project_id,
4379
+ kb_name=kb_name,
4380
+ kb_id=kb_id
4381
+ )
4382
+ if ErrorHandler.has_errors(response_data):
4383
+ result = ErrorHandler.extract_error(response_data)
4384
+ else:
4385
+ result = KnowledgeBaseMapper.map_to_knowledge_base(response_data)
4386
+
4387
+ return result
4388
+
4389
+ def delete_knowledge_base(
4390
+ self,
4391
+ project_id: str,
4392
+ kb_name: Optional[str] = None,
4393
+ kb_id: Optional[str] = None
4394
+ ) -> Union[EmptyResponse, ErrorListResponse]:
4395
+ '''
4396
+ Deletes a specific knowledge base from the specified project.
4397
+
4398
+ This method sends a request to the process client to delete a knowledge base
4399
+ identified by either `kb_name` or `kb_id`. Returns an `EmptyResponse` if the deletion is
4400
+ successful, or an `ErrorListResponse` if the API returns errors.
4401
+
4402
+ :param project_id: str - Unique identifier of the project where the knowledge base resides.
4403
+ :param kb_name: Optional[str] - Name of the knowledge base to delete.
4404
+ :param kb_id: Optional[str] - Unique identifier of the knowledge base to delete.
4405
+ :return: Union[EmptyResponse, ErrorListResponse] - `EmptyResponse` if the knowledge base was
4406
+ deleted successfully, or an `ErrorListResponse` if the API returns errors.
4407
+ :raises ValueError: If neither `kb_name` nor `kb_id` is provided.
4408
+ '''
4409
+ if not (kb_name or kb_id):
4410
+ raise ValueError("Either kb_name or kb_id must be provided.")
4411
+
4412
+ response_data = self.__process_client.delete_kb(
4413
+ project_id=project_id,
4414
+ kb_name=kb_name,
4415
+ kb_id=kb_id
4416
+ )
4417
+ if ErrorHandler.has_errors(response_data):
4418
+ result = ErrorHandler.extract_error(response_data)
4419
+ else:
4420
+ response_data = response_data if response_data else "Knowledge base deleted successfully"
4421
+ result = ResponseMapper.map_to_empty_response(response_data)
4422
+
4423
+ return result
4424
+
4425
+ def list_jobs(
4426
+ self,
4427
+ project_id: str,
4428
+ filter_settings: Optional[FilterSettings] = None,
4429
+ topic: Optional[str] = None,
4430
+ token: Optional[str] = None
4431
+ ) -> Union[JobList, ErrorListResponse]:
4432
+ '''
4433
+ Retrieves a list of jobs in the specified project.
4434
+
4435
+ This method queries the process client to fetch a list of jobs associated with the specified
4436
+ project ID, applying optional filter settings. If the response contains errors,
4437
+ it maps them to an `ErrorListResponse`. Otherwise, it maps the response to a `JobList`.
4438
+
4439
+ :param project_id: str - Unique identifier of the project.
4440
+ :param filter_settings: Optional[FilterSettings] - Settings to filter the job list (start, count).
4441
+ :param topic: Optional[str] - Topic to filter the jobs (e.g., 'Default', 'Event'). Defaults to None.
4442
+ :param token: Optional[str] - Unique token identifier to filter a specific job. Defaults to None.
4443
+ :return: Union[JobList, ErrorListResponse] - A `JobList` containing the retrieved jobs if successful,
4444
+ or an `ErrorListResponse` if the API returns errors.
4445
+ :raises ValueError: If project_id is not provided.
4446
+ '''
4447
+ if not project_id:
4448
+ raise ValueError("Project ID must be provided.")
4449
+
4450
+ filter_settings = filter_settings or FilterSettings(start="0", count="100")
4451
+ response_data = self.__process_client.list_jobs(
4452
+ project_id=project_id,
4453
+ start=filter_settings.start,
4454
+ count=filter_settings.count,
4455
+ topic=topic,
4456
+ token=token,
4457
+ name=filter_settings.name
4458
+ )
4459
+
4460
+ if ErrorHandler.has_errors(response_data):
4461
+ result = ErrorHandler.extract_error(response_data)
4462
+ else:
4463
+ result = JobMapper.map_to_job_list(response_data)
4464
+
4465
+ return result
4466
+
4467
+ For any other question regarding the command line interface or the debugger, refer the user to the PyGEAI CLI Expert, another
4468
+ Agent specialized in answering those types of questions.
4469
+
4470
+ """
4471
+
4472
+ agent_id = "1765d89b-6111-4780-8ef6-662b108cb96c"
4473
+
4474
+ agent = Agent(
4475
+ id=agent_id,
4476
+ status="active",
4477
+ name="PyGEAI LAB Expert",
4478
+ access_scope="public",
4479
+ public_name="com.globant.geai.pygeai_lab_expert",
4480
+ job_description="Assists with PyGEAI LAB queries",
4481
+ avatar_image="https://www.shareicon.net/data/128x128/2016/11/09/851447_logo_512x512.png",
4482
+ description="Expert agent for the Globant Enterprise AI Lab, providing guidance on using the PyGEAI SDK to manage agents, tools, reasoning strategies, processes, tasks, and runtime instances.",
4483
+ is_draft=False,
4484
+ is_readonly=False,
4485
+ revision=1,
4486
+ version=None,
4487
+ agent_data=AgentData(
4488
+ prompt=Prompt(
4489
+ instructions=f"""\
4490
+ You are an expert assistant for the Globant Enterprise AI Lab, designed to answer queries about using the PyGEAI SDK. Use the GEAI CLI documentation as your knowledge base to provide accurate, clear, and concise responses in plain text. Tailor the response tone based on the 'style' input (formal or informal). If the query is unclear, ask for clarification. Provide examples where relevant. If an error code is mentioned, explain its meaning and suggest solutions.
4491
+ IMPORTANT: Answers should be short, clear, and concise.
4492
+
4493
+ The documentation is provided below for reference:
4494
+
4495
+ {GEAI_LAB_HELP}
4496
+
4497
+ Respond with a detailed answer to the query and a brief summary. Ensure responses are accurate and aligned with the documentation.
4498
+ """,
4499
+ inputs=["query", "style"],
4500
+ outputs=[
4501
+ PromptOutput(key="response", description="Answer to the user's query about PyGEAI SDK usage, in plain text."),
4502
+ ],
4503
+ examples=[
4504
+ PromptExample(
4505
+ input_data="How do I create a new agent using PyGEAI SDK? [formal]",
4506
+ output="Use the AILabManager's `create_agent` method, specifying the project ID and an Agent object with attributes like name, prompts, and LLM configurations. Example: `manager.create_agent(project_id='proj123', agent=Agent(id=str(uuid.uuid4()), name='MyAgent', agent_data=AgentData(prompt=Prompt(instructions='...'))))`."
4507
+ ),
4508
+ PromptExample(
4509
+ input_data="What does error code 403 mean in PyGEAI? [informal]",
4510
+ output="Error 403 means 'Forbidden'. It usually pops up when you don't have permission for that action. Check your API key's access scope with `geai configure --key <your_key>` or verify your role in the project with `geai organization list-members`."
4511
+ ),
4512
+ PromptExample(
4513
+ input_data="How to list all tools in a project? [formal]",
4514
+ output="To list all tools in a project, use the AILabManager's `list_tools` method: `manager.list_tools(project_id='proj123')`. Alternatively, use the CLI command: `geai organization list-tools --organization-id org123 --project-id proj123`. Ensure your API key is configured with `geai configure`."
4515
+ ),
4516
+ PromptExample(
4517
+ input_data="How do I start a process instance? [formal]",
4518
+ output="Use the AILabManager's `start_instance` method, specifying the process ID and project ID. Example: `manager.start_instance(project_id='proj123', process_id='proc456')`. Alternatively, use the CLI: `geai process start-instance --project-id proj123 --process-id proc456`."
4519
+ )
4520
+ ]
4521
+ ),
4522
+ llm_config=LlmConfig(
4523
+ max_tokens=5000,
4524
+ timeout=0,
4525
+ sampling=Sampling(temperature=0.7, top_k=0, top_p=0)
4526
+ ),
4527
+ models=[Model(name="openai/gpt-4.1")]
4528
+ )
4529
+ )
4530
+
4531
+ manager = AILabManager()
4532
+ result = manager.update_agent(
4533
+ project_id="2ca6883f-6778-40bb-bcc1-85451fb11107",
4534
+ agent=agent,
4535
+ automatic_publish=False
4536
+ )
4537
+
4538
+ if isinstance(result, Agent):
4539
+ print(f"Agent created successfully: {agent.to_dict()}")
4540
+ else:
4541
+ print("Errors:", result.errors)