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.
- praisonai/__init__.py +54 -0
- praisonai/__main__.py +15 -0
- praisonai/acp/__init__.py +54 -0
- praisonai/acp/config.py +159 -0
- praisonai/acp/server.py +587 -0
- praisonai/acp/session.py +219 -0
- praisonai/adapters/__init__.py +50 -0
- praisonai/adapters/readers.py +395 -0
- praisonai/adapters/rerankers.py +315 -0
- praisonai/adapters/retrievers.py +394 -0
- praisonai/adapters/vector_stores.py +409 -0
- praisonai/agent_scheduler.py +337 -0
- praisonai/agents_generator.py +903 -0
- praisonai/api/call.py +292 -0
- praisonai/auto.py +1197 -0
- praisonai/capabilities/__init__.py +275 -0
- praisonai/capabilities/a2a.py +140 -0
- praisonai/capabilities/assistants.py +283 -0
- praisonai/capabilities/audio.py +320 -0
- praisonai/capabilities/batches.py +469 -0
- praisonai/capabilities/completions.py +336 -0
- praisonai/capabilities/container_files.py +155 -0
- praisonai/capabilities/containers.py +93 -0
- praisonai/capabilities/embeddings.py +158 -0
- praisonai/capabilities/files.py +467 -0
- praisonai/capabilities/fine_tuning.py +293 -0
- praisonai/capabilities/guardrails.py +182 -0
- praisonai/capabilities/images.py +330 -0
- praisonai/capabilities/mcp.py +190 -0
- praisonai/capabilities/messages.py +270 -0
- praisonai/capabilities/moderations.py +154 -0
- praisonai/capabilities/ocr.py +217 -0
- praisonai/capabilities/passthrough.py +204 -0
- praisonai/capabilities/rag.py +207 -0
- praisonai/capabilities/realtime.py +160 -0
- praisonai/capabilities/rerank.py +165 -0
- praisonai/capabilities/responses.py +266 -0
- praisonai/capabilities/search.py +109 -0
- praisonai/capabilities/skills.py +133 -0
- praisonai/capabilities/vector_store_files.py +334 -0
- praisonai/capabilities/vector_stores.py +304 -0
- praisonai/capabilities/videos.py +141 -0
- praisonai/chainlit_ui.py +304 -0
- praisonai/chat/__init__.py +106 -0
- praisonai/chat/app.py +125 -0
- praisonai/cli/__init__.py +26 -0
- praisonai/cli/app.py +213 -0
- praisonai/cli/commands/__init__.py +75 -0
- praisonai/cli/commands/acp.py +70 -0
- praisonai/cli/commands/completion.py +333 -0
- praisonai/cli/commands/config.py +166 -0
- praisonai/cli/commands/debug.py +142 -0
- praisonai/cli/commands/diag.py +55 -0
- praisonai/cli/commands/doctor.py +166 -0
- praisonai/cli/commands/environment.py +179 -0
- praisonai/cli/commands/lsp.py +112 -0
- praisonai/cli/commands/mcp.py +210 -0
- praisonai/cli/commands/profile.py +457 -0
- praisonai/cli/commands/run.py +228 -0
- praisonai/cli/commands/schedule.py +150 -0
- praisonai/cli/commands/serve.py +97 -0
- praisonai/cli/commands/session.py +212 -0
- praisonai/cli/commands/traces.py +145 -0
- praisonai/cli/commands/version.py +101 -0
- praisonai/cli/configuration/__init__.py +18 -0
- praisonai/cli/configuration/loader.py +353 -0
- praisonai/cli/configuration/paths.py +114 -0
- praisonai/cli/configuration/schema.py +164 -0
- praisonai/cli/features/__init__.py +268 -0
- praisonai/cli/features/acp.py +236 -0
- praisonai/cli/features/action_orchestrator.py +546 -0
- praisonai/cli/features/agent_scheduler.py +773 -0
- praisonai/cli/features/agent_tools.py +474 -0
- praisonai/cli/features/agents.py +375 -0
- praisonai/cli/features/at_mentions.py +471 -0
- praisonai/cli/features/auto_memory.py +182 -0
- praisonai/cli/features/autonomy_mode.py +490 -0
- praisonai/cli/features/background.py +356 -0
- praisonai/cli/features/base.py +168 -0
- praisonai/cli/features/capabilities.py +1326 -0
- praisonai/cli/features/checkpoints.py +338 -0
- praisonai/cli/features/code_intelligence.py +652 -0
- praisonai/cli/features/compaction.py +294 -0
- praisonai/cli/features/compare.py +534 -0
- praisonai/cli/features/cost_tracker.py +514 -0
- praisonai/cli/features/debug.py +810 -0
- praisonai/cli/features/deploy.py +517 -0
- praisonai/cli/features/diag.py +289 -0
- praisonai/cli/features/doctor/__init__.py +63 -0
- praisonai/cli/features/doctor/checks/__init__.py +24 -0
- praisonai/cli/features/doctor/checks/acp_checks.py +240 -0
- praisonai/cli/features/doctor/checks/config_checks.py +366 -0
- praisonai/cli/features/doctor/checks/db_checks.py +366 -0
- praisonai/cli/features/doctor/checks/env_checks.py +543 -0
- praisonai/cli/features/doctor/checks/lsp_checks.py +199 -0
- praisonai/cli/features/doctor/checks/mcp_checks.py +349 -0
- praisonai/cli/features/doctor/checks/memory_checks.py +268 -0
- praisonai/cli/features/doctor/checks/network_checks.py +251 -0
- praisonai/cli/features/doctor/checks/obs_checks.py +328 -0
- praisonai/cli/features/doctor/checks/performance_checks.py +235 -0
- praisonai/cli/features/doctor/checks/permissions_checks.py +259 -0
- praisonai/cli/features/doctor/checks/selftest_checks.py +322 -0
- praisonai/cli/features/doctor/checks/serve_checks.py +426 -0
- praisonai/cli/features/doctor/checks/skills_checks.py +231 -0
- praisonai/cli/features/doctor/checks/tools_checks.py +371 -0
- praisonai/cli/features/doctor/engine.py +266 -0
- praisonai/cli/features/doctor/formatters.py +310 -0
- praisonai/cli/features/doctor/handler.py +397 -0
- praisonai/cli/features/doctor/models.py +264 -0
- praisonai/cli/features/doctor/registry.py +239 -0
- praisonai/cli/features/endpoints.py +1019 -0
- praisonai/cli/features/eval.py +560 -0
- praisonai/cli/features/external_agents.py +231 -0
- praisonai/cli/features/fast_context.py +410 -0
- praisonai/cli/features/flow_display.py +566 -0
- praisonai/cli/features/git_integration.py +651 -0
- praisonai/cli/features/guardrail.py +171 -0
- praisonai/cli/features/handoff.py +185 -0
- praisonai/cli/features/hooks.py +583 -0
- praisonai/cli/features/image.py +384 -0
- praisonai/cli/features/interactive_runtime.py +585 -0
- praisonai/cli/features/interactive_tools.py +380 -0
- praisonai/cli/features/interactive_tui.py +603 -0
- praisonai/cli/features/jobs.py +632 -0
- praisonai/cli/features/knowledge.py +531 -0
- praisonai/cli/features/lite.py +244 -0
- praisonai/cli/features/lsp_cli.py +225 -0
- praisonai/cli/features/mcp.py +169 -0
- praisonai/cli/features/message_queue.py +587 -0
- praisonai/cli/features/metrics.py +211 -0
- praisonai/cli/features/n8n.py +673 -0
- praisonai/cli/features/observability.py +293 -0
- praisonai/cli/features/ollama.py +361 -0
- praisonai/cli/features/output_style.py +273 -0
- praisonai/cli/features/package.py +631 -0
- praisonai/cli/features/performance.py +308 -0
- praisonai/cli/features/persistence.py +636 -0
- praisonai/cli/features/profile.py +226 -0
- praisonai/cli/features/profiler/__init__.py +81 -0
- praisonai/cli/features/profiler/core.py +558 -0
- praisonai/cli/features/profiler/optimizations.py +652 -0
- praisonai/cli/features/profiler/suite.py +386 -0
- praisonai/cli/features/profiling.py +350 -0
- praisonai/cli/features/queue/__init__.py +73 -0
- praisonai/cli/features/queue/manager.py +395 -0
- praisonai/cli/features/queue/models.py +286 -0
- praisonai/cli/features/queue/persistence.py +564 -0
- praisonai/cli/features/queue/scheduler.py +484 -0
- praisonai/cli/features/queue/worker.py +372 -0
- praisonai/cli/features/recipe.py +1723 -0
- praisonai/cli/features/recipes.py +449 -0
- praisonai/cli/features/registry.py +229 -0
- praisonai/cli/features/repo_map.py +860 -0
- praisonai/cli/features/router.py +466 -0
- praisonai/cli/features/sandbox_executor.py +515 -0
- praisonai/cli/features/serve.py +829 -0
- praisonai/cli/features/session.py +222 -0
- praisonai/cli/features/skills.py +856 -0
- praisonai/cli/features/slash_commands.py +650 -0
- praisonai/cli/features/telemetry.py +179 -0
- praisonai/cli/features/templates.py +1384 -0
- praisonai/cli/features/thinking.py +305 -0
- praisonai/cli/features/todo.py +334 -0
- praisonai/cli/features/tools.py +680 -0
- praisonai/cli/features/tui/__init__.py +83 -0
- praisonai/cli/features/tui/app.py +580 -0
- praisonai/cli/features/tui/cli.py +566 -0
- praisonai/cli/features/tui/debug.py +511 -0
- praisonai/cli/features/tui/events.py +99 -0
- praisonai/cli/features/tui/mock_provider.py +328 -0
- praisonai/cli/features/tui/orchestrator.py +652 -0
- praisonai/cli/features/tui/screens/__init__.py +50 -0
- praisonai/cli/features/tui/screens/main.py +245 -0
- praisonai/cli/features/tui/screens/queue.py +174 -0
- praisonai/cli/features/tui/screens/session.py +124 -0
- praisonai/cli/features/tui/screens/settings.py +148 -0
- praisonai/cli/features/tui/widgets/__init__.py +56 -0
- praisonai/cli/features/tui/widgets/chat.py +261 -0
- praisonai/cli/features/tui/widgets/composer.py +224 -0
- praisonai/cli/features/tui/widgets/queue_panel.py +200 -0
- praisonai/cli/features/tui/widgets/status.py +167 -0
- praisonai/cli/features/tui/widgets/tool_panel.py +248 -0
- praisonai/cli/features/workflow.py +720 -0
- praisonai/cli/legacy.py +236 -0
- praisonai/cli/main.py +5559 -0
- praisonai/cli/schedule_cli.py +54 -0
- praisonai/cli/state/__init__.py +31 -0
- praisonai/cli/state/identifiers.py +161 -0
- praisonai/cli/state/sessions.py +313 -0
- praisonai/code/__init__.py +93 -0
- praisonai/code/agent_tools.py +344 -0
- praisonai/code/diff/__init__.py +21 -0
- praisonai/code/diff/diff_strategy.py +432 -0
- praisonai/code/tools/__init__.py +27 -0
- praisonai/code/tools/apply_diff.py +221 -0
- praisonai/code/tools/execute_command.py +275 -0
- praisonai/code/tools/list_files.py +274 -0
- praisonai/code/tools/read_file.py +206 -0
- praisonai/code/tools/search_replace.py +248 -0
- praisonai/code/tools/write_file.py +217 -0
- praisonai/code/utils/__init__.py +46 -0
- praisonai/code/utils/file_utils.py +307 -0
- praisonai/code/utils/ignore_utils.py +308 -0
- praisonai/code/utils/text_utils.py +276 -0
- praisonai/db/__init__.py +64 -0
- praisonai/db/adapter.py +531 -0
- praisonai/deploy/__init__.py +62 -0
- praisonai/deploy/api.py +231 -0
- praisonai/deploy/docker.py +454 -0
- praisonai/deploy/doctor.py +367 -0
- praisonai/deploy/main.py +327 -0
- praisonai/deploy/models.py +179 -0
- praisonai/deploy/providers/__init__.py +33 -0
- praisonai/deploy/providers/aws.py +331 -0
- praisonai/deploy/providers/azure.py +358 -0
- praisonai/deploy/providers/base.py +101 -0
- praisonai/deploy/providers/gcp.py +314 -0
- praisonai/deploy/schema.py +208 -0
- praisonai/deploy.py +185 -0
- praisonai/endpoints/__init__.py +53 -0
- praisonai/endpoints/a2u_server.py +410 -0
- praisonai/endpoints/discovery.py +165 -0
- praisonai/endpoints/providers/__init__.py +28 -0
- praisonai/endpoints/providers/a2a.py +253 -0
- praisonai/endpoints/providers/a2u.py +208 -0
- praisonai/endpoints/providers/agents_api.py +171 -0
- praisonai/endpoints/providers/base.py +231 -0
- praisonai/endpoints/providers/mcp.py +263 -0
- praisonai/endpoints/providers/recipe.py +206 -0
- praisonai/endpoints/providers/tools_mcp.py +150 -0
- praisonai/endpoints/registry.py +131 -0
- praisonai/endpoints/server.py +161 -0
- praisonai/inbuilt_tools/__init__.py +24 -0
- praisonai/inbuilt_tools/autogen_tools.py +117 -0
- praisonai/inc/__init__.py +2 -0
- praisonai/inc/config.py +96 -0
- praisonai/inc/models.py +155 -0
- praisonai/integrations/__init__.py +56 -0
- praisonai/integrations/base.py +303 -0
- praisonai/integrations/claude_code.py +270 -0
- praisonai/integrations/codex_cli.py +255 -0
- praisonai/integrations/cursor_cli.py +195 -0
- praisonai/integrations/gemini_cli.py +222 -0
- praisonai/jobs/__init__.py +67 -0
- praisonai/jobs/executor.py +425 -0
- praisonai/jobs/models.py +230 -0
- praisonai/jobs/router.py +314 -0
- praisonai/jobs/server.py +186 -0
- praisonai/jobs/store.py +203 -0
- praisonai/llm/__init__.py +66 -0
- praisonai/llm/registry.py +382 -0
- praisonai/mcp_server/__init__.py +152 -0
- praisonai/mcp_server/adapters/__init__.py +74 -0
- praisonai/mcp_server/adapters/agents.py +128 -0
- praisonai/mcp_server/adapters/capabilities.py +168 -0
- praisonai/mcp_server/adapters/cli_tools.py +568 -0
- praisonai/mcp_server/adapters/extended_capabilities.py +462 -0
- praisonai/mcp_server/adapters/knowledge.py +93 -0
- praisonai/mcp_server/adapters/memory.py +104 -0
- praisonai/mcp_server/adapters/prompts.py +306 -0
- praisonai/mcp_server/adapters/resources.py +124 -0
- praisonai/mcp_server/adapters/tools_bridge.py +280 -0
- praisonai/mcp_server/auth/__init__.py +48 -0
- praisonai/mcp_server/auth/api_key.py +291 -0
- praisonai/mcp_server/auth/oauth.py +460 -0
- praisonai/mcp_server/auth/oidc.py +289 -0
- praisonai/mcp_server/auth/scopes.py +260 -0
- praisonai/mcp_server/cli.py +852 -0
- praisonai/mcp_server/elicitation.py +445 -0
- praisonai/mcp_server/icons.py +302 -0
- praisonai/mcp_server/recipe_adapter.py +573 -0
- praisonai/mcp_server/recipe_cli.py +824 -0
- praisonai/mcp_server/registry.py +703 -0
- praisonai/mcp_server/sampling.py +422 -0
- praisonai/mcp_server/server.py +490 -0
- praisonai/mcp_server/tasks.py +443 -0
- praisonai/mcp_server/transports/__init__.py +18 -0
- praisonai/mcp_server/transports/http_stream.py +376 -0
- praisonai/mcp_server/transports/stdio.py +132 -0
- praisonai/persistence/__init__.py +84 -0
- praisonai/persistence/config.py +238 -0
- praisonai/persistence/conversation/__init__.py +25 -0
- praisonai/persistence/conversation/async_mysql.py +427 -0
- praisonai/persistence/conversation/async_postgres.py +410 -0
- praisonai/persistence/conversation/async_sqlite.py +371 -0
- praisonai/persistence/conversation/base.py +151 -0
- praisonai/persistence/conversation/json_store.py +250 -0
- praisonai/persistence/conversation/mysql.py +387 -0
- praisonai/persistence/conversation/postgres.py +401 -0
- praisonai/persistence/conversation/singlestore.py +240 -0
- praisonai/persistence/conversation/sqlite.py +341 -0
- praisonai/persistence/conversation/supabase.py +203 -0
- praisonai/persistence/conversation/surrealdb.py +287 -0
- praisonai/persistence/factory.py +301 -0
- praisonai/persistence/hooks/__init__.py +18 -0
- praisonai/persistence/hooks/agent_hooks.py +297 -0
- praisonai/persistence/knowledge/__init__.py +26 -0
- praisonai/persistence/knowledge/base.py +144 -0
- praisonai/persistence/knowledge/cassandra.py +232 -0
- praisonai/persistence/knowledge/chroma.py +295 -0
- praisonai/persistence/knowledge/clickhouse.py +242 -0
- praisonai/persistence/knowledge/cosmosdb_vector.py +438 -0
- praisonai/persistence/knowledge/couchbase.py +286 -0
- praisonai/persistence/knowledge/lancedb.py +216 -0
- praisonai/persistence/knowledge/langchain_adapter.py +291 -0
- praisonai/persistence/knowledge/lightrag_adapter.py +212 -0
- praisonai/persistence/knowledge/llamaindex_adapter.py +256 -0
- praisonai/persistence/knowledge/milvus.py +277 -0
- praisonai/persistence/knowledge/mongodb_vector.py +306 -0
- praisonai/persistence/knowledge/pgvector.py +335 -0
- praisonai/persistence/knowledge/pinecone.py +253 -0
- praisonai/persistence/knowledge/qdrant.py +301 -0
- praisonai/persistence/knowledge/redis_vector.py +291 -0
- praisonai/persistence/knowledge/singlestore_vector.py +299 -0
- praisonai/persistence/knowledge/surrealdb_vector.py +309 -0
- praisonai/persistence/knowledge/upstash_vector.py +266 -0
- praisonai/persistence/knowledge/weaviate.py +223 -0
- praisonai/persistence/migrations/__init__.py +10 -0
- praisonai/persistence/migrations/manager.py +251 -0
- praisonai/persistence/orchestrator.py +406 -0
- praisonai/persistence/state/__init__.py +21 -0
- praisonai/persistence/state/async_mongodb.py +200 -0
- praisonai/persistence/state/base.py +107 -0
- praisonai/persistence/state/dynamodb.py +226 -0
- praisonai/persistence/state/firestore.py +175 -0
- praisonai/persistence/state/gcs.py +155 -0
- praisonai/persistence/state/memory.py +245 -0
- praisonai/persistence/state/mongodb.py +158 -0
- praisonai/persistence/state/redis.py +190 -0
- praisonai/persistence/state/upstash.py +144 -0
- praisonai/persistence/tests/__init__.py +3 -0
- praisonai/persistence/tests/test_all_backends.py +633 -0
- praisonai/profiler.py +1214 -0
- praisonai/recipe/__init__.py +134 -0
- praisonai/recipe/bridge.py +278 -0
- praisonai/recipe/core.py +893 -0
- praisonai/recipe/exceptions.py +54 -0
- praisonai/recipe/history.py +402 -0
- praisonai/recipe/models.py +266 -0
- praisonai/recipe/operations.py +440 -0
- praisonai/recipe/policy.py +422 -0
- praisonai/recipe/registry.py +849 -0
- praisonai/recipe/runtime.py +214 -0
- praisonai/recipe/security.py +711 -0
- praisonai/recipe/serve.py +859 -0
- praisonai/recipe/server.py +613 -0
- praisonai/scheduler/__init__.py +45 -0
- praisonai/scheduler/agent_scheduler.py +552 -0
- praisonai/scheduler/base.py +124 -0
- praisonai/scheduler/daemon_manager.py +225 -0
- praisonai/scheduler/state_manager.py +155 -0
- praisonai/scheduler/yaml_loader.py +193 -0
- praisonai/scheduler.py +194 -0
- praisonai/setup/__init__.py +1 -0
- praisonai/setup/build.py +21 -0
- praisonai/setup/post_install.py +23 -0
- praisonai/setup/setup_conda_env.py +25 -0
- praisonai/setup.py +16 -0
- praisonai/templates/__init__.py +116 -0
- praisonai/templates/cache.py +364 -0
- praisonai/templates/dependency_checker.py +358 -0
- praisonai/templates/discovery.py +391 -0
- praisonai/templates/loader.py +564 -0
- praisonai/templates/registry.py +511 -0
- praisonai/templates/resolver.py +206 -0
- praisonai/templates/security.py +327 -0
- praisonai/templates/tool_override.py +498 -0
- praisonai/templates/tools_doctor.py +256 -0
- praisonai/test.py +105 -0
- praisonai/train.py +562 -0
- praisonai/train_vision.py +306 -0
- praisonai/ui/agents.py +824 -0
- praisonai/ui/callbacks.py +57 -0
- praisonai/ui/chainlit_compat.py +246 -0
- praisonai/ui/chat.py +532 -0
- praisonai/ui/code.py +717 -0
- praisonai/ui/colab.py +474 -0
- praisonai/ui/colab_chainlit.py +81 -0
- praisonai/ui/components/aicoder.py +284 -0
- praisonai/ui/context.py +283 -0
- praisonai/ui/database_config.py +56 -0
- praisonai/ui/db.py +294 -0
- praisonai/ui/realtime.py +488 -0
- praisonai/ui/realtimeclient/__init__.py +756 -0
- praisonai/ui/realtimeclient/tools.py +242 -0
- praisonai/ui/sql_alchemy.py +710 -0
- praisonai/upload_vision.py +140 -0
- praisonai/version.py +1 -0
- praisonai-3.0.0.dist-info/METADATA +3493 -0
- praisonai-3.0.0.dist-info/RECORD +393 -0
- praisonai-3.0.0.dist-info/WHEEL +5 -0
- praisonai-3.0.0.dist-info/entry_points.txt +4 -0
- 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
|