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,171 @@
1
+ """
2
+ Guardrail Handler for CLI.
3
+
4
+ Provides output validation using LLM guardrails.
5
+ Usage: praisonai "prompt" --guardrail "Ensure output is valid JSON"
6
+ """
7
+
8
+ from typing import Any, Dict, Tuple
9
+ from .base import FlagHandler
10
+
11
+ # Lazy import to avoid performance impact
12
+ PRAISONAI_AVAILABLE = False
13
+ LLMGuardrail = None
14
+
15
+ def _check_praisonai():
16
+ """Check if praisonaiagents is available."""
17
+ global PRAISONAI_AVAILABLE, LLMGuardrail
18
+ try:
19
+ from praisonaiagents import LLMGuardrail as _LLMGuardrail
20
+ LLMGuardrail = _LLMGuardrail
21
+ PRAISONAI_AVAILABLE = True
22
+ except ImportError:
23
+ PRAISONAI_AVAILABLE = False
24
+ return PRAISONAI_AVAILABLE
25
+
26
+
27
+ class GuardrailHandler(FlagHandler):
28
+ """
29
+ Handler for --guardrail flag.
30
+
31
+ Validates agent output using LLM-based guardrails.
32
+
33
+ Example:
34
+ praisonai "Write code" --guardrail "Ensure code is secure"
35
+ """
36
+
37
+ @property
38
+ def feature_name(self) -> str:
39
+ return "guardrail"
40
+
41
+ @property
42
+ def flag_name(self) -> str:
43
+ return "guardrail"
44
+
45
+ @property
46
+ def flag_help(self) -> str:
47
+ return "Validate output with LLM guardrail (provide description string)"
48
+
49
+ def check_dependencies(self) -> Tuple[bool, str]:
50
+ """Check if praisonaiagents is available."""
51
+ if _check_praisonai():
52
+ return True, ""
53
+ return False, "praisonaiagents not installed. Install with: pip install praisonaiagents"
54
+
55
+ def apply_to_agent_config(self, config: Dict[str, Any], flag_value: Any) -> Dict[str, Any]:
56
+ """
57
+ Apply guardrail configuration to agent config.
58
+
59
+ Args:
60
+ config: Agent configuration dictionary
61
+ flag_value: Guardrail description string
62
+
63
+ Returns:
64
+ Modified configuration with guardrail settings
65
+ """
66
+ if flag_value:
67
+ config["guardrail_description"] = flag_value
68
+ # Store for later use in post_process_result
69
+ self._guardrail_description = flag_value
70
+ return config
71
+
72
+ def create_guardrail(self, description: str, llm: Any = None):
73
+ """
74
+ Create an LLMGuardrail instance.
75
+
76
+ Args:
77
+ description: Natural language description of validation criteria
78
+ llm: Optional LLM instance for validation (defaults to gpt-4o-mini)
79
+
80
+ Returns:
81
+ LLMGuardrail instance or None if unavailable
82
+ """
83
+ if not _check_praisonai():
84
+ self.print_status(
85
+ "Guardrail requires praisonaiagents. Install with: pip install praisonaiagents",
86
+ "error"
87
+ )
88
+ return None
89
+
90
+ # Provide default LLM if none specified
91
+ if llm is None:
92
+ import os
93
+ # Try to get from environment or use default
94
+ llm = os.environ.get('OPENAI_MODEL_NAME', 'gpt-4o-mini')
95
+
96
+ return LLMGuardrail(description=description, llm=llm)
97
+
98
+ def validate_output(self, output: str, description: str, llm: Any = None) -> Tuple[bool, str]:
99
+ """
100
+ Validate output against guardrail criteria.
101
+
102
+ Args:
103
+ output: The output to validate
104
+ description: Validation criteria description
105
+ llm: Optional LLM for validation
106
+
107
+ Returns:
108
+ Tuple of (is_valid, message)
109
+ """
110
+ guardrail = self.create_guardrail(description, llm)
111
+ if not guardrail:
112
+ return True, "Guardrail unavailable, skipping validation"
113
+
114
+ try:
115
+ # Create a mock TaskOutput for the guardrail
116
+ from praisonaiagents import TaskOutput
117
+ task_output = TaskOutput(
118
+ description="CLI output",
119
+ summary="CLI output",
120
+ raw=output,
121
+ agent="CLI",
122
+ output_format="RAW"
123
+ )
124
+
125
+ success, result = guardrail(task_output)
126
+ if success:
127
+ return True, "Guardrail validation passed"
128
+ else:
129
+ return False, f"Guardrail validation failed: {result}"
130
+ except Exception as e:
131
+ self.log(f"Guardrail error: {e}", "warning")
132
+ return True, f"Guardrail error (skipped): {e}"
133
+
134
+ def post_process_result(self, result: Any, flag_value: Any) -> Any:
135
+ """
136
+ Post-process result with guardrail validation.
137
+
138
+ Args:
139
+ result: Agent output
140
+ flag_value: Guardrail description
141
+
142
+ Returns:
143
+ Original result (validation is logged)
144
+ """
145
+ if not flag_value:
146
+ return result
147
+
148
+ is_valid, message = self.validate_output(str(result), flag_value)
149
+
150
+ if is_valid:
151
+ self.print_status(f"✅ {message}", "success")
152
+ else:
153
+ self.print_status(f"⚠️ {message}", "warning")
154
+
155
+ return result
156
+
157
+ def execute(self, output: str = None, guardrail_description: str = None, **kwargs) -> Tuple[bool, str]:
158
+ """
159
+ Execute guardrail validation.
160
+
161
+ Args:
162
+ output: Output to validate
163
+ guardrail_description: Validation criteria
164
+
165
+ Returns:
166
+ Tuple of (is_valid, message)
167
+ """
168
+ if not output or not guardrail_description:
169
+ return True, "No output or description provided"
170
+
171
+ return self.validate_output(output, guardrail_description)
@@ -0,0 +1,185 @@
1
+ """
2
+ Handoff Handler for CLI.
3
+
4
+ Provides agent-to-agent delegation capability.
5
+ Usage: praisonai "Complex task" --handoff "researcher,writer,editor"
6
+ """
7
+
8
+ from typing import Any, Dict, Tuple, List
9
+ from .base import FlagHandler
10
+
11
+
12
+ class HandoffHandler(FlagHandler):
13
+ """
14
+ Handler for --handoff flag.
15
+
16
+ Enables agent-to-agent delegation for complex tasks.
17
+
18
+ Example:
19
+ praisonai "Research and write article" --handoff "researcher,writer"
20
+ praisonai "Analyze and visualize data" --handoff "analyst,visualizer"
21
+ """
22
+
23
+ @property
24
+ def feature_name(self) -> str:
25
+ return "handoff"
26
+
27
+ @property
28
+ def flag_name(self) -> str:
29
+ return "handoff"
30
+
31
+ @property
32
+ def flag_help(self) -> str:
33
+ return "Comma-separated list of agent roles for task delegation"
34
+
35
+ def check_dependencies(self) -> Tuple[bool, str]:
36
+ """Check if Handoff is available."""
37
+ try:
38
+ import importlib.util
39
+ if importlib.util.find_spec("praisonaiagents") is not None:
40
+ return True, ""
41
+ return False, "praisonaiagents not installed"
42
+ except ImportError:
43
+ return False, "praisonaiagents not installed. Install with: pip install praisonaiagents"
44
+
45
+ def parse_agent_names(self, names_str: str) -> List[str]:
46
+ """
47
+ Parse comma-separated agent names.
48
+
49
+ Args:
50
+ names_str: Comma-separated string of agent names/roles
51
+
52
+ Returns:
53
+ List of agent names
54
+ """
55
+ if not names_str:
56
+ return []
57
+ return [name.strip() for name in names_str.split(',') if name.strip()]
58
+
59
+ def create_agents_with_handoff(self, agent_names: List[str], llm: str = None) -> List[Any]:
60
+ """
61
+ Create agents with handoff capability.
62
+
63
+ Args:
64
+ agent_names: List of agent role names
65
+ llm: Optional LLM model name
66
+
67
+ Returns:
68
+ List of Agent instances with handoff configured
69
+ """
70
+ available, msg = self.check_dependencies()
71
+ if not available:
72
+ self.print_status(msg, "error")
73
+ return []
74
+
75
+ from praisonaiagents import Agent, handoff
76
+
77
+ agents = []
78
+
79
+ # First pass: Create all agents without handoffs
80
+ for i, name in enumerate(agent_names):
81
+ agent_config = {
82
+ "name": name.title().replace("_", " "),
83
+ "role": name.title().replace("_", " "),
84
+ "goal": f"Complete tasks as {name}",
85
+ "backstory": f"Expert {name} with specialized skills"
86
+ }
87
+
88
+ if llm:
89
+ agent_config["llm"] = llm
90
+
91
+ agent = Agent(**agent_config)
92
+ agents.append(agent)
93
+
94
+ # Second pass: Set up handoffs by recreating agents with handoff config
95
+ final_agents = []
96
+ for i, name in enumerate(agent_names):
97
+ agent_config = {
98
+ "name": name.title().replace("_", " "),
99
+ "role": name.title().replace("_", " "),
100
+ "goal": f"Complete tasks as {name}",
101
+ "backstory": f"Expert {name} with specialized skills"
102
+ }
103
+
104
+ if llm:
105
+ agent_config["llm"] = llm
106
+
107
+ # Add handoff to next agent if not the last agent
108
+ if i < len(agent_names) - 1:
109
+ next_agent = agents[i + 1]
110
+ next_agent_name = agent_names[i + 1]
111
+
112
+ # Pass handoffs via constructor - this properly registers them as tools
113
+ agent_config["handoffs"] = [
114
+ handoff(
115
+ agent=next_agent,
116
+ tool_name_override=f"handoff_to_{next_agent_name}",
117
+ tool_description_override=f"Hand off the task to {next_agent_name}. Call this after completing your part."
118
+ )
119
+ ]
120
+
121
+ # Add instructions to use handoff
122
+ agent_config["instructions"] = f"After completing your task, you MUST use the handoff_to_{next_agent_name} tool to pass your work to the next agent."
123
+
124
+ final_agent = Agent(**agent_config)
125
+ final_agents.append(final_agent)
126
+
127
+ self.print_status(f"🤝 Created {len(final_agents)} agents with handoff chain", "success")
128
+ for i, name in enumerate(agent_names):
129
+ arrow = " → " if i < len(agent_names) - 1 else ""
130
+ self.print_status(f" {name}{arrow}", "info")
131
+
132
+ return final_agents
133
+
134
+ def apply_to_agent_config(self, config: Dict[str, Any], flag_value: Any) -> Dict[str, Any]:
135
+ """
136
+ Apply handoff configuration.
137
+
138
+ Args:
139
+ config: Agent configuration dictionary
140
+ flag_value: Comma-separated agent names
141
+
142
+ Returns:
143
+ Modified configuration
144
+ """
145
+ if flag_value:
146
+ agent_names = self.parse_agent_names(flag_value)
147
+ config['handoff_agents'] = agent_names
148
+ config['use_handoff'] = True
149
+ return config
150
+
151
+ def execute(self, prompt: str = None, agent_names: str = None, llm: str = None, **kwargs) -> Any:
152
+ """
153
+ Execute task with handoff agents.
154
+
155
+ Args:
156
+ prompt: Task prompt
157
+ agent_names: Comma-separated agent names
158
+ llm: Optional LLM model
159
+
160
+ Returns:
161
+ Task result
162
+ """
163
+ if not agent_names:
164
+ self.print_status("No agent names provided for handoff", "error")
165
+ return None
166
+
167
+ names = self.parse_agent_names(agent_names)
168
+ if len(names) < 2:
169
+ self.print_status("Handoff requires at least 2 agents", "error")
170
+ return None
171
+
172
+ agents = self.create_agents_with_handoff(names, llm)
173
+ if not agents:
174
+ return None
175
+
176
+ if prompt:
177
+ # Execute with first agent
178
+ try:
179
+ result = agents[0].start(prompt)
180
+ return result
181
+ except Exception as e:
182
+ self.print_status(f"Handoff execution failed: {e}", "error")
183
+ return None
184
+
185
+ return agents