PraisonAI 3.0.0__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.
Files changed (393) hide show
  1. praisonai/__init__.py +54 -0
  2. praisonai/__main__.py +15 -0
  3. praisonai/acp/__init__.py +54 -0
  4. praisonai/acp/config.py +159 -0
  5. praisonai/acp/server.py +587 -0
  6. praisonai/acp/session.py +219 -0
  7. praisonai/adapters/__init__.py +50 -0
  8. praisonai/adapters/readers.py +395 -0
  9. praisonai/adapters/rerankers.py +315 -0
  10. praisonai/adapters/retrievers.py +394 -0
  11. praisonai/adapters/vector_stores.py +409 -0
  12. praisonai/agent_scheduler.py +337 -0
  13. praisonai/agents_generator.py +903 -0
  14. praisonai/api/call.py +292 -0
  15. praisonai/auto.py +1197 -0
  16. praisonai/capabilities/__init__.py +275 -0
  17. praisonai/capabilities/a2a.py +140 -0
  18. praisonai/capabilities/assistants.py +283 -0
  19. praisonai/capabilities/audio.py +320 -0
  20. praisonai/capabilities/batches.py +469 -0
  21. praisonai/capabilities/completions.py +336 -0
  22. praisonai/capabilities/container_files.py +155 -0
  23. praisonai/capabilities/containers.py +93 -0
  24. praisonai/capabilities/embeddings.py +158 -0
  25. praisonai/capabilities/files.py +467 -0
  26. praisonai/capabilities/fine_tuning.py +293 -0
  27. praisonai/capabilities/guardrails.py +182 -0
  28. praisonai/capabilities/images.py +330 -0
  29. praisonai/capabilities/mcp.py +190 -0
  30. praisonai/capabilities/messages.py +270 -0
  31. praisonai/capabilities/moderations.py +154 -0
  32. praisonai/capabilities/ocr.py +217 -0
  33. praisonai/capabilities/passthrough.py +204 -0
  34. praisonai/capabilities/rag.py +207 -0
  35. praisonai/capabilities/realtime.py +160 -0
  36. praisonai/capabilities/rerank.py +165 -0
  37. praisonai/capabilities/responses.py +266 -0
  38. praisonai/capabilities/search.py +109 -0
  39. praisonai/capabilities/skills.py +133 -0
  40. praisonai/capabilities/vector_store_files.py +334 -0
  41. praisonai/capabilities/vector_stores.py +304 -0
  42. praisonai/capabilities/videos.py +141 -0
  43. praisonai/chainlit_ui.py +304 -0
  44. praisonai/chat/__init__.py +106 -0
  45. praisonai/chat/app.py +125 -0
  46. praisonai/cli/__init__.py +26 -0
  47. praisonai/cli/app.py +213 -0
  48. praisonai/cli/commands/__init__.py +75 -0
  49. praisonai/cli/commands/acp.py +70 -0
  50. praisonai/cli/commands/completion.py +333 -0
  51. praisonai/cli/commands/config.py +166 -0
  52. praisonai/cli/commands/debug.py +142 -0
  53. praisonai/cli/commands/diag.py +55 -0
  54. praisonai/cli/commands/doctor.py +166 -0
  55. praisonai/cli/commands/environment.py +179 -0
  56. praisonai/cli/commands/lsp.py +112 -0
  57. praisonai/cli/commands/mcp.py +210 -0
  58. praisonai/cli/commands/profile.py +457 -0
  59. praisonai/cli/commands/run.py +228 -0
  60. praisonai/cli/commands/schedule.py +150 -0
  61. praisonai/cli/commands/serve.py +97 -0
  62. praisonai/cli/commands/session.py +212 -0
  63. praisonai/cli/commands/traces.py +145 -0
  64. praisonai/cli/commands/version.py +101 -0
  65. praisonai/cli/configuration/__init__.py +18 -0
  66. praisonai/cli/configuration/loader.py +353 -0
  67. praisonai/cli/configuration/paths.py +114 -0
  68. praisonai/cli/configuration/schema.py +164 -0
  69. praisonai/cli/features/__init__.py +268 -0
  70. praisonai/cli/features/acp.py +236 -0
  71. praisonai/cli/features/action_orchestrator.py +546 -0
  72. praisonai/cli/features/agent_scheduler.py +773 -0
  73. praisonai/cli/features/agent_tools.py +474 -0
  74. praisonai/cli/features/agents.py +375 -0
  75. praisonai/cli/features/at_mentions.py +471 -0
  76. praisonai/cli/features/auto_memory.py +182 -0
  77. praisonai/cli/features/autonomy_mode.py +490 -0
  78. praisonai/cli/features/background.py +356 -0
  79. praisonai/cli/features/base.py +168 -0
  80. praisonai/cli/features/capabilities.py +1326 -0
  81. praisonai/cli/features/checkpoints.py +338 -0
  82. praisonai/cli/features/code_intelligence.py +652 -0
  83. praisonai/cli/features/compaction.py +294 -0
  84. praisonai/cli/features/compare.py +534 -0
  85. praisonai/cli/features/cost_tracker.py +514 -0
  86. praisonai/cli/features/debug.py +810 -0
  87. praisonai/cli/features/deploy.py +517 -0
  88. praisonai/cli/features/diag.py +289 -0
  89. praisonai/cli/features/doctor/__init__.py +63 -0
  90. praisonai/cli/features/doctor/checks/__init__.py +24 -0
  91. praisonai/cli/features/doctor/checks/acp_checks.py +240 -0
  92. praisonai/cli/features/doctor/checks/config_checks.py +366 -0
  93. praisonai/cli/features/doctor/checks/db_checks.py +366 -0
  94. praisonai/cli/features/doctor/checks/env_checks.py +543 -0
  95. praisonai/cli/features/doctor/checks/lsp_checks.py +199 -0
  96. praisonai/cli/features/doctor/checks/mcp_checks.py +349 -0
  97. praisonai/cli/features/doctor/checks/memory_checks.py +268 -0
  98. praisonai/cli/features/doctor/checks/network_checks.py +251 -0
  99. praisonai/cli/features/doctor/checks/obs_checks.py +328 -0
  100. praisonai/cli/features/doctor/checks/performance_checks.py +235 -0
  101. praisonai/cli/features/doctor/checks/permissions_checks.py +259 -0
  102. praisonai/cli/features/doctor/checks/selftest_checks.py +322 -0
  103. praisonai/cli/features/doctor/checks/serve_checks.py +426 -0
  104. praisonai/cli/features/doctor/checks/skills_checks.py +231 -0
  105. praisonai/cli/features/doctor/checks/tools_checks.py +371 -0
  106. praisonai/cli/features/doctor/engine.py +266 -0
  107. praisonai/cli/features/doctor/formatters.py +310 -0
  108. praisonai/cli/features/doctor/handler.py +397 -0
  109. praisonai/cli/features/doctor/models.py +264 -0
  110. praisonai/cli/features/doctor/registry.py +239 -0
  111. praisonai/cli/features/endpoints.py +1019 -0
  112. praisonai/cli/features/eval.py +560 -0
  113. praisonai/cli/features/external_agents.py +231 -0
  114. praisonai/cli/features/fast_context.py +410 -0
  115. praisonai/cli/features/flow_display.py +566 -0
  116. praisonai/cli/features/git_integration.py +651 -0
  117. praisonai/cli/features/guardrail.py +171 -0
  118. praisonai/cli/features/handoff.py +185 -0
  119. praisonai/cli/features/hooks.py +583 -0
  120. praisonai/cli/features/image.py +384 -0
  121. praisonai/cli/features/interactive_runtime.py +585 -0
  122. praisonai/cli/features/interactive_tools.py +380 -0
  123. praisonai/cli/features/interactive_tui.py +603 -0
  124. praisonai/cli/features/jobs.py +632 -0
  125. praisonai/cli/features/knowledge.py +531 -0
  126. praisonai/cli/features/lite.py +244 -0
  127. praisonai/cli/features/lsp_cli.py +225 -0
  128. praisonai/cli/features/mcp.py +169 -0
  129. praisonai/cli/features/message_queue.py +587 -0
  130. praisonai/cli/features/metrics.py +211 -0
  131. praisonai/cli/features/n8n.py +673 -0
  132. praisonai/cli/features/observability.py +293 -0
  133. praisonai/cli/features/ollama.py +361 -0
  134. praisonai/cli/features/output_style.py +273 -0
  135. praisonai/cli/features/package.py +631 -0
  136. praisonai/cli/features/performance.py +308 -0
  137. praisonai/cli/features/persistence.py +636 -0
  138. praisonai/cli/features/profile.py +226 -0
  139. praisonai/cli/features/profiler/__init__.py +81 -0
  140. praisonai/cli/features/profiler/core.py +558 -0
  141. praisonai/cli/features/profiler/optimizations.py +652 -0
  142. praisonai/cli/features/profiler/suite.py +386 -0
  143. praisonai/cli/features/profiling.py +350 -0
  144. praisonai/cli/features/queue/__init__.py +73 -0
  145. praisonai/cli/features/queue/manager.py +395 -0
  146. praisonai/cli/features/queue/models.py +286 -0
  147. praisonai/cli/features/queue/persistence.py +564 -0
  148. praisonai/cli/features/queue/scheduler.py +484 -0
  149. praisonai/cli/features/queue/worker.py +372 -0
  150. praisonai/cli/features/recipe.py +1723 -0
  151. praisonai/cli/features/recipes.py +449 -0
  152. praisonai/cli/features/registry.py +229 -0
  153. praisonai/cli/features/repo_map.py +860 -0
  154. praisonai/cli/features/router.py +466 -0
  155. praisonai/cli/features/sandbox_executor.py +515 -0
  156. praisonai/cli/features/serve.py +829 -0
  157. praisonai/cli/features/session.py +222 -0
  158. praisonai/cli/features/skills.py +856 -0
  159. praisonai/cli/features/slash_commands.py +650 -0
  160. praisonai/cli/features/telemetry.py +179 -0
  161. praisonai/cli/features/templates.py +1384 -0
  162. praisonai/cli/features/thinking.py +305 -0
  163. praisonai/cli/features/todo.py +334 -0
  164. praisonai/cli/features/tools.py +680 -0
  165. praisonai/cli/features/tui/__init__.py +83 -0
  166. praisonai/cli/features/tui/app.py +580 -0
  167. praisonai/cli/features/tui/cli.py +566 -0
  168. praisonai/cli/features/tui/debug.py +511 -0
  169. praisonai/cli/features/tui/events.py +99 -0
  170. praisonai/cli/features/tui/mock_provider.py +328 -0
  171. praisonai/cli/features/tui/orchestrator.py +652 -0
  172. praisonai/cli/features/tui/screens/__init__.py +50 -0
  173. praisonai/cli/features/tui/screens/main.py +245 -0
  174. praisonai/cli/features/tui/screens/queue.py +174 -0
  175. praisonai/cli/features/tui/screens/session.py +124 -0
  176. praisonai/cli/features/tui/screens/settings.py +148 -0
  177. praisonai/cli/features/tui/widgets/__init__.py +56 -0
  178. praisonai/cli/features/tui/widgets/chat.py +261 -0
  179. praisonai/cli/features/tui/widgets/composer.py +224 -0
  180. praisonai/cli/features/tui/widgets/queue_panel.py +200 -0
  181. praisonai/cli/features/tui/widgets/status.py +167 -0
  182. praisonai/cli/features/tui/widgets/tool_panel.py +248 -0
  183. praisonai/cli/features/workflow.py +720 -0
  184. praisonai/cli/legacy.py +236 -0
  185. praisonai/cli/main.py +5559 -0
  186. praisonai/cli/schedule_cli.py +54 -0
  187. praisonai/cli/state/__init__.py +31 -0
  188. praisonai/cli/state/identifiers.py +161 -0
  189. praisonai/cli/state/sessions.py +313 -0
  190. praisonai/code/__init__.py +93 -0
  191. praisonai/code/agent_tools.py +344 -0
  192. praisonai/code/diff/__init__.py +21 -0
  193. praisonai/code/diff/diff_strategy.py +432 -0
  194. praisonai/code/tools/__init__.py +27 -0
  195. praisonai/code/tools/apply_diff.py +221 -0
  196. praisonai/code/tools/execute_command.py +275 -0
  197. praisonai/code/tools/list_files.py +274 -0
  198. praisonai/code/tools/read_file.py +206 -0
  199. praisonai/code/tools/search_replace.py +248 -0
  200. praisonai/code/tools/write_file.py +217 -0
  201. praisonai/code/utils/__init__.py +46 -0
  202. praisonai/code/utils/file_utils.py +307 -0
  203. praisonai/code/utils/ignore_utils.py +308 -0
  204. praisonai/code/utils/text_utils.py +276 -0
  205. praisonai/db/__init__.py +64 -0
  206. praisonai/db/adapter.py +531 -0
  207. praisonai/deploy/__init__.py +62 -0
  208. praisonai/deploy/api.py +231 -0
  209. praisonai/deploy/docker.py +454 -0
  210. praisonai/deploy/doctor.py +367 -0
  211. praisonai/deploy/main.py +327 -0
  212. praisonai/deploy/models.py +179 -0
  213. praisonai/deploy/providers/__init__.py +33 -0
  214. praisonai/deploy/providers/aws.py +331 -0
  215. praisonai/deploy/providers/azure.py +358 -0
  216. praisonai/deploy/providers/base.py +101 -0
  217. praisonai/deploy/providers/gcp.py +314 -0
  218. praisonai/deploy/schema.py +208 -0
  219. praisonai/deploy.py +185 -0
  220. praisonai/endpoints/__init__.py +53 -0
  221. praisonai/endpoints/a2u_server.py +410 -0
  222. praisonai/endpoints/discovery.py +165 -0
  223. praisonai/endpoints/providers/__init__.py +28 -0
  224. praisonai/endpoints/providers/a2a.py +253 -0
  225. praisonai/endpoints/providers/a2u.py +208 -0
  226. praisonai/endpoints/providers/agents_api.py +171 -0
  227. praisonai/endpoints/providers/base.py +231 -0
  228. praisonai/endpoints/providers/mcp.py +263 -0
  229. praisonai/endpoints/providers/recipe.py +206 -0
  230. praisonai/endpoints/providers/tools_mcp.py +150 -0
  231. praisonai/endpoints/registry.py +131 -0
  232. praisonai/endpoints/server.py +161 -0
  233. praisonai/inbuilt_tools/__init__.py +24 -0
  234. praisonai/inbuilt_tools/autogen_tools.py +117 -0
  235. praisonai/inc/__init__.py +2 -0
  236. praisonai/inc/config.py +96 -0
  237. praisonai/inc/models.py +155 -0
  238. praisonai/integrations/__init__.py +56 -0
  239. praisonai/integrations/base.py +303 -0
  240. praisonai/integrations/claude_code.py +270 -0
  241. praisonai/integrations/codex_cli.py +255 -0
  242. praisonai/integrations/cursor_cli.py +195 -0
  243. praisonai/integrations/gemini_cli.py +222 -0
  244. praisonai/jobs/__init__.py +67 -0
  245. praisonai/jobs/executor.py +425 -0
  246. praisonai/jobs/models.py +230 -0
  247. praisonai/jobs/router.py +314 -0
  248. praisonai/jobs/server.py +186 -0
  249. praisonai/jobs/store.py +203 -0
  250. praisonai/llm/__init__.py +66 -0
  251. praisonai/llm/registry.py +382 -0
  252. praisonai/mcp_server/__init__.py +152 -0
  253. praisonai/mcp_server/adapters/__init__.py +74 -0
  254. praisonai/mcp_server/adapters/agents.py +128 -0
  255. praisonai/mcp_server/adapters/capabilities.py +168 -0
  256. praisonai/mcp_server/adapters/cli_tools.py +568 -0
  257. praisonai/mcp_server/adapters/extended_capabilities.py +462 -0
  258. praisonai/mcp_server/adapters/knowledge.py +93 -0
  259. praisonai/mcp_server/adapters/memory.py +104 -0
  260. praisonai/mcp_server/adapters/prompts.py +306 -0
  261. praisonai/mcp_server/adapters/resources.py +124 -0
  262. praisonai/mcp_server/adapters/tools_bridge.py +280 -0
  263. praisonai/mcp_server/auth/__init__.py +48 -0
  264. praisonai/mcp_server/auth/api_key.py +291 -0
  265. praisonai/mcp_server/auth/oauth.py +460 -0
  266. praisonai/mcp_server/auth/oidc.py +289 -0
  267. praisonai/mcp_server/auth/scopes.py +260 -0
  268. praisonai/mcp_server/cli.py +852 -0
  269. praisonai/mcp_server/elicitation.py +445 -0
  270. praisonai/mcp_server/icons.py +302 -0
  271. praisonai/mcp_server/recipe_adapter.py +573 -0
  272. praisonai/mcp_server/recipe_cli.py +824 -0
  273. praisonai/mcp_server/registry.py +703 -0
  274. praisonai/mcp_server/sampling.py +422 -0
  275. praisonai/mcp_server/server.py +490 -0
  276. praisonai/mcp_server/tasks.py +443 -0
  277. praisonai/mcp_server/transports/__init__.py +18 -0
  278. praisonai/mcp_server/transports/http_stream.py +376 -0
  279. praisonai/mcp_server/transports/stdio.py +132 -0
  280. praisonai/persistence/__init__.py +84 -0
  281. praisonai/persistence/config.py +238 -0
  282. praisonai/persistence/conversation/__init__.py +25 -0
  283. praisonai/persistence/conversation/async_mysql.py +427 -0
  284. praisonai/persistence/conversation/async_postgres.py +410 -0
  285. praisonai/persistence/conversation/async_sqlite.py +371 -0
  286. praisonai/persistence/conversation/base.py +151 -0
  287. praisonai/persistence/conversation/json_store.py +250 -0
  288. praisonai/persistence/conversation/mysql.py +387 -0
  289. praisonai/persistence/conversation/postgres.py +401 -0
  290. praisonai/persistence/conversation/singlestore.py +240 -0
  291. praisonai/persistence/conversation/sqlite.py +341 -0
  292. praisonai/persistence/conversation/supabase.py +203 -0
  293. praisonai/persistence/conversation/surrealdb.py +287 -0
  294. praisonai/persistence/factory.py +301 -0
  295. praisonai/persistence/hooks/__init__.py +18 -0
  296. praisonai/persistence/hooks/agent_hooks.py +297 -0
  297. praisonai/persistence/knowledge/__init__.py +26 -0
  298. praisonai/persistence/knowledge/base.py +144 -0
  299. praisonai/persistence/knowledge/cassandra.py +232 -0
  300. praisonai/persistence/knowledge/chroma.py +295 -0
  301. praisonai/persistence/knowledge/clickhouse.py +242 -0
  302. praisonai/persistence/knowledge/cosmosdb_vector.py +438 -0
  303. praisonai/persistence/knowledge/couchbase.py +286 -0
  304. praisonai/persistence/knowledge/lancedb.py +216 -0
  305. praisonai/persistence/knowledge/langchain_adapter.py +291 -0
  306. praisonai/persistence/knowledge/lightrag_adapter.py +212 -0
  307. praisonai/persistence/knowledge/llamaindex_adapter.py +256 -0
  308. praisonai/persistence/knowledge/milvus.py +277 -0
  309. praisonai/persistence/knowledge/mongodb_vector.py +306 -0
  310. praisonai/persistence/knowledge/pgvector.py +335 -0
  311. praisonai/persistence/knowledge/pinecone.py +253 -0
  312. praisonai/persistence/knowledge/qdrant.py +301 -0
  313. praisonai/persistence/knowledge/redis_vector.py +291 -0
  314. praisonai/persistence/knowledge/singlestore_vector.py +299 -0
  315. praisonai/persistence/knowledge/surrealdb_vector.py +309 -0
  316. praisonai/persistence/knowledge/upstash_vector.py +266 -0
  317. praisonai/persistence/knowledge/weaviate.py +223 -0
  318. praisonai/persistence/migrations/__init__.py +10 -0
  319. praisonai/persistence/migrations/manager.py +251 -0
  320. praisonai/persistence/orchestrator.py +406 -0
  321. praisonai/persistence/state/__init__.py +21 -0
  322. praisonai/persistence/state/async_mongodb.py +200 -0
  323. praisonai/persistence/state/base.py +107 -0
  324. praisonai/persistence/state/dynamodb.py +226 -0
  325. praisonai/persistence/state/firestore.py +175 -0
  326. praisonai/persistence/state/gcs.py +155 -0
  327. praisonai/persistence/state/memory.py +245 -0
  328. praisonai/persistence/state/mongodb.py +158 -0
  329. praisonai/persistence/state/redis.py +190 -0
  330. praisonai/persistence/state/upstash.py +144 -0
  331. praisonai/persistence/tests/__init__.py +3 -0
  332. praisonai/persistence/tests/test_all_backends.py +633 -0
  333. praisonai/profiler.py +1214 -0
  334. praisonai/recipe/__init__.py +134 -0
  335. praisonai/recipe/bridge.py +278 -0
  336. praisonai/recipe/core.py +893 -0
  337. praisonai/recipe/exceptions.py +54 -0
  338. praisonai/recipe/history.py +402 -0
  339. praisonai/recipe/models.py +266 -0
  340. praisonai/recipe/operations.py +440 -0
  341. praisonai/recipe/policy.py +422 -0
  342. praisonai/recipe/registry.py +849 -0
  343. praisonai/recipe/runtime.py +214 -0
  344. praisonai/recipe/security.py +711 -0
  345. praisonai/recipe/serve.py +859 -0
  346. praisonai/recipe/server.py +613 -0
  347. praisonai/scheduler/__init__.py +45 -0
  348. praisonai/scheduler/agent_scheduler.py +552 -0
  349. praisonai/scheduler/base.py +124 -0
  350. praisonai/scheduler/daemon_manager.py +225 -0
  351. praisonai/scheduler/state_manager.py +155 -0
  352. praisonai/scheduler/yaml_loader.py +193 -0
  353. praisonai/scheduler.py +194 -0
  354. praisonai/setup/__init__.py +1 -0
  355. praisonai/setup/build.py +21 -0
  356. praisonai/setup/post_install.py +23 -0
  357. praisonai/setup/setup_conda_env.py +25 -0
  358. praisonai/setup.py +16 -0
  359. praisonai/templates/__init__.py +116 -0
  360. praisonai/templates/cache.py +364 -0
  361. praisonai/templates/dependency_checker.py +358 -0
  362. praisonai/templates/discovery.py +391 -0
  363. praisonai/templates/loader.py +564 -0
  364. praisonai/templates/registry.py +511 -0
  365. praisonai/templates/resolver.py +206 -0
  366. praisonai/templates/security.py +327 -0
  367. praisonai/templates/tool_override.py +498 -0
  368. praisonai/templates/tools_doctor.py +256 -0
  369. praisonai/test.py +105 -0
  370. praisonai/train.py +562 -0
  371. praisonai/train_vision.py +306 -0
  372. praisonai/ui/agents.py +824 -0
  373. praisonai/ui/callbacks.py +57 -0
  374. praisonai/ui/chainlit_compat.py +246 -0
  375. praisonai/ui/chat.py +532 -0
  376. praisonai/ui/code.py +717 -0
  377. praisonai/ui/colab.py +474 -0
  378. praisonai/ui/colab_chainlit.py +81 -0
  379. praisonai/ui/components/aicoder.py +284 -0
  380. praisonai/ui/context.py +283 -0
  381. praisonai/ui/database_config.py +56 -0
  382. praisonai/ui/db.py +294 -0
  383. praisonai/ui/realtime.py +488 -0
  384. praisonai/ui/realtimeclient/__init__.py +756 -0
  385. praisonai/ui/realtimeclient/tools.py +242 -0
  386. praisonai/ui/sql_alchemy.py +710 -0
  387. praisonai/upload_vision.py +140 -0
  388. praisonai/version.py +1 -0
  389. praisonai-3.0.0.dist-info/METADATA +3493 -0
  390. praisonai-3.0.0.dist-info/RECORD +393 -0
  391. praisonai-3.0.0.dist-info/WHEEL +5 -0
  392. praisonai-3.0.0.dist-info/entry_points.txt +4 -0
  393. praisonai-3.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,314 @@
1
+ """
2
+ GCP provider for cloud deployment (Cloud Run).
3
+ """
4
+ import subprocess
5
+ import json
6
+ from typing import Dict, Any
7
+ from .base import BaseProvider
8
+ from ..models import DeployResult, DeployStatus, DestroyResult, ServiceState
9
+ from ..doctor import DoctorReport, DoctorCheckResult, check_gcp_cli
10
+
11
+
12
+ class GCPProvider(BaseProvider):
13
+ """GCP deployment provider using Cloud Run."""
14
+
15
+ def doctor(self) -> DoctorReport:
16
+ """Run GCP-specific health checks."""
17
+ checks = [check_gcp_cli()]
18
+
19
+ # Check if Cloud Run API is enabled
20
+ if self.config.project_id:
21
+ try:
22
+ result = subprocess.run(
23
+ ['gcloud', 'services', 'list',
24
+ '--enabled',
25
+ '--filter', 'name:run.googleapis.com',
26
+ '--project', self.config.project_id,
27
+ '--format', 'json'],
28
+ capture_output=True,
29
+ text=True,
30
+ timeout=10
31
+ )
32
+
33
+ if result.returncode == 0:
34
+ services = json.loads(result.stdout)
35
+ if services:
36
+ checks.append(DoctorCheckResult(
37
+ name="Cloud Run API",
38
+ passed=True,
39
+ message="Cloud Run API is enabled"
40
+ ))
41
+ else:
42
+ checks.append(DoctorCheckResult(
43
+ name="Cloud Run API",
44
+ passed=False,
45
+ message="Cloud Run API is not enabled",
46
+ fix_suggestion=f"Run: gcloud services enable run.googleapis.com --project={self.config.project_id}"
47
+ ))
48
+ except Exception as e:
49
+ checks.append(DoctorCheckResult(
50
+ name="Cloud Run API",
51
+ passed=False,
52
+ message=f"Failed to check Cloud Run API: {e}",
53
+ fix_suggestion="Check gcloud configuration"
54
+ ))
55
+
56
+ return DoctorReport(checks=checks)
57
+
58
+ def plan(self) -> Dict[str, Any]:
59
+ """Generate GCP deployment plan."""
60
+ plan = {
61
+ "provider": "gcp",
62
+ "service_name": self.config.service_name,
63
+ "region": self.config.region,
64
+ "project_id": self.config.project_id,
65
+ "cpu": self.config.cpu,
66
+ "memory": f"{self.config.memory}Mi",
67
+ "min_instances": self.config.min_instances,
68
+ "max_instances": self.config.max_instances,
69
+ "image": self.config.image or f"gcr.io/{self.config.project_id}/{self.config.service_name}:latest",
70
+ "steps": [
71
+ "1. Enable Cloud Run API (if not enabled)",
72
+ "2. Deploy service to Cloud Run",
73
+ "3. Set IAM policy for public access (optional)",
74
+ "4. Get service URL"
75
+ ]
76
+ }
77
+
78
+ return plan
79
+
80
+ def deploy(self) -> DeployResult:
81
+ """Deploy to GCP Cloud Run."""
82
+ try:
83
+ if not self.config.project_id:
84
+ return DeployResult(
85
+ success=False,
86
+ message="Project ID is required for GCP deployment",
87
+ error="Please specify project_id in cloud config"
88
+ )
89
+
90
+ # Step 1: Enable Cloud Run API
91
+ print(f"🔧 Enabling Cloud Run API")
92
+ try:
93
+ subprocess.run(
94
+ ['gcloud', 'services', 'enable', 'run.googleapis.com',
95
+ '--project', self.config.project_id],
96
+ capture_output=True,
97
+ timeout=60
98
+ )
99
+ except Exception:
100
+ pass # May already be enabled
101
+
102
+ # Step 2: Deploy to Cloud Run
103
+ print(f"🚀 Deploying to Cloud Run: {self.config.service_name}")
104
+
105
+ cmd = [
106
+ 'gcloud', 'run', 'deploy', self.config.service_name,
107
+ '--image', self.config.image or f"gcr.io/{self.config.project_id}/{self.config.service_name}:latest",
108
+ '--platform', 'managed',
109
+ '--region', self.config.region,
110
+ '--project', self.config.project_id,
111
+ '--cpu', str(self.config.cpu),
112
+ '--memory', f"{self.config.memory}Mi",
113
+ '--min-instances', str(self.config.min_instances),
114
+ '--max-instances', str(self.config.max_instances),
115
+ '--port', '8005',
116
+ '--allow-unauthenticated'
117
+ ]
118
+
119
+ # Add environment variables
120
+ if self.config.env_vars:
121
+ env_str = ','.join([f"{k}={v}" for k, v in self.config.env_vars.items()])
122
+ cmd.extend(['--set-env-vars', env_str])
123
+
124
+ result = subprocess.run(
125
+ cmd,
126
+ capture_output=True,
127
+ text=True,
128
+ timeout=180
129
+ )
130
+
131
+ if result.returncode == 0:
132
+ # Extract URL from output
133
+ try:
134
+ show_result = subprocess.run(
135
+ ['gcloud', 'run', 'services', 'describe',
136
+ self.config.service_name,
137
+ '--platform', 'managed',
138
+ '--region', self.config.region,
139
+ '--project', self.config.project_id,
140
+ '--format', 'json'],
141
+ capture_output=True,
142
+ text=True,
143
+ timeout=30
144
+ )
145
+
146
+ if show_result.returncode == 0:
147
+ service_data = json.loads(show_result.stdout)
148
+ url = service_data.get('status', {}).get('url')
149
+ else:
150
+ url = None
151
+ except Exception:
152
+ url = None
153
+
154
+ return DeployResult(
155
+ success=True,
156
+ message=f"Service deployed successfully to Cloud Run",
157
+ url=url,
158
+ metadata={
159
+ "project_id": self.config.project_id,
160
+ "service_name": self.config.service_name,
161
+ "region": self.config.region
162
+ }
163
+ )
164
+ else:
165
+ return DeployResult(
166
+ success=False,
167
+ message="Failed to deploy to Cloud Run",
168
+ error=result.stderr
169
+ )
170
+
171
+ except Exception as e:
172
+ return DeployResult(
173
+ success=False,
174
+ message="GCP deployment failed",
175
+ error=str(e)
176
+ )
177
+
178
+ def status(self) -> DeployStatus:
179
+ """Get current GCP Cloud Run service status."""
180
+ try:
181
+ if not self.config.project_id:
182
+ return DeployStatus(
183
+ state=ServiceState.UNKNOWN,
184
+ message="Project ID not configured",
185
+ service_name=self.config.service_name,
186
+ provider="gcp",
187
+ region=self.config.region
188
+ )
189
+
190
+ result = subprocess.run(
191
+ ['gcloud', 'run', 'services', 'describe',
192
+ self.config.service_name,
193
+ '--platform', 'managed',
194
+ '--region', self.config.region,
195
+ '--project', self.config.project_id,
196
+ '--format', 'json'],
197
+ capture_output=True,
198
+ text=True,
199
+ timeout=30
200
+ )
201
+
202
+ if result.returncode != 0:
203
+ return DeployStatus(
204
+ state=ServiceState.NOT_FOUND,
205
+ message=f"Service not found: {result.stderr}",
206
+ service_name=self.config.service_name,
207
+ provider="gcp",
208
+ region=self.config.region
209
+ )
210
+
211
+ data = json.loads(result.stdout)
212
+ status_data = data.get('status', {})
213
+ conditions = status_data.get('conditions', [])
214
+
215
+ # Get URL
216
+ url = status_data.get('url')
217
+
218
+ # Parse conditions to determine state
219
+ ready_condition = next((c for c in conditions if c.get('type') == 'Ready'), None)
220
+
221
+ if ready_condition:
222
+ if ready_condition.get('status') == 'True':
223
+ state = ServiceState.RUNNING
224
+ elif ready_condition.get('status') == 'Unknown':
225
+ state = ServiceState.PENDING
226
+ else:
227
+ state = ServiceState.FAILED
228
+ else:
229
+ state = ServiceState.UNKNOWN
230
+
231
+ # Get metadata
232
+ metadata_info = data.get('metadata', {})
233
+ spec = data.get('spec', {})
234
+ template = spec.get('template', {})
235
+
236
+ return DeployStatus(
237
+ state=state,
238
+ url=url,
239
+ message=f"Ready: {ready_condition.get('status', 'Unknown') if ready_condition else 'Unknown'}",
240
+ service_name=self.config.service_name,
241
+ provider="gcp",
242
+ region=self.config.region,
243
+ healthy=state == ServiceState.RUNNING,
244
+ instances_running=1 if state == ServiceState.RUNNING else 0,
245
+ instances_desired=1,
246
+ created_at=metadata_info.get('creationTimestamp'),
247
+ metadata={
248
+ "project_id": self.config.project_id,
249
+ "generation": metadata_info.get('generation'),
250
+ "latest_revision": status_data.get('latestReadyRevisionName'),
251
+ "traffic": status_data.get('traffic', [])
252
+ }
253
+ )
254
+
255
+ except Exception as e:
256
+ return DeployStatus(
257
+ state=ServiceState.UNKNOWN,
258
+ message=f"Failed to get status: {e}",
259
+ service_name=self.config.service_name,
260
+ provider="gcp",
261
+ region=self.config.region
262
+ )
263
+
264
+ def destroy(self, force: bool = False) -> DestroyResult:
265
+ """Destroy GCP Cloud Run service."""
266
+ try:
267
+ if not self.config.project_id:
268
+ return DestroyResult(
269
+ success=False,
270
+ message="Project ID not configured",
271
+ error="Please specify project_id in cloud config"
272
+ )
273
+
274
+ deleted_resources = []
275
+
276
+ # Delete the Cloud Run service
277
+ print(f"🗑️ Deleting Cloud Run service: {self.config.service_name}")
278
+ result = subprocess.run(
279
+ ['gcloud', 'run', 'services', 'delete',
280
+ self.config.service_name,
281
+ '--platform', 'managed',
282
+ '--region', self.config.region,
283
+ '--project', self.config.project_id,
284
+ '--quiet'],
285
+ capture_output=True,
286
+ text=True,
287
+ timeout=120
288
+ )
289
+
290
+ if result.returncode == 0:
291
+ deleted_resources.append(f"cloud-run:{self.config.service_name}")
292
+ return DestroyResult(
293
+ success=True,
294
+ message="Successfully destroyed GCP Cloud Run service",
295
+ resources_deleted=deleted_resources,
296
+ metadata={
297
+ "project_id": self.config.project_id,
298
+ "region": self.config.region
299
+ }
300
+ )
301
+ else:
302
+ return DestroyResult(
303
+ success=False,
304
+ message="Failed to delete Cloud Run service",
305
+ error=result.stderr,
306
+ resources_deleted=deleted_resources
307
+ )
308
+
309
+ except Exception as e:
310
+ return DestroyResult(
311
+ success=False,
312
+ message="Failed to destroy GCP resources",
313
+ error=str(e)
314
+ )
@@ -0,0 +1,208 @@
1
+ """
2
+ YAML schema validation for deploy configurations.
3
+ """
4
+ import yaml
5
+ from pathlib import Path
6
+ from typing import Optional
7
+ from .models import DeployConfig, DeployType, CloudProvider, APIConfig, DockerConfig, CloudConfig
8
+
9
+
10
+ def validate_agents_yaml(file_path: str) -> Optional[DeployConfig]:
11
+ """
12
+ Validate agents.yaml file and extract deploy configuration.
13
+
14
+ Args:
15
+ file_path: Path to agents.yaml file
16
+
17
+ Returns:
18
+ DeployConfig if deploy section exists, None otherwise
19
+
20
+ Raises:
21
+ FileNotFoundError: If file doesn't exist
22
+ ValueError: If deploy config is invalid
23
+ """
24
+ path = Path(file_path)
25
+ if not path.exists():
26
+ raise FileNotFoundError(f"File not found: {file_path}")
27
+
28
+ with open(path, 'r') as f:
29
+ data = yaml.safe_load(f)
30
+
31
+ if not data or 'deploy' not in data:
32
+ return None
33
+
34
+ deploy_data = data['deploy']
35
+
36
+ # Parse deploy type
37
+ deploy_type_str = deploy_data.get('type')
38
+ if not deploy_type_str:
39
+ raise ValueError("Deploy type is required")
40
+
41
+ try:
42
+ deploy_type = DeployType(deploy_type_str)
43
+ except ValueError:
44
+ raise ValueError(f"Invalid deploy type: {deploy_type_str}. Must be one of: api, docker, cloud")
45
+
46
+ # Build config based on type
47
+ config_dict = {'type': deploy_type}
48
+
49
+ if deploy_type == DeployType.API:
50
+ api_data = deploy_data.get('api', {})
51
+ config_dict['api'] = APIConfig(**api_data) if api_data else APIConfig()
52
+
53
+ elif deploy_type == DeployType.DOCKER:
54
+ docker_data = deploy_data.get('docker', {})
55
+ config_dict['docker'] = DockerConfig(**docker_data) if docker_data else DockerConfig()
56
+
57
+ elif deploy_type == DeployType.CLOUD:
58
+ cloud_data = deploy_data.get('cloud', {})
59
+ if not cloud_data:
60
+ raise ValueError("Cloud configuration is required for cloud deployment type")
61
+
62
+ # Parse provider
63
+ provider_str = cloud_data.get('provider')
64
+ if not provider_str:
65
+ raise ValueError("Cloud provider is required")
66
+
67
+ try:
68
+ cloud_data['provider'] = CloudProvider(provider_str)
69
+ except ValueError:
70
+ raise ValueError(f"Invalid cloud provider: {provider_str}. Must be one of: aws, azure, gcp")
71
+
72
+ config_dict['cloud'] = CloudConfig(**cloud_data)
73
+
74
+ # Parse agents if present
75
+ if 'agents' in deploy_data:
76
+ config_dict['agents'] = deploy_data['agents']
77
+
78
+ return DeployConfig(**config_dict)
79
+
80
+
81
+ def generate_sample_yaml(deploy_type: DeployType, provider: Optional[CloudProvider] = None) -> str:
82
+ """
83
+ Generate sample agents.yaml with deploy configuration.
84
+
85
+ Args:
86
+ deploy_type: Type of deployment
87
+ provider: Cloud provider (required if deploy_type is CLOUD)
88
+
89
+ Returns:
90
+ YAML string with sample configuration
91
+ """
92
+ base_yaml = """name: Sample Agent
93
+ description: Sample agent configuration with deploy settings
94
+ framework: praisonai
95
+
96
+ agents:
97
+ assistant:
98
+ name: Assistant
99
+ role: Helper
100
+ goal: Help users with tasks
101
+ backstory: Experienced assistant ready to help
102
+ instructions: |
103
+ Provide helpful responses to user queries.
104
+ Be concise and accurate.
105
+
106
+ """
107
+
108
+ if deploy_type == DeployType.API:
109
+ deploy_yaml = """deploy:
110
+ type: api
111
+ api:
112
+ host: 0.0.0.0
113
+ port: 8005
114
+ workers: 1
115
+ cors_enabled: true
116
+ auth_enabled: false
117
+ """
118
+
119
+ elif deploy_type == DeployType.DOCKER:
120
+ deploy_yaml = """deploy:
121
+ type: docker
122
+ docker:
123
+ image_name: praisonai-app
124
+ tag: latest
125
+ base_image: python:3.11-slim
126
+ expose:
127
+ - 8005
128
+ registry: null
129
+ push: false
130
+ """
131
+
132
+ elif deploy_type == DeployType.CLOUD:
133
+ if provider == CloudProvider.AWS:
134
+ deploy_yaml = """deploy:
135
+ type: cloud
136
+ cloud:
137
+ provider: aws
138
+ region: us-east-1
139
+ service_name: praisonai-service
140
+ cpu: "256"
141
+ memory: "512"
142
+ min_instances: 1
143
+ max_instances: 10
144
+ # image: your-registry/praisonai-app:latest
145
+ # cluster_name: praisonai-cluster
146
+ """
147
+
148
+ elif provider == CloudProvider.AZURE:
149
+ deploy_yaml = """deploy:
150
+ type: cloud
151
+ cloud:
152
+ provider: azure
153
+ region: eastus
154
+ service_name: praisonai-service
155
+ resource_group: praisonai-rg
156
+ subscription_id: your-subscription-id
157
+ cpu: "0.5"
158
+ memory: "1.0"
159
+ min_instances: 1
160
+ max_instances: 10
161
+ # image: your-registry.azurecr.io/praisonai-app:latest
162
+ """
163
+
164
+ elif provider == CloudProvider.GCP:
165
+ deploy_yaml = """deploy:
166
+ type: cloud
167
+ cloud:
168
+ provider: gcp
169
+ region: us-central1
170
+ service_name: praisonai-service
171
+ project_id: your-project-id
172
+ cpu: "1"
173
+ memory: "512"
174
+ min_instances: 1
175
+ max_instances: 10
176
+ # image: gcr.io/your-project-id/praisonai-app:latest
177
+ """
178
+ else:
179
+ deploy_yaml = """deploy:
180
+ type: cloud
181
+ cloud:
182
+ provider: aws # or azure, gcp
183
+ region: us-east-1
184
+ service_name: praisonai-service
185
+ """
186
+
187
+ else:
188
+ deploy_yaml = ""
189
+
190
+ return base_yaml + deploy_yaml
191
+
192
+
193
+ def save_sample_yaml(file_path: str, deploy_type: DeployType, provider: Optional[CloudProvider] = None):
194
+ """
195
+ Save sample agents.yaml to file.
196
+
197
+ Args:
198
+ file_path: Path to save the file
199
+ deploy_type: Type of deployment
200
+ provider: Cloud provider (required if deploy_type is CLOUD)
201
+ """
202
+ yaml_content = generate_sample_yaml(deploy_type, provider)
203
+
204
+ path = Path(file_path)
205
+ path.parent.mkdir(parents=True, exist_ok=True)
206
+
207
+ with open(path, 'w') as f:
208
+ f.write(yaml_content)