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,289 @@
1
+ """
2
+ Diagnostics export CLI handler for PraisonAI.
3
+
4
+ Provides diagnostic export functionality:
5
+ - diag export: Bundle logs, traces, config for bug reports
6
+ """
7
+
8
+ import argparse
9
+ import json
10
+ import logging
11
+ import os
12
+ import shutil
13
+ import tempfile
14
+ import time
15
+ import zipfile
16
+ from pathlib import Path
17
+ from typing import List
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+
22
+ class DiagHandler:
23
+ """Handler for diag CLI commands."""
24
+
25
+ @staticmethod
26
+ def setup_subparser(subparsers) -> None:
27
+ """Set up the diag subcommand parser."""
28
+ diag_parser = subparsers.add_parser(
29
+ "diag",
30
+ help="Diagnostics export",
31
+ description="Export diagnostic information for bug reports"
32
+ )
33
+
34
+ diag_subparsers = diag_parser.add_subparsers(dest="diag_command", help="Diag subcommands")
35
+
36
+ # diag export
37
+ export_parser = diag_subparsers.add_parser("export", help="Export diagnostic bundle")
38
+ export_parser.add_argument(
39
+ "-o", "--output",
40
+ type=str,
41
+ help="Output path (default: praisonai-diag-{timestamp}.zip)"
42
+ )
43
+ export_parser.add_argument(
44
+ "--include-logs",
45
+ action="store_true",
46
+ default=True,
47
+ help="Include log files (default: true)"
48
+ )
49
+ export_parser.add_argument(
50
+ "--include-config",
51
+ action="store_true",
52
+ default=True,
53
+ help="Include configuration (default: true)"
54
+ )
55
+ export_parser.add_argument(
56
+ "--include-trace",
57
+ action="store_true",
58
+ default=True,
59
+ help="Include recent traces (default: true)"
60
+ )
61
+ export_parser.add_argument(
62
+ "--workspace", "-w",
63
+ type=str,
64
+ default=".",
65
+ help="Workspace root directory"
66
+ )
67
+ export_parser.add_argument("--json", action="store_true", help="Output JSON")
68
+ export_parser.set_defaults(func=DiagHandler.handle_export)
69
+
70
+ @staticmethod
71
+ def handle_export(args: argparse.Namespace) -> int:
72
+ """Handle diag export command."""
73
+ timestamp = int(time.time())
74
+ output_path = args.output or f"praisonai-diag-{timestamp}.zip"
75
+
76
+ collected_files = []
77
+
78
+ with tempfile.TemporaryDirectory() as tmpdir:
79
+ tmppath = Path(tmpdir)
80
+
81
+ # Collect system info
82
+ system_info = DiagHandler._collect_system_info()
83
+ system_file = tmppath / "system_info.json"
84
+ with open(system_file, "w") as f:
85
+ json.dump(system_info, f, indent=2, default=str)
86
+ collected_files.append("system_info.json")
87
+
88
+ # Collect config
89
+ if args.include_config:
90
+ config_files = DiagHandler._collect_config(args.workspace, tmppath)
91
+ collected_files.extend(config_files)
92
+
93
+ # Collect logs
94
+ if args.include_logs:
95
+ log_files = DiagHandler._collect_logs(tmppath)
96
+ collected_files.extend(log_files)
97
+
98
+ # Collect traces
99
+ if args.include_trace:
100
+ trace_files = DiagHandler._collect_traces(args.workspace, tmppath)
101
+ collected_files.extend(trace_files)
102
+
103
+ # Create zip
104
+ with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zf:
105
+ for file in tmppath.rglob("*"):
106
+ if file.is_file():
107
+ arcname = file.relative_to(tmppath)
108
+ zf.write(file, arcname)
109
+
110
+ result = {
111
+ "action": "export",
112
+ "output": output_path,
113
+ "files_collected": collected_files,
114
+ "count": len(collected_files)
115
+ }
116
+
117
+ DiagHandler._output_result(result, args.json)
118
+ return 0
119
+
120
+ @staticmethod
121
+ def _collect_system_info() -> dict:
122
+ """Collect system information."""
123
+ import platform
124
+ import sys
125
+
126
+ info = {
127
+ "timestamp": time.time(),
128
+ "platform": {
129
+ "system": platform.system(),
130
+ "release": platform.release(),
131
+ "version": platform.version(),
132
+ "machine": platform.machine(),
133
+ "python_version": sys.version
134
+ },
135
+ "praisonai": {}
136
+ }
137
+
138
+ # Get PraisonAI version
139
+ try:
140
+ from praisonai.version import __version__
141
+ info["praisonai"]["version"] = __version__
142
+ except ImportError:
143
+ info["praisonai"]["version"] = "unknown"
144
+
145
+ # Get praisonaiagents version
146
+ try:
147
+ import praisonaiagents
148
+ info["praisonai"]["agents_version"] = getattr(praisonaiagents, '__version__', 'unknown')
149
+ except ImportError:
150
+ info["praisonai"]["agents_version"] = "not installed"
151
+
152
+ # Check for optional dependencies
153
+ info["dependencies"] = {}
154
+ for dep in ["acp", "litellm", "openai", "anthropic", "google.generativeai"]:
155
+ try:
156
+ __import__(dep.split(".")[0])
157
+ info["dependencies"][dep] = "installed"
158
+ except ImportError:
159
+ info["dependencies"][dep] = "not installed"
160
+
161
+ # Environment (redacted)
162
+ env_keys = [
163
+ "OPENAI_API_KEY", "ANTHROPIC_API_KEY", "GOOGLE_API_KEY",
164
+ "PRAISONAI_APPROVAL_MODE", "LOGLEVEL"
165
+ ]
166
+ info["environment"] = {}
167
+ for key in env_keys:
168
+ value = os.environ.get(key)
169
+ if value:
170
+ if "KEY" in key or "SECRET" in key:
171
+ info["environment"][key] = f"{value[:4]}...{value[-4:]}" if len(value) > 8 else "***"
172
+ else:
173
+ info["environment"][key] = value
174
+ else:
175
+ info["environment"][key] = None
176
+
177
+ return info
178
+
179
+ @staticmethod
180
+ def _collect_config(workspace: str, tmppath: Path) -> List[str]:
181
+ """Collect configuration files."""
182
+ collected = []
183
+ workspace_path = Path(workspace)
184
+ config_dir = tmppath / "config"
185
+ config_dir.mkdir(exist_ok=True)
186
+
187
+ # Look for config files
188
+ config_patterns = [
189
+ "agents.yaml",
190
+ "workflow.yaml",
191
+ ".praisonai.yaml",
192
+ ".env.example", # Not .env to avoid secrets
193
+ "pyproject.toml",
194
+ ]
195
+
196
+ for pattern in config_patterns:
197
+ for file in workspace_path.glob(pattern):
198
+ if file.is_file():
199
+ dest = config_dir / file.name
200
+ shutil.copy(file, dest)
201
+ collected.append(f"config/{file.name}")
202
+
203
+ return collected
204
+
205
+ @staticmethod
206
+ def _collect_logs(tmppath: Path) -> List[str]:
207
+ """Collect log files."""
208
+ collected = []
209
+ logs_dir = tmppath / "logs"
210
+ logs_dir.mkdir(exist_ok=True)
211
+
212
+ # Look for log files in common locations
213
+ log_locations = [
214
+ Path.home() / ".praison" / "logs",
215
+ Path.home() / ".praisonai" / "logs",
216
+ Path("/var/log/praisonai"),
217
+ ]
218
+
219
+ for log_dir in log_locations:
220
+ if log_dir.exists():
221
+ for log_file in log_dir.glob("*.log"):
222
+ if log_file.is_file():
223
+ dest = logs_dir / log_file.name
224
+ # Only copy last 1000 lines
225
+ try:
226
+ with open(log_file) as f:
227
+ lines = f.readlines()[-1000:]
228
+ with open(dest, "w") as f:
229
+ f.writelines(lines)
230
+ collected.append(f"logs/{log_file.name}")
231
+ except Exception:
232
+ pass
233
+
234
+ return collected
235
+
236
+ @staticmethod
237
+ def _collect_traces(workspace: str, tmppath: Path) -> List[str]:
238
+ """Collect trace files."""
239
+ collected = []
240
+ traces_dir = tmppath / "traces"
241
+ traces_dir.mkdir(exist_ok=True)
242
+
243
+ workspace_path = Path(workspace)
244
+
245
+ # Look for trace files
246
+ trace_patterns = ["*_trace.json", "praisonai_trace*.json", "*.trace"]
247
+
248
+ for pattern in trace_patterns:
249
+ for trace_file in workspace_path.glob(pattern):
250
+ if trace_file.is_file():
251
+ dest = traces_dir / trace_file.name
252
+ shutil.copy(trace_file, dest)
253
+ collected.append(f"traces/{trace_file.name}")
254
+
255
+ return collected
256
+
257
+ @staticmethod
258
+ def _output_result(result: dict, as_json: bool) -> None:
259
+ """Output result in appropriate format."""
260
+ if as_json:
261
+ print(json.dumps(result, indent=2, default=str))
262
+ else:
263
+ print(f"Diagnostic bundle created: {result['output']}")
264
+ print(f"Files collected: {result['count']}")
265
+ for f in result['files_collected']:
266
+ print(f" - {f}")
267
+
268
+
269
+ def run_diag_command(args: List[str]) -> int:
270
+ """Run diag command from CLI."""
271
+ parser = argparse.ArgumentParser(prog="praisonai diag")
272
+ subparsers = parser.add_subparsers(dest="diag_command", help="Diag subcommands")
273
+
274
+ # diag export
275
+ export_parser = subparsers.add_parser("export", help="Export diagnostic bundle")
276
+ export_parser.add_argument("-o", "--output", type=str)
277
+ export_parser.add_argument("--include-logs", action="store_true", default=True)
278
+ export_parser.add_argument("--include-config", action="store_true", default=True)
279
+ export_parser.add_argument("--include-trace", action="store_true", default=True)
280
+ export_parser.add_argument("--workspace", "-w", type=str, default=".")
281
+ export_parser.add_argument("--json", action="store_true")
282
+ export_parser.set_defaults(func=DiagHandler.handle_export)
283
+
284
+ parsed = parser.parse_args(args)
285
+ if hasattr(parsed, 'func'):
286
+ return parsed.func(parsed)
287
+ else:
288
+ parser.print_help()
289
+ return 0
@@ -0,0 +1,63 @@
1
+ """
2
+ Doctor CLI module for PraisonAI.
3
+
4
+ Provides comprehensive health checks, diagnostics, and validation for the PraisonAI ecosystem.
5
+
6
+ Commands:
7
+ praisonai doctor - Run fast default checks
8
+ praisonai doctor env - Environment and API key validation
9
+ praisonai doctor config - Configuration file validation
10
+ praisonai doctor tools - Tool availability checks
11
+ praisonai doctor db - Database connectivity checks
12
+ praisonai doctor mcp - MCP server validation
13
+ praisonai doctor obs - Observability provider checks
14
+ praisonai doctor skills - Agent skills validation
15
+ praisonai doctor memory - Memory/session storage checks
16
+ praisonai doctor permissions - Filesystem permission checks
17
+ praisonai doctor network - Network connectivity checks
18
+ praisonai doctor performance - Import time analysis
19
+ praisonai doctor ci - CI-optimized checks
20
+ praisonai doctor selftest - Minimal agent dry-run
21
+ """
22
+
23
+ __version__ = "1.0.0"
24
+
25
+ __all__ = [
26
+ "DoctorHandler",
27
+ "DoctorEngine",
28
+ "CheckResult",
29
+ "CheckStatus",
30
+ "DoctorReport",
31
+ "CheckRegistry",
32
+ "TextFormatter",
33
+ "JsonFormatter",
34
+ ]
35
+
36
+
37
+ def __getattr__(name: str):
38
+ """Lazy load doctor components to minimize import overhead."""
39
+ if name == "DoctorHandler":
40
+ from .handler import DoctorHandler
41
+ return DoctorHandler
42
+ elif name == "DoctorEngine":
43
+ from .engine import DoctorEngine
44
+ return DoctorEngine
45
+ elif name == "CheckResult":
46
+ from .models import CheckResult
47
+ return CheckResult
48
+ elif name == "CheckStatus":
49
+ from .models import CheckStatus
50
+ return CheckStatus
51
+ elif name == "DoctorReport":
52
+ from .models import DoctorReport
53
+ return DoctorReport
54
+ elif name == "CheckRegistry":
55
+ from .registry import CheckRegistry
56
+ return CheckRegistry
57
+ elif name == "TextFormatter":
58
+ from .formatters import TextFormatter
59
+ return TextFormatter
60
+ elif name == "JsonFormatter":
61
+ from .formatters import JsonFormatter
62
+ return JsonFormatter
63
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
@@ -0,0 +1,24 @@
1
+ """
2
+ Doctor checks package.
3
+
4
+ Contains all individual check implementations organized by category.
5
+ """
6
+
7
+ # Import all check modules to register them
8
+ def register_all_checks():
9
+ """Register all doctor checks."""
10
+ from . import env_checks
11
+ from . import config_checks
12
+ from . import tools_checks
13
+ from . import db_checks
14
+ from . import mcp_checks
15
+ from . import obs_checks
16
+ from . import skills_checks
17
+ from . import memory_checks
18
+ from . import permissions_checks
19
+ from . import network_checks
20
+ from . import performance_checks
21
+ from . import selftest_checks
22
+ from . import serve_checks
23
+ from . import lsp_checks
24
+ from . import acp_checks
@@ -0,0 +1,240 @@
1
+ """
2
+ ACP health checks for PraisonAI Doctor.
3
+ """
4
+
5
+ import asyncio
6
+ import logging
7
+
8
+ from ..models import CheckCategory, CheckResult, CheckStatus
9
+ from ..registry import register_check
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ @register_check(
15
+ id="acp_module",
16
+ title="ACP Module Available",
17
+ category=CheckCategory.TOOLS,
18
+ description="Check if ACP module is installed"
19
+ )
20
+ def check_acp_module() -> CheckResult:
21
+ """Check if ACP module is available."""
22
+ try:
23
+ import importlib.util
24
+ spec = importlib.util.find_spec("praisonai.acp")
25
+
26
+ if spec is not None:
27
+ return CheckResult(
28
+ status=CheckStatus.PASS,
29
+ message="ACP module is available",
30
+ details={"module": "praisonai.acp"}
31
+ )
32
+ else:
33
+ return CheckResult(
34
+ status=CheckStatus.WARN,
35
+ message="ACP module not found",
36
+ details={"hint": "ACP module should be part of praisonai package"}
37
+ )
38
+ except Exception as e:
39
+ return CheckResult(
40
+ status=CheckStatus.FAIL,
41
+ message=f"Error checking ACP module: {e}",
42
+ details={"error": str(e)}
43
+ )
44
+
45
+
46
+ @register_check(
47
+ id="acp_sdk",
48
+ title="ACP SDK Available",
49
+ category=CheckCategory.TOOLS,
50
+ description="Check if agent-client-protocol SDK is installed"
51
+ )
52
+ def check_acp_sdk() -> CheckResult:
53
+ """Check if ACP SDK is available."""
54
+ try:
55
+ import importlib.util
56
+ spec = importlib.util.find_spec("acp")
57
+
58
+ if spec is not None:
59
+ return CheckResult(
60
+ status=CheckStatus.PASS,
61
+ message="ACP SDK (agent-client-protocol) is installed",
62
+ details={"package": "agent-client-protocol"}
63
+ )
64
+ else:
65
+ return CheckResult(
66
+ status=CheckStatus.INFO,
67
+ message="ACP SDK not installed (optional)",
68
+ details={"hint": "Install with: pip install agent-client-protocol"}
69
+ )
70
+ except Exception as e:
71
+ return CheckResult(
72
+ status=CheckStatus.FAIL,
73
+ message=f"Error checking ACP SDK: {e}",
74
+ details={"error": str(e)}
75
+ )
76
+
77
+
78
+ @register_check(
79
+ id="acp_server",
80
+ title="ACP Server Import",
81
+ category=CheckCategory.TOOLS,
82
+ description="Check if ACP server can be imported"
83
+ )
84
+ def check_acp_server() -> CheckResult:
85
+ """Check if ACP server can be imported."""
86
+ try:
87
+ from praisonai.acp import ACPServer # noqa: F401
88
+
89
+ return CheckResult(
90
+ status=CheckStatus.PASS,
91
+ message="ACP server can be imported",
92
+ details={"class": "ACPServer"}
93
+ )
94
+ except ImportError as e:
95
+ return CheckResult(
96
+ status=CheckStatus.WARN,
97
+ message=f"ACP server import failed: {e}",
98
+ details={"error": str(e)}
99
+ )
100
+ except Exception as e:
101
+ return CheckResult(
102
+ status=CheckStatus.FAIL,
103
+ message=f"Error importing ACP server: {e}",
104
+ details={"error": str(e)}
105
+ )
106
+
107
+
108
+ @register_check(
109
+ id="acp_config",
110
+ title="ACP Configuration",
111
+ category=CheckCategory.CONFIG,
112
+ description="Check ACP configuration"
113
+ )
114
+ def check_acp_config() -> CheckResult:
115
+ """Check ACP configuration."""
116
+ import os
117
+
118
+ config = {
119
+ "approval_mode": os.environ.get("PRAISONAI_APPROVAL_MODE", "manual"),
120
+ "allow_write": os.environ.get("PRAISONAI_ALLOW_WRITE", "false"),
121
+ "allow_shell": os.environ.get("PRAISONAI_ALLOW_SHELL", "false"),
122
+ }
123
+
124
+ return CheckResult(
125
+ status=CheckStatus.PASS,
126
+ message=f"ACP configured with approval_mode={config['approval_mode']}",
127
+ details=config
128
+ )
129
+
130
+
131
+ @register_check(
132
+ id="acp_runtime",
133
+ title="ACP Runtime Check",
134
+ category=CheckCategory.TOOLS,
135
+ description="Check if ACP runtime can start",
136
+ requires_deep=True
137
+ )
138
+ def check_acp_runtime() -> CheckResult:
139
+ """Check if ACP runtime can start."""
140
+ try:
141
+ from praisonai.cli.features.interactive_runtime import create_runtime
142
+
143
+ async def _check():
144
+ runtime = create_runtime(
145
+ workspace=".",
146
+ lsp=False,
147
+ acp=True
148
+ )
149
+ try:
150
+ await runtime.start()
151
+ ready = runtime.acp_ready
152
+ error = runtime._acp_state.error
153
+ read_only = runtime.read_only
154
+ return ready, error, read_only
155
+ finally:
156
+ await runtime.stop()
157
+
158
+ ready, error, read_only = asyncio.run(_check())
159
+
160
+ if ready:
161
+ return CheckResult(
162
+ status=CheckStatus.PASS,
163
+ message="ACP runtime started successfully",
164
+ details={"ready": True, "read_only": read_only}
165
+ )
166
+ else:
167
+ return CheckResult(
168
+ status=CheckStatus.WARN,
169
+ message=f"ACP runtime failed to start: {error}",
170
+ details={"ready": False, "error": error, "read_only": read_only}
171
+ )
172
+
173
+ except Exception as e:
174
+ return CheckResult(
175
+ status=CheckStatus.FAIL,
176
+ message=f"ACP runtime check failed: {e}",
177
+ details={"error": str(e)}
178
+ )
179
+
180
+
181
+ @register_check(
182
+ id="interactive_runtime",
183
+ title="Interactive Runtime Check",
184
+ category=CheckCategory.TOOLS,
185
+ description="Check if full interactive runtime can start",
186
+ requires_deep=True
187
+ )
188
+ def check_interactive_runtime() -> CheckResult:
189
+ """Check if full interactive runtime can start."""
190
+ try:
191
+ from praisonai.cli.features.interactive_runtime import create_runtime
192
+
193
+ async def _check():
194
+ runtime = create_runtime(
195
+ workspace=".",
196
+ lsp=True,
197
+ acp=True
198
+ )
199
+ try:
200
+ await runtime.start()
201
+ status = runtime.get_status()
202
+ return status
203
+ finally:
204
+ await runtime.stop()
205
+
206
+ status = asyncio.run(_check())
207
+
208
+ lsp_ready = status.get("lsp", {}).get("ready", False)
209
+ acp_ready = status.get("acp", {}).get("ready", False)
210
+
211
+ if lsp_ready and acp_ready:
212
+ return CheckResult(
213
+ status=CheckStatus.PASS,
214
+ message="Interactive runtime fully operational",
215
+ details=status
216
+ )
217
+ elif lsp_ready or acp_ready:
218
+ return CheckResult(
219
+ status=CheckStatus.WARN,
220
+ message="Interactive runtime partially operational",
221
+ details=status
222
+ )
223
+ else:
224
+ return CheckResult(
225
+ status=CheckStatus.FAIL,
226
+ message="Interactive runtime failed to start",
227
+ details=status
228
+ )
229
+
230
+ except Exception as e:
231
+ return CheckResult(
232
+ status=CheckStatus.FAIL,
233
+ message=f"Interactive runtime check failed: {e}",
234
+ details={"error": str(e)}
235
+ )
236
+
237
+
238
+ def register_acp_checks():
239
+ """Register all ACP checks."""
240
+ pass