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,328 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Observability checks for the Doctor CLI module.
|
|
3
|
+
|
|
4
|
+
Validates observability provider configurations.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
|
|
9
|
+
from ..models import (
|
|
10
|
+
CheckCategory,
|
|
11
|
+
CheckResult,
|
|
12
|
+
CheckStatus,
|
|
13
|
+
CheckSeverity,
|
|
14
|
+
DoctorConfig,
|
|
15
|
+
)
|
|
16
|
+
from ..registry import register_check
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# Observability providers and their required env vars
|
|
20
|
+
OBS_PROVIDERS = {
|
|
21
|
+
"langfuse": {
|
|
22
|
+
"env_vars": ["LANGFUSE_PUBLIC_KEY", "LANGFUSE_SECRET_KEY"],
|
|
23
|
+
"optional_vars": ["LANGFUSE_HOST"],
|
|
24
|
+
"package": "langfuse",
|
|
25
|
+
},
|
|
26
|
+
"langsmith": {
|
|
27
|
+
"env_vars": ["LANGSMITH_API_KEY"],
|
|
28
|
+
"optional_vars": ["LANGSMITH_PROJECT"],
|
|
29
|
+
"package": "langsmith",
|
|
30
|
+
},
|
|
31
|
+
"agentops": {
|
|
32
|
+
"env_vars": ["AGENTOPS_API_KEY"],
|
|
33
|
+
"optional_vars": [],
|
|
34
|
+
"package": "agentops",
|
|
35
|
+
},
|
|
36
|
+
"arize": {
|
|
37
|
+
"env_vars": ["ARIZE_API_KEY"],
|
|
38
|
+
"optional_vars": ["ARIZE_SPACE_KEY"],
|
|
39
|
+
"package": "arize",
|
|
40
|
+
},
|
|
41
|
+
"datadog": {
|
|
42
|
+
"env_vars": ["DATADOG_API_KEY"],
|
|
43
|
+
"optional_vars": ["DD_SITE"],
|
|
44
|
+
"package": "ddtrace",
|
|
45
|
+
},
|
|
46
|
+
"mlflow": {
|
|
47
|
+
"env_vars": [],
|
|
48
|
+
"optional_vars": ["MLFLOW_TRACKING_URI"],
|
|
49
|
+
"package": "mlflow",
|
|
50
|
+
},
|
|
51
|
+
"wandb": {
|
|
52
|
+
"env_vars": ["WANDB_API_KEY"],
|
|
53
|
+
"optional_vars": ["WANDB_PROJECT"],
|
|
54
|
+
"package": "wandb",
|
|
55
|
+
},
|
|
56
|
+
"braintrust": {
|
|
57
|
+
"env_vars": ["BRAINTRUST_API_KEY"],
|
|
58
|
+
"optional_vars": [],
|
|
59
|
+
"package": "braintrust",
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@register_check(
|
|
65
|
+
id="obs_config",
|
|
66
|
+
title="Observability Configuration",
|
|
67
|
+
description="Check observability provider configuration",
|
|
68
|
+
category=CheckCategory.OBSERVABILITY,
|
|
69
|
+
severity=CheckSeverity.INFO,
|
|
70
|
+
)
|
|
71
|
+
def check_obs_config(config: DoctorConfig) -> CheckResult:
|
|
72
|
+
"""Check observability provider configuration."""
|
|
73
|
+
configured = []
|
|
74
|
+
|
|
75
|
+
for provider, info in OBS_PROVIDERS.items():
|
|
76
|
+
env_vars = info["env_vars"]
|
|
77
|
+
if env_vars:
|
|
78
|
+
if all(os.environ.get(var) for var in env_vars):
|
|
79
|
+
configured.append(provider)
|
|
80
|
+
else:
|
|
81
|
+
# Check optional vars for providers without required vars
|
|
82
|
+
if any(os.environ.get(var) for var in info.get("optional_vars", [])):
|
|
83
|
+
configured.append(provider)
|
|
84
|
+
|
|
85
|
+
if configured:
|
|
86
|
+
return CheckResult(
|
|
87
|
+
id="obs_config",
|
|
88
|
+
title="Observability Configuration",
|
|
89
|
+
category=CheckCategory.OBSERVABILITY,
|
|
90
|
+
status=CheckStatus.PASS,
|
|
91
|
+
message=f"Configured provider(s): {', '.join(configured)}",
|
|
92
|
+
metadata={"providers": configured},
|
|
93
|
+
)
|
|
94
|
+
else:
|
|
95
|
+
return CheckResult(
|
|
96
|
+
id="obs_config",
|
|
97
|
+
title="Observability Configuration",
|
|
98
|
+
category=CheckCategory.OBSERVABILITY,
|
|
99
|
+
status=CheckStatus.SKIP,
|
|
100
|
+
message="No observability providers configured (optional)",
|
|
101
|
+
details="Set provider API keys to enable observability",
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@register_check(
|
|
106
|
+
id="obs_langfuse",
|
|
107
|
+
title="Langfuse",
|
|
108
|
+
description="Check Langfuse observability provider",
|
|
109
|
+
category=CheckCategory.OBSERVABILITY,
|
|
110
|
+
severity=CheckSeverity.LOW,
|
|
111
|
+
)
|
|
112
|
+
def check_obs_langfuse(config: DoctorConfig) -> CheckResult:
|
|
113
|
+
"""Check Langfuse observability provider."""
|
|
114
|
+
public_key = os.environ.get("LANGFUSE_PUBLIC_KEY")
|
|
115
|
+
secret_key = os.environ.get("LANGFUSE_SECRET_KEY")
|
|
116
|
+
|
|
117
|
+
if public_key and secret_key:
|
|
118
|
+
try:
|
|
119
|
+
import langfuse
|
|
120
|
+
version = getattr(langfuse, "__version__", "unknown")
|
|
121
|
+
return CheckResult(
|
|
122
|
+
id="obs_langfuse",
|
|
123
|
+
title="Langfuse",
|
|
124
|
+
category=CheckCategory.OBSERVABILITY,
|
|
125
|
+
status=CheckStatus.PASS,
|
|
126
|
+
message=f"Langfuse configured (SDK {version})",
|
|
127
|
+
)
|
|
128
|
+
except ImportError:
|
|
129
|
+
return CheckResult(
|
|
130
|
+
id="obs_langfuse",
|
|
131
|
+
title="Langfuse",
|
|
132
|
+
category=CheckCategory.OBSERVABILITY,
|
|
133
|
+
status=CheckStatus.WARN,
|
|
134
|
+
message="Langfuse keys set but SDK not installed",
|
|
135
|
+
remediation="Install with: pip install langfuse",
|
|
136
|
+
)
|
|
137
|
+
else:
|
|
138
|
+
return CheckResult(
|
|
139
|
+
id="obs_langfuse",
|
|
140
|
+
title="Langfuse",
|
|
141
|
+
category=CheckCategory.OBSERVABILITY,
|
|
142
|
+
status=CheckStatus.SKIP,
|
|
143
|
+
message="Langfuse not configured (optional)",
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@register_check(
|
|
148
|
+
id="obs_langsmith",
|
|
149
|
+
title="LangSmith",
|
|
150
|
+
description="Check LangSmith observability provider",
|
|
151
|
+
category=CheckCategory.OBSERVABILITY,
|
|
152
|
+
severity=CheckSeverity.LOW,
|
|
153
|
+
)
|
|
154
|
+
def check_obs_langsmith(config: DoctorConfig) -> CheckResult:
|
|
155
|
+
"""Check LangSmith observability provider."""
|
|
156
|
+
api_key = os.environ.get("LANGSMITH_API_KEY")
|
|
157
|
+
|
|
158
|
+
if api_key:
|
|
159
|
+
try:
|
|
160
|
+
import langsmith
|
|
161
|
+
version = getattr(langsmith, "__version__", "unknown")
|
|
162
|
+
return CheckResult(
|
|
163
|
+
id="obs_langsmith",
|
|
164
|
+
title="LangSmith",
|
|
165
|
+
category=CheckCategory.OBSERVABILITY,
|
|
166
|
+
status=CheckStatus.PASS,
|
|
167
|
+
message=f"LangSmith configured (SDK {version})",
|
|
168
|
+
)
|
|
169
|
+
except ImportError:
|
|
170
|
+
return CheckResult(
|
|
171
|
+
id="obs_langsmith",
|
|
172
|
+
title="LangSmith",
|
|
173
|
+
category=CheckCategory.OBSERVABILITY,
|
|
174
|
+
status=CheckStatus.WARN,
|
|
175
|
+
message="LangSmith key set but SDK not installed",
|
|
176
|
+
remediation="Install with: pip install langsmith",
|
|
177
|
+
)
|
|
178
|
+
else:
|
|
179
|
+
return CheckResult(
|
|
180
|
+
id="obs_langsmith",
|
|
181
|
+
title="LangSmith",
|
|
182
|
+
category=CheckCategory.OBSERVABILITY,
|
|
183
|
+
status=CheckStatus.SKIP,
|
|
184
|
+
message="LangSmith not configured (optional)",
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
@register_check(
|
|
189
|
+
id="obs_agentops",
|
|
190
|
+
title="AgentOps",
|
|
191
|
+
description="Check AgentOps observability provider",
|
|
192
|
+
category=CheckCategory.OBSERVABILITY,
|
|
193
|
+
severity=CheckSeverity.LOW,
|
|
194
|
+
)
|
|
195
|
+
def check_obs_agentops(config: DoctorConfig) -> CheckResult:
|
|
196
|
+
"""Check AgentOps observability provider."""
|
|
197
|
+
api_key = os.environ.get("AGENTOPS_API_KEY")
|
|
198
|
+
|
|
199
|
+
if api_key:
|
|
200
|
+
try:
|
|
201
|
+
import agentops
|
|
202
|
+
version = getattr(agentops, "__version__", "unknown")
|
|
203
|
+
return CheckResult(
|
|
204
|
+
id="obs_agentops",
|
|
205
|
+
title="AgentOps",
|
|
206
|
+
category=CheckCategory.OBSERVABILITY,
|
|
207
|
+
status=CheckStatus.PASS,
|
|
208
|
+
message=f"AgentOps configured (SDK {version})",
|
|
209
|
+
)
|
|
210
|
+
except ImportError:
|
|
211
|
+
return CheckResult(
|
|
212
|
+
id="obs_agentops",
|
|
213
|
+
title="AgentOps",
|
|
214
|
+
category=CheckCategory.OBSERVABILITY,
|
|
215
|
+
status=CheckStatus.WARN,
|
|
216
|
+
message="AgentOps key set but SDK not installed",
|
|
217
|
+
remediation="Install with: pip install agentops",
|
|
218
|
+
)
|
|
219
|
+
else:
|
|
220
|
+
return CheckResult(
|
|
221
|
+
id="obs_agentops",
|
|
222
|
+
title="AgentOps",
|
|
223
|
+
category=CheckCategory.OBSERVABILITY,
|
|
224
|
+
status=CheckStatus.SKIP,
|
|
225
|
+
message="AgentOps not configured (optional)",
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
@register_check(
|
|
230
|
+
id="obs_praisonai_telemetry",
|
|
231
|
+
title="PraisonAI Telemetry",
|
|
232
|
+
description="Check PraisonAI built-in telemetry",
|
|
233
|
+
category=CheckCategory.OBSERVABILITY,
|
|
234
|
+
severity=CheckSeverity.INFO,
|
|
235
|
+
)
|
|
236
|
+
def check_obs_praisonai_telemetry(config: DoctorConfig) -> CheckResult:
|
|
237
|
+
"""Check PraisonAI built-in telemetry."""
|
|
238
|
+
telemetry_enabled = os.environ.get("PRAISONAI_TELEMETRY_ENABLED", "").lower() in ("true", "1", "yes")
|
|
239
|
+
|
|
240
|
+
try:
|
|
241
|
+
from praisonaiagents.telemetry import get_telemetry
|
|
242
|
+
|
|
243
|
+
if telemetry_enabled:
|
|
244
|
+
return CheckResult(
|
|
245
|
+
id="obs_praisonai_telemetry",
|
|
246
|
+
title="PraisonAI Telemetry",
|
|
247
|
+
category=CheckCategory.OBSERVABILITY,
|
|
248
|
+
status=CheckStatus.PASS,
|
|
249
|
+
message="PraisonAI telemetry enabled",
|
|
250
|
+
)
|
|
251
|
+
else:
|
|
252
|
+
return CheckResult(
|
|
253
|
+
id="obs_praisonai_telemetry",
|
|
254
|
+
title="PraisonAI Telemetry",
|
|
255
|
+
category=CheckCategory.OBSERVABILITY,
|
|
256
|
+
status=CheckStatus.SKIP,
|
|
257
|
+
message="PraisonAI telemetry available but not enabled",
|
|
258
|
+
details="Set PRAISONAI_TELEMETRY_ENABLED=true to enable",
|
|
259
|
+
)
|
|
260
|
+
except ImportError:
|
|
261
|
+
return CheckResult(
|
|
262
|
+
id="obs_praisonai_telemetry",
|
|
263
|
+
title="PraisonAI Telemetry",
|
|
264
|
+
category=CheckCategory.OBSERVABILITY,
|
|
265
|
+
status=CheckStatus.SKIP,
|
|
266
|
+
message="PraisonAI telemetry module not available",
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
@register_check(
|
|
271
|
+
id="obs_connectivity",
|
|
272
|
+
title="Observability Connectivity",
|
|
273
|
+
description="Test connectivity to observability providers",
|
|
274
|
+
category=CheckCategory.OBSERVABILITY,
|
|
275
|
+
severity=CheckSeverity.LOW,
|
|
276
|
+
requires_deep=True,
|
|
277
|
+
)
|
|
278
|
+
def check_obs_connectivity(config: DoctorConfig) -> CheckResult:
|
|
279
|
+
"""Test connectivity to observability providers (deep mode)."""
|
|
280
|
+
# Only test if a specific provider is requested or if we have configured providers
|
|
281
|
+
provider = config.provider
|
|
282
|
+
|
|
283
|
+
if provider == "langfuse":
|
|
284
|
+
public_key = os.environ.get("LANGFUSE_PUBLIC_KEY")
|
|
285
|
+
secret_key = os.environ.get("LANGFUSE_SECRET_KEY")
|
|
286
|
+
|
|
287
|
+
if not (public_key and secret_key):
|
|
288
|
+
return CheckResult(
|
|
289
|
+
id="obs_connectivity",
|
|
290
|
+
title="Observability Connectivity",
|
|
291
|
+
category=CheckCategory.OBSERVABILITY,
|
|
292
|
+
status=CheckStatus.SKIP,
|
|
293
|
+
message="Langfuse not configured",
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
try:
|
|
297
|
+
from langfuse import Langfuse
|
|
298
|
+
client = Langfuse(
|
|
299
|
+
public_key=public_key,
|
|
300
|
+
secret_key=secret_key,
|
|
301
|
+
)
|
|
302
|
+
# Try to authenticate
|
|
303
|
+
client.auth_check()
|
|
304
|
+
return CheckResult(
|
|
305
|
+
id="obs_connectivity",
|
|
306
|
+
title="Observability Connectivity",
|
|
307
|
+
category=CheckCategory.OBSERVABILITY,
|
|
308
|
+
status=CheckStatus.PASS,
|
|
309
|
+
message="Langfuse connectivity verified",
|
|
310
|
+
)
|
|
311
|
+
except Exception as e:
|
|
312
|
+
return CheckResult(
|
|
313
|
+
id="obs_connectivity",
|
|
314
|
+
title="Observability Connectivity",
|
|
315
|
+
category=CheckCategory.OBSERVABILITY,
|
|
316
|
+
status=CheckStatus.FAIL,
|
|
317
|
+
message=f"Langfuse connection failed: {type(e).__name__}",
|
|
318
|
+
details=str(e)[:200],
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
# Default: skip if no specific provider requested
|
|
322
|
+
return CheckResult(
|
|
323
|
+
id="obs_connectivity",
|
|
324
|
+
title="Observability Connectivity",
|
|
325
|
+
category=CheckCategory.OBSERVABILITY,
|
|
326
|
+
status=CheckStatus.SKIP,
|
|
327
|
+
message="Use --provider to test specific provider connectivity",
|
|
328
|
+
)
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Performance checks for the Doctor CLI module.
|
|
3
|
+
|
|
4
|
+
Measures import times and identifies slow imports.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import sys
|
|
8
|
+
import time
|
|
9
|
+
|
|
10
|
+
from ..models import (
|
|
11
|
+
CheckCategory,
|
|
12
|
+
CheckResult,
|
|
13
|
+
CheckStatus,
|
|
14
|
+
CheckSeverity,
|
|
15
|
+
DoctorConfig,
|
|
16
|
+
)
|
|
17
|
+
from ..registry import register_check
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _measure_import_time(module_name: str) -> tuple:
|
|
21
|
+
"""Measure import time for a module."""
|
|
22
|
+
# Remove from cache if present
|
|
23
|
+
modules_before = set(sys.modules.keys())
|
|
24
|
+
|
|
25
|
+
start = time.perf_counter()
|
|
26
|
+
try:
|
|
27
|
+
__import__(module_name)
|
|
28
|
+
elapsed = (time.perf_counter() - start) * 1000 # ms
|
|
29
|
+
return True, elapsed, None
|
|
30
|
+
except ImportError as e:
|
|
31
|
+
elapsed = (time.perf_counter() - start) * 1000
|
|
32
|
+
return False, elapsed, str(e)
|
|
33
|
+
finally:
|
|
34
|
+
# Clean up imported modules (optional, for accurate re-measurement)
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@register_check(
|
|
39
|
+
id="performance_praisonai_import",
|
|
40
|
+
title="PraisonAI Import Time",
|
|
41
|
+
description="Measure praisonai package import time",
|
|
42
|
+
category=CheckCategory.PERFORMANCE,
|
|
43
|
+
severity=CheckSeverity.INFO,
|
|
44
|
+
)
|
|
45
|
+
def check_performance_praisonai_import(config: DoctorConfig) -> CheckResult:
|
|
46
|
+
"""Measure praisonai package import time."""
|
|
47
|
+
budget_ms = config.budget_ms or 2000 # 2 second default budget
|
|
48
|
+
|
|
49
|
+
# praisonai is already imported, measure a fresh import of a submodule
|
|
50
|
+
start = time.perf_counter()
|
|
51
|
+
try:
|
|
52
|
+
# Import version module (lightweight)
|
|
53
|
+
from praisonai import version
|
|
54
|
+
elapsed = (time.perf_counter() - start) * 1000
|
|
55
|
+
|
|
56
|
+
if elapsed > budget_ms:
|
|
57
|
+
return CheckResult(
|
|
58
|
+
id="performance_praisonai_import",
|
|
59
|
+
title="PraisonAI Import Time",
|
|
60
|
+
category=CheckCategory.PERFORMANCE,
|
|
61
|
+
status=CheckStatus.WARN,
|
|
62
|
+
message=f"Import time {elapsed:.0f}ms exceeds budget {budget_ms}ms",
|
|
63
|
+
remediation="Check for slow dependencies or disk I/O issues",
|
|
64
|
+
)
|
|
65
|
+
else:
|
|
66
|
+
return CheckResult(
|
|
67
|
+
id="performance_praisonai_import",
|
|
68
|
+
title="PraisonAI Import Time",
|
|
69
|
+
category=CheckCategory.PERFORMANCE,
|
|
70
|
+
status=CheckStatus.PASS,
|
|
71
|
+
message=f"Import time: {elapsed:.0f}ms (budget: {budget_ms}ms)",
|
|
72
|
+
metadata={"import_time_ms": elapsed, "budget_ms": budget_ms},
|
|
73
|
+
)
|
|
74
|
+
except ImportError as e:
|
|
75
|
+
return CheckResult(
|
|
76
|
+
id="performance_praisonai_import",
|
|
77
|
+
title="PraisonAI Import Time",
|
|
78
|
+
category=CheckCategory.PERFORMANCE,
|
|
79
|
+
status=CheckStatus.FAIL,
|
|
80
|
+
message=f"Import failed: {e}",
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@register_check(
|
|
85
|
+
id="performance_praisonaiagents_import",
|
|
86
|
+
title="PraisonAI Agents Import Time",
|
|
87
|
+
description="Measure praisonaiagents package import time",
|
|
88
|
+
category=CheckCategory.PERFORMANCE,
|
|
89
|
+
severity=CheckSeverity.INFO,
|
|
90
|
+
)
|
|
91
|
+
def check_performance_praisonaiagents_import(config: DoctorConfig) -> CheckResult:
|
|
92
|
+
"""Measure praisonaiagents package import time."""
|
|
93
|
+
budget_ms = config.budget_ms or 3000 # 3 second default budget
|
|
94
|
+
|
|
95
|
+
start = time.perf_counter()
|
|
96
|
+
try:
|
|
97
|
+
import praisonaiagents
|
|
98
|
+
elapsed = (time.perf_counter() - start) * 1000
|
|
99
|
+
|
|
100
|
+
if elapsed > budget_ms:
|
|
101
|
+
return CheckResult(
|
|
102
|
+
id="performance_praisonaiagents_import",
|
|
103
|
+
title="PraisonAI Agents Import Time",
|
|
104
|
+
category=CheckCategory.PERFORMANCE,
|
|
105
|
+
status=CheckStatus.WARN,
|
|
106
|
+
message=f"Import time {elapsed:.0f}ms exceeds budget {budget_ms}ms",
|
|
107
|
+
remediation="Check for slow dependencies",
|
|
108
|
+
)
|
|
109
|
+
else:
|
|
110
|
+
return CheckResult(
|
|
111
|
+
id="performance_praisonaiagents_import",
|
|
112
|
+
title="PraisonAI Agents Import Time",
|
|
113
|
+
category=CheckCategory.PERFORMANCE,
|
|
114
|
+
status=CheckStatus.PASS,
|
|
115
|
+
message=f"Import time: {elapsed:.0f}ms (budget: {budget_ms}ms)",
|
|
116
|
+
metadata={"import_time_ms": elapsed, "budget_ms": budget_ms},
|
|
117
|
+
)
|
|
118
|
+
except ImportError as e:
|
|
119
|
+
return CheckResult(
|
|
120
|
+
id="performance_praisonaiagents_import",
|
|
121
|
+
title="PraisonAI Agents Import Time",
|
|
122
|
+
category=CheckCategory.PERFORMANCE,
|
|
123
|
+
status=CheckStatus.FAIL,
|
|
124
|
+
message=f"Import failed: {e}",
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
@register_check(
|
|
129
|
+
id="performance_slow_imports",
|
|
130
|
+
title="Slow Import Detection",
|
|
131
|
+
description="Detect slow-loading optional dependencies",
|
|
132
|
+
category=CheckCategory.PERFORMANCE,
|
|
133
|
+
severity=CheckSeverity.INFO,
|
|
134
|
+
requires_deep=True,
|
|
135
|
+
)
|
|
136
|
+
def check_performance_slow_imports(config: DoctorConfig) -> CheckResult:
|
|
137
|
+
"""Detect slow-loading optional dependencies."""
|
|
138
|
+
modules_to_check = [
|
|
139
|
+
"litellm",
|
|
140
|
+
"chromadb",
|
|
141
|
+
"langchain",
|
|
142
|
+
"torch",
|
|
143
|
+
"transformers",
|
|
144
|
+
"pandas",
|
|
145
|
+
"numpy",
|
|
146
|
+
]
|
|
147
|
+
|
|
148
|
+
top_n = config.top_n or 5
|
|
149
|
+
budget_ms = config.budget_ms or 1000
|
|
150
|
+
|
|
151
|
+
import_times = []
|
|
152
|
+
|
|
153
|
+
for module in modules_to_check:
|
|
154
|
+
if module in sys.modules:
|
|
155
|
+
# Already imported, skip
|
|
156
|
+
continue
|
|
157
|
+
|
|
158
|
+
success, elapsed, error = _measure_import_time(module)
|
|
159
|
+
if success:
|
|
160
|
+
import_times.append((module, elapsed))
|
|
161
|
+
|
|
162
|
+
# Sort by time, descending
|
|
163
|
+
import_times.sort(key=lambda x: x[1], reverse=True)
|
|
164
|
+
|
|
165
|
+
slow_imports = [(m, t) for m, t in import_times if t > budget_ms]
|
|
166
|
+
top_imports = import_times[:top_n]
|
|
167
|
+
|
|
168
|
+
if slow_imports:
|
|
169
|
+
slow_str = ", ".join(f"{m}({t:.0f}ms)" for m, t in slow_imports[:3])
|
|
170
|
+
return CheckResult(
|
|
171
|
+
id="performance_slow_imports",
|
|
172
|
+
title="Slow Import Detection",
|
|
173
|
+
category=CheckCategory.PERFORMANCE,
|
|
174
|
+
status=CheckStatus.WARN,
|
|
175
|
+
message=f"{len(slow_imports)} slow import(s) detected",
|
|
176
|
+
details=f"Slow: {slow_str}",
|
|
177
|
+
metadata={"slow_imports": slow_imports, "top_imports": top_imports},
|
|
178
|
+
)
|
|
179
|
+
elif top_imports:
|
|
180
|
+
top_str = ", ".join(f"{m}({t:.0f}ms)" for m, t in top_imports[:3])
|
|
181
|
+
return CheckResult(
|
|
182
|
+
id="performance_slow_imports",
|
|
183
|
+
title="Slow Import Detection",
|
|
184
|
+
category=CheckCategory.PERFORMANCE,
|
|
185
|
+
status=CheckStatus.PASS,
|
|
186
|
+
message=f"No slow imports (top: {top_str})",
|
|
187
|
+
metadata={"top_imports": top_imports},
|
|
188
|
+
)
|
|
189
|
+
else:
|
|
190
|
+
return CheckResult(
|
|
191
|
+
id="performance_slow_imports",
|
|
192
|
+
title="Slow Import Detection",
|
|
193
|
+
category=CheckCategory.PERFORMANCE,
|
|
194
|
+
status=CheckStatus.SKIP,
|
|
195
|
+
message="No optional modules to measure",
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
@register_check(
|
|
200
|
+
id="performance_loaded_modules",
|
|
201
|
+
title="Loaded Modules Count",
|
|
202
|
+
description="Count currently loaded Python modules",
|
|
203
|
+
category=CheckCategory.PERFORMANCE,
|
|
204
|
+
severity=CheckSeverity.INFO,
|
|
205
|
+
)
|
|
206
|
+
def check_performance_loaded_modules(config: DoctorConfig) -> CheckResult:
|
|
207
|
+
"""Count currently loaded Python modules."""
|
|
208
|
+
module_count = len(sys.modules)
|
|
209
|
+
|
|
210
|
+
# Categorize modules
|
|
211
|
+
stdlib_count = 0
|
|
212
|
+
third_party_count = 0
|
|
213
|
+
praison_count = 0
|
|
214
|
+
|
|
215
|
+
for name in sys.modules:
|
|
216
|
+
if name.startswith("praisonai"):
|
|
217
|
+
praison_count += 1
|
|
218
|
+
elif "site-packages" in str(getattr(sys.modules[name], "__file__", "")):
|
|
219
|
+
third_party_count += 1
|
|
220
|
+
else:
|
|
221
|
+
stdlib_count += 1
|
|
222
|
+
|
|
223
|
+
return CheckResult(
|
|
224
|
+
id="performance_loaded_modules",
|
|
225
|
+
title="Loaded Modules Count",
|
|
226
|
+
category=CheckCategory.PERFORMANCE,
|
|
227
|
+
status=CheckStatus.PASS,
|
|
228
|
+
message=f"{module_count} modules loaded (praison: {praison_count})",
|
|
229
|
+
metadata={
|
|
230
|
+
"total": module_count,
|
|
231
|
+
"praison": praison_count,
|
|
232
|
+
"third_party": third_party_count,
|
|
233
|
+
"stdlib": stdlib_count,
|
|
234
|
+
},
|
|
235
|
+
)
|