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,199 @@
1
+ """
2
+ LSP 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="lsp_module",
16
+ title="LSP Module Available",
17
+ category=CheckCategory.TOOLS,
18
+ description="Check if LSP module is installed"
19
+ )
20
+ def check_lsp_module() -> CheckResult:
21
+ """Check if LSP module is available."""
22
+ try:
23
+ import importlib.util
24
+ spec = importlib.util.find_spec("praisonaiagents.lsp")
25
+
26
+ if spec is not None:
27
+ return CheckResult(
28
+ status=CheckStatus.PASS,
29
+ message="LSP module is available",
30
+ details={"module": "praisonaiagents.lsp"}
31
+ )
32
+ else:
33
+ return CheckResult(
34
+ status=CheckStatus.WARN,
35
+ message="LSP module not found",
36
+ details={"hint": "Install praisonaiagents with LSP support"}
37
+ )
38
+ except Exception as e:
39
+ return CheckResult(
40
+ status=CheckStatus.FAIL,
41
+ message=f"Error checking LSP module: {e}",
42
+ details={"error": str(e)}
43
+ )
44
+
45
+
46
+ @register_check(
47
+ id="lsp_client",
48
+ title="LSP Client Import",
49
+ category=CheckCategory.TOOLS,
50
+ description="Check if LSP client can be imported"
51
+ )
52
+ def check_lsp_client() -> CheckResult:
53
+ """Check if LSP client can be imported."""
54
+ try:
55
+ from praisonaiagents.lsp import LSPClient # noqa: F401
56
+
57
+ return CheckResult(
58
+ status=CheckStatus.PASS,
59
+ message="LSP client can be imported",
60
+ details={"class": "LSPClient"}
61
+ )
62
+ except ImportError as e:
63
+ return CheckResult(
64
+ status=CheckStatus.WARN,
65
+ message=f"LSP client import failed: {e}",
66
+ details={"error": str(e)}
67
+ )
68
+ except Exception as e:
69
+ return CheckResult(
70
+ status=CheckStatus.FAIL,
71
+ message=f"Error importing LSP client: {e}",
72
+ details={"error": str(e)}
73
+ )
74
+
75
+
76
+ @register_check(
77
+ id="lsp_server_python",
78
+ title="Python LSP Server",
79
+ category=CheckCategory.TOOLS,
80
+ description="Check if Python language server is available"
81
+ )
82
+ def check_lsp_server_python() -> CheckResult:
83
+ """Check if Python language server is available."""
84
+ import shutil
85
+
86
+ # Check for common Python language servers
87
+ servers = [
88
+ ("pyright-langserver", "pyright"),
89
+ ("pylsp", "python-lsp-server"),
90
+ ("pyls", "python-language-server"),
91
+ ]
92
+
93
+ found = []
94
+ for cmd, package in servers:
95
+ if shutil.which(cmd):
96
+ found.append({"command": cmd, "package": package})
97
+
98
+ if found:
99
+ return CheckResult(
100
+ status=CheckStatus.PASS,
101
+ message=f"Python LSP server available: {found[0]['command']}",
102
+ details={"servers": found}
103
+ )
104
+ else:
105
+ return CheckResult(
106
+ status=CheckStatus.WARN,
107
+ message="No Python LSP server found",
108
+ details={
109
+ "hint": "Install with: npm install -g pyright OR pip install python-lsp-server",
110
+ "checked": [s[0] for s in servers]
111
+ }
112
+ )
113
+
114
+
115
+ @register_check(
116
+ id="lsp_server_typescript",
117
+ title="TypeScript LSP Server",
118
+ category=CheckCategory.TOOLS,
119
+ description="Check if TypeScript language server is available"
120
+ )
121
+ def check_lsp_server_typescript() -> CheckResult:
122
+ """Check if TypeScript language server is available."""
123
+ import shutil
124
+
125
+ # Check for TypeScript language server
126
+ if shutil.which("typescript-language-server"):
127
+ return CheckResult(
128
+ status=CheckStatus.PASS,
129
+ message="TypeScript LSP server available",
130
+ details={"command": "typescript-language-server"}
131
+ )
132
+ elif shutil.which("tsserver"):
133
+ return CheckResult(
134
+ status=CheckStatus.PASS,
135
+ message="TypeScript server available (tsserver)",
136
+ details={"command": "tsserver"}
137
+ )
138
+ else:
139
+ return CheckResult(
140
+ status=CheckStatus.INFO,
141
+ message="TypeScript LSP server not found (optional)",
142
+ details={
143
+ "hint": "Install with: npm install -g typescript-language-server typescript"
144
+ }
145
+ )
146
+
147
+
148
+ @register_check(
149
+ id="lsp_runtime",
150
+ title="LSP Runtime Check",
151
+ category=CheckCategory.TOOLS,
152
+ description="Check if LSP runtime can start",
153
+ requires_deep=True
154
+ )
155
+ def check_lsp_runtime() -> CheckResult:
156
+ """Check if LSP runtime can start."""
157
+ try:
158
+ from praisonai.cli.features.interactive_runtime import create_runtime
159
+
160
+ async def _check():
161
+ runtime = create_runtime(
162
+ workspace=".",
163
+ lsp=True,
164
+ acp=False
165
+ )
166
+ try:
167
+ await runtime.start()
168
+ ready = runtime.lsp_ready
169
+ error = runtime._lsp_state.error
170
+ return ready, error
171
+ finally:
172
+ await runtime.stop()
173
+
174
+ ready, error = asyncio.run(_check())
175
+
176
+ if ready:
177
+ return CheckResult(
178
+ status=CheckStatus.PASS,
179
+ message="LSP runtime started successfully",
180
+ details={"ready": True}
181
+ )
182
+ else:
183
+ return CheckResult(
184
+ status=CheckStatus.WARN,
185
+ message=f"LSP runtime failed to start: {error}",
186
+ details={"ready": False, "error": error}
187
+ )
188
+
189
+ except Exception as e:
190
+ return CheckResult(
191
+ status=CheckStatus.FAIL,
192
+ message=f"LSP runtime check failed: {e}",
193
+ details={"error": str(e)}
194
+ )
195
+
196
+
197
+ def register_lsp_checks():
198
+ """Register all LSP checks."""
199
+ pass
@@ -0,0 +1,349 @@
1
+ """
2
+ MCP (Model Context Protocol) checks for the Doctor CLI module.
3
+
4
+ Validates MCP server configurations and connectivity.
5
+ """
6
+
7
+ import os
8
+ import shutil
9
+ from pathlib import Path
10
+
11
+ from ..models import (
12
+ CheckCategory,
13
+ CheckResult,
14
+ CheckStatus,
15
+ CheckSeverity,
16
+ DoctorConfig,
17
+ )
18
+ from ..registry import register_check
19
+
20
+
21
+ def _find_mcp_config() -> dict:
22
+ """Find MCP configuration files."""
23
+ locations = [
24
+ Path.cwd() / ".praison" / "mcp.json",
25
+ Path.cwd() / ".praison" / "mcp" / "config.json",
26
+ Path.home() / ".praison" / "mcp.json",
27
+ Path.home() / ".config" / "praison" / "mcp.json",
28
+ ]
29
+
30
+ for loc in locations:
31
+ if loc.exists():
32
+ try:
33
+ import json
34
+ with open(loc) as f:
35
+ return {"path": str(loc), "config": json.load(f)}
36
+ except Exception:
37
+ pass
38
+
39
+ return {}
40
+
41
+
42
+ @register_check(
43
+ id="mcp_config",
44
+ title="MCP Configuration",
45
+ description="Check MCP configuration file",
46
+ category=CheckCategory.MCP,
47
+ severity=CheckSeverity.INFO,
48
+ )
49
+ def check_mcp_config(config: DoctorConfig) -> CheckResult:
50
+ """Check MCP configuration file."""
51
+ mcp_config = _find_mcp_config()
52
+
53
+ if mcp_config:
54
+ servers = mcp_config.get("config", {}).get("mcpServers", {})
55
+ server_count = len(servers) if isinstance(servers, dict) else 0
56
+
57
+ return CheckResult(
58
+ id="mcp_config",
59
+ title="MCP Configuration",
60
+ category=CheckCategory.MCP,
61
+ status=CheckStatus.PASS,
62
+ message=f"MCP config found with {server_count} server(s)",
63
+ details=f"Path: {mcp_config['path']}",
64
+ metadata={"path": mcp_config["path"], "server_count": server_count},
65
+ )
66
+ else:
67
+ return CheckResult(
68
+ id="mcp_config",
69
+ title="MCP Configuration",
70
+ category=CheckCategory.MCP,
71
+ status=CheckStatus.SKIP,
72
+ message="No MCP configuration found (optional)",
73
+ details="Create .praison/mcp.json to configure MCP servers",
74
+ )
75
+
76
+
77
+ @register_check(
78
+ id="mcp_npx",
79
+ title="npx for MCP",
80
+ description="Check npx availability for MCP servers",
81
+ category=CheckCategory.MCP,
82
+ severity=CheckSeverity.LOW,
83
+ )
84
+ def check_mcp_npx(config: DoctorConfig) -> CheckResult:
85
+ """Check npx availability for MCP servers."""
86
+ npx_path = shutil.which("npx")
87
+
88
+ if npx_path:
89
+ return CheckResult(
90
+ id="mcp_npx",
91
+ title="npx for MCP",
92
+ category=CheckCategory.MCP,
93
+ status=CheckStatus.PASS,
94
+ message=f"npx available at {npx_path}",
95
+ )
96
+ else:
97
+ return CheckResult(
98
+ id="mcp_npx",
99
+ title="npx for MCP",
100
+ category=CheckCategory.MCP,
101
+ status=CheckStatus.WARN,
102
+ message="npx not found (required for most MCP servers)",
103
+ remediation="Install Node.js to use MCP servers",
104
+ )
105
+
106
+
107
+ @register_check(
108
+ id="mcp_python",
109
+ title="Python MCP Support",
110
+ description="Check Python MCP package availability",
111
+ category=CheckCategory.MCP,
112
+ severity=CheckSeverity.LOW,
113
+ )
114
+ def check_mcp_python(config: DoctorConfig) -> CheckResult:
115
+ """Check Python MCP package availability."""
116
+ try:
117
+ import mcp
118
+ version = getattr(mcp, "__version__", "unknown")
119
+ return CheckResult(
120
+ id="mcp_python",
121
+ title="Python MCP Support",
122
+ category=CheckCategory.MCP,
123
+ status=CheckStatus.PASS,
124
+ message=f"mcp package {version} available",
125
+ )
126
+ except ImportError:
127
+ return CheckResult(
128
+ id="mcp_python",
129
+ title="Python MCP Support",
130
+ category=CheckCategory.MCP,
131
+ status=CheckStatus.SKIP,
132
+ message="mcp package not installed (optional)",
133
+ remediation="Install with: pip install mcp",
134
+ )
135
+
136
+
137
+ @register_check(
138
+ id="mcp_servers_valid",
139
+ title="MCP Server Configs Valid",
140
+ description="Validate MCP server configurations",
141
+ category=CheckCategory.MCP,
142
+ severity=CheckSeverity.MEDIUM,
143
+ dependencies=["mcp_config"],
144
+ )
145
+ def check_mcp_servers_valid(config: DoctorConfig) -> CheckResult:
146
+ """Validate MCP server configurations."""
147
+ mcp_config = _find_mcp_config()
148
+
149
+ if not mcp_config:
150
+ return CheckResult(
151
+ id="mcp_servers_valid",
152
+ title="MCP Server Configs Valid",
153
+ category=CheckCategory.MCP,
154
+ status=CheckStatus.SKIP,
155
+ message="No MCP configuration to validate",
156
+ )
157
+
158
+ servers = mcp_config.get("config", {}).get("mcpServers", {})
159
+ if not servers:
160
+ return CheckResult(
161
+ id="mcp_servers_valid",
162
+ title="MCP Server Configs Valid",
163
+ category=CheckCategory.MCP,
164
+ status=CheckStatus.SKIP,
165
+ message="No MCP servers configured",
166
+ )
167
+
168
+ valid = []
169
+ invalid = []
170
+
171
+ for name, server_config in servers.items():
172
+ if not isinstance(server_config, dict):
173
+ invalid.append(f"{name}: invalid config format")
174
+ continue
175
+
176
+ command = server_config.get("command")
177
+ if not command:
178
+ invalid.append(f"{name}: missing 'command'")
179
+ continue
180
+
181
+ # Check if command executable exists
182
+ cmd_parts = command.split() if isinstance(command, str) else [command]
183
+ cmd_exe = cmd_parts[0] if cmd_parts else ""
184
+
185
+ if cmd_exe and shutil.which(cmd_exe):
186
+ valid.append(name)
187
+ else:
188
+ invalid.append(f"{name}: command '{cmd_exe}' not found")
189
+
190
+ if invalid:
191
+ return CheckResult(
192
+ id="mcp_servers_valid",
193
+ title="MCP Server Configs Valid",
194
+ category=CheckCategory.MCP,
195
+ status=CheckStatus.WARN,
196
+ message=f"{len(valid)} valid, {len(invalid)} invalid server(s)",
197
+ details="; ".join(invalid[:3]) + ("..." if len(invalid) > 3 else ""),
198
+ metadata={"valid": valid, "invalid": invalid},
199
+ )
200
+ else:
201
+ return CheckResult(
202
+ id="mcp_servers_valid",
203
+ title="MCP Server Configs Valid",
204
+ category=CheckCategory.MCP,
205
+ status=CheckStatus.PASS,
206
+ message=f"All {len(valid)} MCP server config(s) valid",
207
+ metadata={"valid": valid},
208
+ )
209
+
210
+
211
+ @register_check(
212
+ id="mcp_server_spawn",
213
+ title="MCP Server Spawn Test",
214
+ description="Test spawning MCP servers",
215
+ category=CheckCategory.MCP,
216
+ severity=CheckSeverity.LOW,
217
+ requires_deep=True,
218
+ )
219
+ def check_mcp_server_spawn(config: DoctorConfig) -> CheckResult:
220
+ """Test spawning MCP servers (deep mode only)."""
221
+ mcp_config = _find_mcp_config()
222
+
223
+ if not mcp_config:
224
+ return CheckResult(
225
+ id="mcp_server_spawn",
226
+ title="MCP Server Spawn Test",
227
+ category=CheckCategory.MCP,
228
+ status=CheckStatus.SKIP,
229
+ message="No MCP configuration to test",
230
+ )
231
+
232
+ servers = mcp_config.get("config", {}).get("mcpServers", {})
233
+ if not servers:
234
+ return CheckResult(
235
+ id="mcp_server_spawn",
236
+ title="MCP Server Spawn Test",
237
+ category=CheckCategory.MCP,
238
+ status=CheckStatus.SKIP,
239
+ message="No MCP servers to test",
240
+ )
241
+
242
+ # Only test first server to avoid long delays
243
+ test_server = config.name if config.name else list(servers.keys())[0]
244
+ server_config = servers.get(test_server)
245
+
246
+ if not server_config:
247
+ return CheckResult(
248
+ id="mcp_server_spawn",
249
+ title="MCP Server Spawn Test",
250
+ category=CheckCategory.MCP,
251
+ status=CheckStatus.SKIP,
252
+ message=f"Server '{test_server}' not found",
253
+ )
254
+
255
+ try:
256
+ import subprocess
257
+
258
+ command = server_config.get("command", "")
259
+ args = server_config.get("args", [])
260
+
261
+ if isinstance(command, str):
262
+ cmd = command.split() + args
263
+ else:
264
+ cmd = [command] + args
265
+
266
+ # Try to start the server with a short timeout
267
+ proc = subprocess.Popen(
268
+ cmd,
269
+ stdout=subprocess.PIPE,
270
+ stderr=subprocess.PIPE,
271
+ env={**os.environ, **server_config.get("env", {})},
272
+ )
273
+
274
+ # Wait briefly to see if it starts
275
+ import time
276
+ time.sleep(1)
277
+
278
+ if proc.poll() is None:
279
+ # Process is still running - success
280
+ proc.terminate()
281
+ proc.wait(timeout=2)
282
+ return CheckResult(
283
+ id="mcp_server_spawn",
284
+ title="MCP Server Spawn Test",
285
+ category=CheckCategory.MCP,
286
+ status=CheckStatus.PASS,
287
+ message=f"Server '{test_server}' started successfully",
288
+ )
289
+ else:
290
+ # Process exited
291
+ stderr = proc.stderr.read().decode()[:200] if proc.stderr else ""
292
+ return CheckResult(
293
+ id="mcp_server_spawn",
294
+ title="MCP Server Spawn Test",
295
+ category=CheckCategory.MCP,
296
+ status=CheckStatus.WARN,
297
+ message=f"Server '{test_server}' exited immediately",
298
+ details=stderr if stderr else "No error output",
299
+ )
300
+
301
+ except FileNotFoundError as e:
302
+ return CheckResult(
303
+ id="mcp_server_spawn",
304
+ title="MCP Server Spawn Test",
305
+ category=CheckCategory.MCP,
306
+ status=CheckStatus.FAIL,
307
+ message=f"Command not found for '{test_server}'",
308
+ details=str(e),
309
+ remediation="Install the required MCP server package",
310
+ )
311
+ except Exception as e:
312
+ return CheckResult(
313
+ id="mcp_server_spawn",
314
+ title="MCP Server Spawn Test",
315
+ category=CheckCategory.MCP,
316
+ status=CheckStatus.WARN,
317
+ message=f"Could not test server '{test_server}'",
318
+ details=str(e)[:200],
319
+ )
320
+
321
+
322
+ @register_check(
323
+ id="mcp_praisonai_integration",
324
+ title="PraisonAI MCP Integration",
325
+ description="Check PraisonAI MCP integration",
326
+ category=CheckCategory.MCP,
327
+ severity=CheckSeverity.LOW,
328
+ )
329
+ def check_mcp_praisonai_integration(config: DoctorConfig) -> CheckResult:
330
+ """Check PraisonAI MCP integration."""
331
+ try:
332
+ from praisonaiagents.mcp import MCP
333
+ return CheckResult(
334
+ id="mcp_praisonai_integration",
335
+ title="PraisonAI MCP Integration",
336
+ category=CheckCategory.MCP,
337
+ status=CheckStatus.PASS,
338
+ message="PraisonAI MCP integration available",
339
+ )
340
+ except ImportError as e:
341
+ return CheckResult(
342
+ id="mcp_praisonai_integration",
343
+ title="PraisonAI MCP Integration",
344
+ category=CheckCategory.MCP,
345
+ status=CheckStatus.SKIP,
346
+ message="MCP integration not available",
347
+ details=str(e),
348
+ remediation="Install with: pip install praisonaiagents[mcp]",
349
+ )