praisonai-code 0.0.1__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_code/__init__.py +17 -0
- praisonai_code/cli/__init__.py +12 -0
- praisonai_code/cli/_forward_shim.py +10 -0
- praisonai_code/cli/_paths.py +88 -0
- praisonai_code/cli/_warnings.py +58 -0
- praisonai_code/cli/app.py +757 -0
- praisonai_code/cli/approval_backend.py +272 -0
- praisonai_code/cli/branding.py +94 -0
- praisonai_code/cli/commands/__init__.py +114 -0
- praisonai_code/cli/commands/acp.py +80 -0
- praisonai_code/cli/commands/agent.py +116 -0
- praisonai_code/cli/commands/agents.py +80 -0
- praisonai_code/cli/commands/app.py +139 -0
- praisonai_code/cli/commands/attach.py +95 -0
- praisonai_code/cli/commands/audit.py +102 -0
- praisonai_code/cli/commands/auth.py +508 -0
- praisonai_code/cli/commands/batch.py +848 -0
- praisonai_code/cli/commands/benchmark.py +286 -0
- praisonai_code/cli/commands/browser.py +299 -0
- praisonai_code/cli/commands/call.py +45 -0
- praisonai_code/cli/commands/chat.py +332 -0
- praisonai_code/cli/commands/checkpoint.py +170 -0
- praisonai_code/cli/commands/code.py +276 -0
- praisonai_code/cli/commands/command.py +114 -0
- praisonai_code/cli/commands/commit.py +47 -0
- praisonai_code/cli/commands/completion.py +333 -0
- praisonai_code/cli/commands/config.py +681 -0
- praisonai_code/cli/commands/context.py +414 -0
- praisonai_code/cli/commands/daemon.py +203 -0
- praisonai_code/cli/commands/debug.py +142 -0
- praisonai_code/cli/commands/deploy.py +71 -0
- praisonai_code/cli/commands/diag.py +55 -0
- praisonai_code/cli/commands/docs.py +1575 -0
- praisonai_code/cli/commands/doctor.py +332 -0
- praisonai_code/cli/commands/endpoints.py +51 -0
- praisonai_code/cli/commands/environment.py +179 -0
- praisonai_code/cli/commands/eval.py +131 -0
- praisonai_code/cli/commands/examples.py +953 -0
- praisonai_code/cli/commands/flow.py +436 -0
- praisonai_code/cli/commands/github.py +752 -0
- praisonai_code/cli/commands/hooks.py +74 -0
- praisonai_code/cli/commands/init.py +174 -0
- praisonai_code/cli/commands/knowledge.py +440 -0
- praisonai_code/cli/commands/langextract.py +120 -0
- praisonai_code/cli/commands/langfuse.py +984 -0
- praisonai_code/cli/commands/loop.py +211 -0
- praisonai_code/cli/commands/lsp.py +112 -0
- praisonai_code/cli/commands/managed.py +659 -0
- praisonai_code/cli/commands/mcp.py +763 -0
- praisonai_code/cli/commands/memory.py +298 -0
- praisonai_code/cli/commands/models.py +264 -0
- praisonai_code/cli/commands/n8n.py +326 -0
- praisonai_code/cli/commands/obs.py +19 -0
- praisonai_code/cli/commands/package.py +76 -0
- praisonai_code/cli/commands/paths.py +106 -0
- praisonai_code/cli/commands/permissions.py +272 -0
- praisonai_code/cli/commands/plugins.py +609 -0
- praisonai_code/cli/commands/port.py +530 -0
- praisonai_code/cli/commands/profile.py +466 -0
- praisonai_code/cli/commands/publish.py +193 -0
- praisonai_code/cli/commands/rag.py +913 -0
- praisonai_code/cli/commands/realtime.py +52 -0
- praisonai_code/cli/commands/recipe.py +684 -0
- praisonai_code/cli/commands/registry.py +59 -0
- praisonai_code/cli/commands/replay.py +830 -0
- praisonai_code/cli/commands/research.py +49 -0
- praisonai_code/cli/commands/retrieval.py +377 -0
- praisonai_code/cli/commands/rules.py +71 -0
- praisonai_code/cli/commands/run.py +1573 -0
- praisonai_code/cli/commands/sandbox.py +371 -0
- praisonai_code/cli/commands/schedule.py +529 -0
- praisonai_code/cli/commands/serve.py +690 -0
- praisonai_code/cli/commands/session.py +450 -0
- praisonai_code/cli/commands/setup.py +174 -0
- praisonai_code/cli/commands/skills.py +545 -0
- praisonai_code/cli/commands/standardise.py +711 -0
- praisonai_code/cli/commands/templates.py +54 -0
- praisonai_code/cli/commands/test.py +558 -0
- praisonai_code/cli/commands/todo.py +74 -0
- praisonai_code/cli/commands/tools.py +205 -0
- praisonai_code/cli/commands/traces.py +145 -0
- praisonai_code/cli/commands/tracker.py +852 -0
- praisonai_code/cli/commands/train.py +613 -0
- praisonai_code/cli/commands/ui.py +172 -0
- praisonai_code/cli/commands/up.py +354 -0
- praisonai_code/cli/commands/validate.py +291 -0
- praisonai_code/cli/commands/version.py +101 -0
- praisonai_code/cli/commands/workflow.py +97 -0
- praisonai_code/cli/config_loader.py +437 -0
- praisonai_code/cli/configuration/__init__.py +27 -0
- praisonai_code/cli/configuration/config.schema.json +57 -0
- praisonai_code/cli/configuration/credentials.py +446 -0
- praisonai_code/cli/configuration/loader.py +364 -0
- praisonai_code/cli/configuration/model_resolver.py +161 -0
- praisonai_code/cli/configuration/oauth.py +389 -0
- praisonai_code/cli/configuration/paths.py +224 -0
- praisonai_code/cli/configuration/resolver.py +687 -0
- praisonai_code/cli/configuration/schema.py +317 -0
- praisonai_code/cli/execution/__init__.py +99 -0
- praisonai_code/cli/execution/core.py +208 -0
- praisonai_code/cli/execution/profiler.py +898 -0
- praisonai_code/cli/execution/request.py +85 -0
- praisonai_code/cli/execution/result.py +74 -0
- praisonai_code/cli/fallback_schema.py +416 -0
- praisonai_code/cli/features/__init__.py +278 -0
- praisonai_code/cli/features/_endpoint_registry.py +64 -0
- praisonai_code/cli/features/_search_registry.py +43 -0
- praisonai_code/cli/features/acp.py +236 -0
- praisonai_code/cli/features/action_orchestrator.py +576 -0
- praisonai_code/cli/features/agent_scheduler.py +773 -0
- praisonai_code/cli/features/agent_tools.py +603 -0
- praisonai_code/cli/features/agents.py +397 -0
- praisonai_code/cli/features/at_mentions.py +471 -0
- praisonai_code/cli/features/audit_cli.py +270 -0
- praisonai_code/cli/features/auto_memory.py +182 -0
- praisonai_code/cli/features/auto_mode.py +552 -0
- praisonai_code/cli/features/autonomy_mode.py +546 -0
- praisonai_code/cli/features/background.py +356 -0
- praisonai_code/cli/features/base.py +168 -0
- praisonai_code/cli/features/benchmark.py +1462 -0
- praisonai_code/cli/features/capabilities.py +1326 -0
- praisonai_code/cli/features/checkpoints.py +345 -0
- praisonai_code/cli/features/cli_profiler.py +335 -0
- praisonai_code/cli/features/code_intelligence.py +666 -0
- praisonai_code/cli/features/compaction.py +294 -0
- praisonai_code/cli/features/compare.py +534 -0
- praisonai_code/cli/features/config_hierarchy.py +366 -0
- praisonai_code/cli/features/context_manager.py +597 -0
- praisonai_code/cli/features/cost_tracker.py +514 -0
- praisonai_code/cli/features/csv_test_runner.py +736 -0
- praisonai_code/cli/features/custom_definitions.py +790 -0
- praisonai_code/cli/features/debug.py +810 -0
- praisonai_code/cli/features/deploy.py +605 -0
- praisonai_code/cli/features/diag.py +289 -0
- praisonai_code/cli/features/display_jsonl.py +173 -0
- praisonai_code/cli/features/doctor/__init__.py +63 -0
- praisonai_code/cli/features/doctor/checks/__init__.py +29 -0
- praisonai_code/cli/features/doctor/checks/acp_checks.py +220 -0
- praisonai_code/cli/features/doctor/checks/bot_checks.py +340 -0
- praisonai_code/cli/features/doctor/checks/config_checks.py +373 -0
- praisonai_code/cli/features/doctor/checks/db_checks.py +366 -0
- praisonai_code/cli/features/doctor/checks/env_checks.py +637 -0
- praisonai_code/cli/features/doctor/checks/gateway_checks.py +387 -0
- praisonai_code/cli/features/doctor/checks/lsp_checks.py +231 -0
- praisonai_code/cli/features/doctor/checks/mcp_checks.py +367 -0
- praisonai_code/cli/features/doctor/checks/memory_checks.py +268 -0
- praisonai_code/cli/features/doctor/checks/network_checks.py +251 -0
- praisonai_code/cli/features/doctor/checks/obs_checks.py +328 -0
- praisonai_code/cli/features/doctor/checks/packaging_checks.py +422 -0
- praisonai_code/cli/features/doctor/checks/performance_checks.py +235 -0
- praisonai_code/cli/features/doctor/checks/permissions_checks.py +259 -0
- praisonai_code/cli/features/doctor/checks/runtime_checks.py +650 -0
- praisonai_code/cli/features/doctor/checks/runtime_migration_checks.py +220 -0
- praisonai_code/cli/features/doctor/checks/selftest_checks.py +322 -0
- praisonai_code/cli/features/doctor/checks/serve_checks.py +426 -0
- praisonai_code/cli/features/doctor/checks/skills_checks.py +327 -0
- praisonai_code/cli/features/doctor/checks/tools_checks.py +371 -0
- praisonai_code/cli/features/doctor/engine.py +266 -0
- praisonai_code/cli/features/doctor/formatters.py +377 -0
- praisonai_code/cli/features/doctor/handler.py +564 -0
- praisonai_code/cli/features/doctor/models.py +276 -0
- praisonai_code/cli/features/doctor/registry.py +239 -0
- praisonai_code/cli/features/endpoints.py +1016 -0
- praisonai_code/cli/features/eval.py +559 -0
- praisonai_code/cli/features/examples.py +707 -0
- praisonai_code/cli/features/external_agents.py +231 -0
- praisonai_code/cli/features/fast_context.py +410 -0
- praisonai_code/cli/features/file_history.py +320 -0
- praisonai_code/cli/features/flow_display.py +566 -0
- praisonai_code/cli/features/git_attribution.py +159 -0
- praisonai_code/cli/features/git_integration.py +651 -0
- praisonai_code/cli/features/guardrail.py +171 -0
- praisonai_code/cli/features/handoff.py +252 -0
- praisonai_code/cli/features/hooks.py +583 -0
- praisonai_code/cli/features/hybrid_workflow.py +391 -0
- praisonai_code/cli/features/image.py +384 -0
- praisonai_code/cli/features/interactive_core_headless.py +450 -0
- praisonai_code/cli/features/interactive_runtime.py +600 -0
- praisonai_code/cli/features/interactive_test_harness.py +537 -0
- praisonai_code/cli/features/interactive_tools.py +428 -0
- praisonai_code/cli/features/interactive_tui.py +603 -0
- praisonai_code/cli/features/job_workflow.py +906 -0
- praisonai_code/cli/features/jobs.py +632 -0
- praisonai_code/cli/features/knowledge.py +531 -0
- praisonai_code/cli/features/knowledge_cli.py +438 -0
- praisonai_code/cli/features/lite.py +244 -0
- praisonai_code/cli/features/logs.py +200 -0
- praisonai_code/cli/features/lsp_cli.py +225 -0
- praisonai_code/cli/features/lsp_diagnostics.py +185 -0
- praisonai_code/cli/features/mcp.py +344 -0
- praisonai_code/cli/features/message_queue.py +587 -0
- praisonai_code/cli/features/metrics.py +210 -0
- praisonai_code/cli/features/migrate.py +1329 -0
- praisonai_code/cli/features/migration_flow.py +463 -0
- praisonai_code/cli/features/migration_spec.py +276 -0
- praisonai_code/cli/features/n8n.py +703 -0
- praisonai_code/cli/features/observability.py +293 -0
- praisonai_code/cli/features/ollama.py +361 -0
- praisonai_code/cli/features/output_modes.py +155 -0
- praisonai_code/cli/features/output_style.py +273 -0
- praisonai_code/cli/features/package.py +631 -0
- praisonai_code/cli/features/performance.py +308 -0
- praisonai_code/cli/features/persistence.py +636 -0
- praisonai_code/cli/features/profiler/__init__.py +81 -0
- praisonai_code/cli/features/profiler/core.py +558 -0
- praisonai_code/cli/features/profiler/optimizations.py +652 -0
- praisonai_code/cli/features/profiler/suite.py +386 -0
- praisonai_code/cli/features/queue/__init__.py +73 -0
- praisonai_code/cli/features/queue/manager.py +435 -0
- praisonai_code/cli/features/queue/models.py +289 -0
- praisonai_code/cli/features/queue/persistence.py +564 -0
- praisonai_code/cli/features/queue/scheduler.py +529 -0
- praisonai_code/cli/features/queue/worker.py +400 -0
- praisonai_code/cli/features/recipe.py +2187 -0
- praisonai_code/cli/features/recipe_creator.py +996 -0
- praisonai_code/cli/features/recipe_optimizer.py +1364 -0
- praisonai_code/cli/features/recipe_prompts.py +226 -0
- praisonai_code/cli/features/registry.py +229 -0
- praisonai_code/cli/features/repo_map.py +860 -0
- praisonai_code/cli/features/router.py +466 -0
- praisonai_code/cli/features/safe_shell.py +427 -0
- praisonai_code/cli/features/sandbox_cli.py +283 -0
- praisonai_code/cli/features/sandbox_executor.py +536 -0
- praisonai_code/cli/features/sdk_knowledge.py +500 -0
- praisonai_code/cli/features/session.py +222 -0
- praisonai_code/cli/features/session_checkpoints.py +208 -0
- praisonai_code/cli/features/setup/__init__.py +9 -0
- praisonai_code/cli/features/setup/handler.py +355 -0
- praisonai_code/cli/features/setup/templates.py +62 -0
- praisonai_code/cli/features/skills.py +940 -0
- praisonai_code/cli/features/slash_commands.py +692 -0
- praisonai_code/cli/features/telemetry.py +179 -0
- praisonai_code/cli/features/templates.py +1390 -0
- praisonai_code/cli/features/thinking.py +343 -0
- praisonai_code/cli/features/todo.py +334 -0
- praisonai_code/cli/features/tools.py +680 -0
- praisonai_code/cli/features/tui/__init__.py +83 -0
- praisonai_code/cli/features/tui/app.py +871 -0
- praisonai_code/cli/features/tui/cli.py +580 -0
- praisonai_code/cli/features/tui/config.py +150 -0
- praisonai_code/cli/features/tui/debug.py +526 -0
- praisonai_code/cli/features/tui/events.py +99 -0
- praisonai_code/cli/features/tui/mock_provider.py +328 -0
- praisonai_code/cli/features/tui/orchestrator.py +652 -0
- praisonai_code/cli/features/tui/screens/__init__.py +50 -0
- praisonai_code/cli/features/tui/screens/help.py +157 -0
- praisonai_code/cli/features/tui/screens/main.py +568 -0
- praisonai_code/cli/features/tui/screens/queue.py +174 -0
- praisonai_code/cli/features/tui/screens/session.py +124 -0
- praisonai_code/cli/features/tui/screens/settings.py +148 -0
- praisonai_code/cli/features/tui/session_store.py +198 -0
- praisonai_code/cli/features/tui/widgets/__init__.py +56 -0
- praisonai_code/cli/features/tui/widgets/chat.py +263 -0
- praisonai_code/cli/features/tui/widgets/command_popup.py +258 -0
- praisonai_code/cli/features/tui/widgets/composer.py +292 -0
- praisonai_code/cli/features/tui/widgets/file_popup.py +207 -0
- praisonai_code/cli/features/tui/widgets/queue_panel.py +223 -0
- praisonai_code/cli/features/tui/widgets/status.py +181 -0
- praisonai_code/cli/features/tui/widgets/tool_panel.py +307 -0
- praisonai_code/cli/features/wizard.py +289 -0
- praisonai_code/cli/features/workflow.py +802 -0
- praisonai_code/cli/features/yaml_utils.py +321 -0
- praisonai_code/cli/interactive/__init__.py +48 -0
- praisonai_code/cli/interactive/async_tui.py +1218 -0
- praisonai_code/cli/interactive/config.py +139 -0
- praisonai_code/cli/interactive/core.py +618 -0
- praisonai_code/cli/interactive/events.py +131 -0
- praisonai_code/cli/interactive/frontends/__init__.py +31 -0
- praisonai_code/cli/interactive/frontends/rich_frontend.py +462 -0
- praisonai_code/cli/interactive/frontends/textual_frontend.py +157 -0
- praisonai_code/cli/interactive/praison_io.py +502 -0
- praisonai_code/cli/interactive/repl.py +297 -0
- praisonai_code/cli/interactive/split_tui.py +456 -0
- praisonai_code/cli/interactive/tui_app.py +457 -0
- praisonai_code/cli/langfuse_client.py +360 -0
- praisonai_code/cli/main.py +7421 -0
- praisonai_code/cli/output/__init__.py +25 -0
- praisonai_code/cli/output/console.py +456 -0
- praisonai_code/cli/output/event_bridge.py +191 -0
- praisonai_code/cli/schedule_cli.py +54 -0
- praisonai_code/cli/schema_provider.py +23 -0
- praisonai_code/cli/session/__init__.py +16 -0
- praisonai_code/cli/session/resume.py +148 -0
- praisonai_code/cli/session/unified.py +548 -0
- praisonai_code/cli/state/__init__.py +31 -0
- praisonai_code/cli/state/identifiers.py +161 -0
- praisonai_code/cli/state/project_sessions.py +383 -0
- praisonai_code/cli/state/sessions.py +390 -0
- praisonai_code/cli/ui/__init__.py +160 -0
- praisonai_code/cli/ui/config.py +46 -0
- praisonai_code/cli/ui/events.py +61 -0
- praisonai_code/cli/ui/mg_backend.py +342 -0
- praisonai_code/cli/ui/plain.py +133 -0
- praisonai_code/cli/ui/rich_backend.py +162 -0
- praisonai_code/cli/unified_schema.py +655 -0
- praisonai_code/cli/utils/env_utils.py +126 -0
- praisonai_code/cli/utils/project.py +131 -0
- praisonai_code/cli_backends/__init__.py +73 -0
- praisonai_code/cli_backends/claude.py +373 -0
- praisonai_code/cli_backends/registry.py +113 -0
- praisonai_code/runtime/__init__.py +36 -0
- praisonai_code/runtime/__main__.py +81 -0
- praisonai_code/runtime/client.py +131 -0
- praisonai_code/runtime/descriptor.py +209 -0
- praisonai_code/runtime/server.py +356 -0
- praisonai_code-0.0.1.dist-info/METADATA +80 -0
- praisonai_code-0.0.1.dist-info/RECORD +309 -0
- praisonai_code-0.0.1.dist-info/WHEEL +5 -0
- praisonai_code-0.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,367 @@
|
|
|
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
|
+
# Use canonical MCP paths from praisonaiagents.paths
|
|
24
|
+
try:
|
|
25
|
+
from praisonaiagents.paths import get_mcp_dir, get_project_data_dir
|
|
26
|
+
canonical_mcp_dir = get_mcp_dir()
|
|
27
|
+
project_mcp_dir = get_project_data_dir() / "mcp"
|
|
28
|
+
|
|
29
|
+
locations = [
|
|
30
|
+
project_mcp_dir / "config.json",
|
|
31
|
+
canonical_mcp_dir / "config.json",
|
|
32
|
+
# Legacy paths for backward compatibility
|
|
33
|
+
Path.cwd() / ".praison" / "mcp.json",
|
|
34
|
+
Path.cwd() / ".praison" / "mcp" / "config.json",
|
|
35
|
+
Path.home() / ".praison" / "mcp.json",
|
|
36
|
+
Path.home() / ".config" / "praison" / "mcp.json",
|
|
37
|
+
]
|
|
38
|
+
except ImportError:
|
|
39
|
+
# Fallback to legacy paths if praisonaiagents not available
|
|
40
|
+
locations = [
|
|
41
|
+
Path.cwd() / ".praisonai" / "mcp" / "config.json",
|
|
42
|
+
Path.cwd() / ".praison" / "mcp.json",
|
|
43
|
+
Path.cwd() / ".praison" / "mcp" / "config.json",
|
|
44
|
+
Path.home() / ".praison" / "mcp.json",
|
|
45
|
+
Path.home() / ".config" / "praison" / "mcp.json",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
for loc in locations:
|
|
49
|
+
if loc.exists():
|
|
50
|
+
try:
|
|
51
|
+
import json
|
|
52
|
+
with open(loc) as f:
|
|
53
|
+
return {"path": str(loc), "config": json.load(f)}
|
|
54
|
+
except Exception:
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
return {}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@register_check(
|
|
61
|
+
id="mcp_config",
|
|
62
|
+
title="MCP Configuration",
|
|
63
|
+
description="Check MCP configuration file",
|
|
64
|
+
category=CheckCategory.MCP,
|
|
65
|
+
severity=CheckSeverity.INFO,
|
|
66
|
+
)
|
|
67
|
+
def check_mcp_config(config: DoctorConfig) -> CheckResult:
|
|
68
|
+
"""Check MCP configuration file."""
|
|
69
|
+
mcp_config = _find_mcp_config()
|
|
70
|
+
|
|
71
|
+
if mcp_config:
|
|
72
|
+
servers = mcp_config.get("config", {}).get("mcpServers", {})
|
|
73
|
+
server_count = len(servers) if isinstance(servers, dict) else 0
|
|
74
|
+
|
|
75
|
+
return CheckResult(
|
|
76
|
+
id="mcp_config",
|
|
77
|
+
title="MCP Configuration",
|
|
78
|
+
category=CheckCategory.MCP,
|
|
79
|
+
status=CheckStatus.PASS,
|
|
80
|
+
message=f"MCP config found with {server_count} server(s)",
|
|
81
|
+
details=f"Path: {mcp_config['path']}",
|
|
82
|
+
metadata={"path": mcp_config["path"], "server_count": server_count},
|
|
83
|
+
)
|
|
84
|
+
else:
|
|
85
|
+
return CheckResult(
|
|
86
|
+
id="mcp_config",
|
|
87
|
+
title="MCP Configuration",
|
|
88
|
+
category=CheckCategory.MCP,
|
|
89
|
+
status=CheckStatus.SKIP,
|
|
90
|
+
message="No MCP configuration found (optional)",
|
|
91
|
+
details="Create ~/.praisonai/mcp/config.json to configure MCP servers",
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@register_check(
|
|
96
|
+
id="mcp_npx",
|
|
97
|
+
title="npx for MCP",
|
|
98
|
+
description="Check npx availability for MCP servers",
|
|
99
|
+
category=CheckCategory.MCP,
|
|
100
|
+
severity=CheckSeverity.LOW,
|
|
101
|
+
)
|
|
102
|
+
def check_mcp_npx(config: DoctorConfig) -> CheckResult:
|
|
103
|
+
"""Check npx availability for MCP servers."""
|
|
104
|
+
npx_path = shutil.which("npx")
|
|
105
|
+
|
|
106
|
+
if npx_path:
|
|
107
|
+
return CheckResult(
|
|
108
|
+
id="mcp_npx",
|
|
109
|
+
title="npx for MCP",
|
|
110
|
+
category=CheckCategory.MCP,
|
|
111
|
+
status=CheckStatus.PASS,
|
|
112
|
+
message=f"npx available at {npx_path}",
|
|
113
|
+
)
|
|
114
|
+
else:
|
|
115
|
+
return CheckResult(
|
|
116
|
+
id="mcp_npx",
|
|
117
|
+
title="npx for MCP",
|
|
118
|
+
category=CheckCategory.MCP,
|
|
119
|
+
status=CheckStatus.WARN,
|
|
120
|
+
message="npx not found (required for most MCP servers)",
|
|
121
|
+
remediation="Install Node.js to use MCP servers",
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
@register_check(
|
|
126
|
+
id="mcp_python",
|
|
127
|
+
title="Python MCP Support",
|
|
128
|
+
description="Check Python MCP package availability",
|
|
129
|
+
category=CheckCategory.MCP,
|
|
130
|
+
severity=CheckSeverity.LOW,
|
|
131
|
+
)
|
|
132
|
+
def check_mcp_python(config: DoctorConfig) -> CheckResult:
|
|
133
|
+
"""Check Python MCP package availability."""
|
|
134
|
+
try:
|
|
135
|
+
import mcp
|
|
136
|
+
version = getattr(mcp, "__version__", "unknown")
|
|
137
|
+
return CheckResult(
|
|
138
|
+
id="mcp_python",
|
|
139
|
+
title="Python MCP Support",
|
|
140
|
+
category=CheckCategory.MCP,
|
|
141
|
+
status=CheckStatus.PASS,
|
|
142
|
+
message=f"mcp package {version} available",
|
|
143
|
+
)
|
|
144
|
+
except ImportError:
|
|
145
|
+
return CheckResult(
|
|
146
|
+
id="mcp_python",
|
|
147
|
+
title="Python MCP Support",
|
|
148
|
+
category=CheckCategory.MCP,
|
|
149
|
+
status=CheckStatus.SKIP,
|
|
150
|
+
message="mcp package not installed (optional)",
|
|
151
|
+
remediation="Install with: pip install mcp",
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
@register_check(
|
|
156
|
+
id="mcp_servers_valid",
|
|
157
|
+
title="MCP Server Configs Valid",
|
|
158
|
+
description="Validate MCP server configurations",
|
|
159
|
+
category=CheckCategory.MCP,
|
|
160
|
+
severity=CheckSeverity.MEDIUM,
|
|
161
|
+
dependencies=["mcp_config"],
|
|
162
|
+
)
|
|
163
|
+
def check_mcp_servers_valid(config: DoctorConfig) -> CheckResult:
|
|
164
|
+
"""Validate MCP server configurations."""
|
|
165
|
+
mcp_config = _find_mcp_config()
|
|
166
|
+
|
|
167
|
+
if not mcp_config:
|
|
168
|
+
return CheckResult(
|
|
169
|
+
id="mcp_servers_valid",
|
|
170
|
+
title="MCP Server Configs Valid",
|
|
171
|
+
category=CheckCategory.MCP,
|
|
172
|
+
status=CheckStatus.SKIP,
|
|
173
|
+
message="No MCP configuration to validate",
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
servers = mcp_config.get("config", {}).get("mcpServers", {})
|
|
177
|
+
if not servers:
|
|
178
|
+
return CheckResult(
|
|
179
|
+
id="mcp_servers_valid",
|
|
180
|
+
title="MCP Server Configs Valid",
|
|
181
|
+
category=CheckCategory.MCP,
|
|
182
|
+
status=CheckStatus.SKIP,
|
|
183
|
+
message="No MCP servers configured",
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
valid = []
|
|
187
|
+
invalid = []
|
|
188
|
+
|
|
189
|
+
for name, server_config in servers.items():
|
|
190
|
+
if not isinstance(server_config, dict):
|
|
191
|
+
invalid.append(f"{name}: invalid config format")
|
|
192
|
+
continue
|
|
193
|
+
|
|
194
|
+
command = server_config.get("command")
|
|
195
|
+
if not command:
|
|
196
|
+
invalid.append(f"{name}: missing 'command'")
|
|
197
|
+
continue
|
|
198
|
+
|
|
199
|
+
# Check if command executable exists
|
|
200
|
+
cmd_parts = command.split() if isinstance(command, str) else [command]
|
|
201
|
+
cmd_exe = cmd_parts[0] if cmd_parts else ""
|
|
202
|
+
|
|
203
|
+
if cmd_exe and shutil.which(cmd_exe):
|
|
204
|
+
valid.append(name)
|
|
205
|
+
else:
|
|
206
|
+
invalid.append(f"{name}: command '{cmd_exe}' not found")
|
|
207
|
+
|
|
208
|
+
if invalid:
|
|
209
|
+
return CheckResult(
|
|
210
|
+
id="mcp_servers_valid",
|
|
211
|
+
title="MCP Server Configs Valid",
|
|
212
|
+
category=CheckCategory.MCP,
|
|
213
|
+
status=CheckStatus.WARN,
|
|
214
|
+
message=f"{len(valid)} valid, {len(invalid)} invalid server(s)",
|
|
215
|
+
details="; ".join(invalid[:3]) + ("..." if len(invalid) > 3 else ""),
|
|
216
|
+
metadata={"valid": valid, "invalid": invalid},
|
|
217
|
+
)
|
|
218
|
+
else:
|
|
219
|
+
return CheckResult(
|
|
220
|
+
id="mcp_servers_valid",
|
|
221
|
+
title="MCP Server Configs Valid",
|
|
222
|
+
category=CheckCategory.MCP,
|
|
223
|
+
status=CheckStatus.PASS,
|
|
224
|
+
message=f"All {len(valid)} MCP server config(s) valid",
|
|
225
|
+
metadata={"valid": valid},
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
@register_check(
|
|
230
|
+
id="mcp_server_spawn",
|
|
231
|
+
title="MCP Server Spawn Test",
|
|
232
|
+
description="Test spawning MCP servers",
|
|
233
|
+
category=CheckCategory.MCP,
|
|
234
|
+
severity=CheckSeverity.LOW,
|
|
235
|
+
requires_deep=True,
|
|
236
|
+
)
|
|
237
|
+
def check_mcp_server_spawn(config: DoctorConfig) -> CheckResult:
|
|
238
|
+
"""Test spawning MCP servers (deep mode only)."""
|
|
239
|
+
mcp_config = _find_mcp_config()
|
|
240
|
+
|
|
241
|
+
if not mcp_config:
|
|
242
|
+
return CheckResult(
|
|
243
|
+
id="mcp_server_spawn",
|
|
244
|
+
title="MCP Server Spawn Test",
|
|
245
|
+
category=CheckCategory.MCP,
|
|
246
|
+
status=CheckStatus.SKIP,
|
|
247
|
+
message="No MCP configuration to test",
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
servers = mcp_config.get("config", {}).get("mcpServers", {})
|
|
251
|
+
if not servers:
|
|
252
|
+
return CheckResult(
|
|
253
|
+
id="mcp_server_spawn",
|
|
254
|
+
title="MCP Server Spawn Test",
|
|
255
|
+
category=CheckCategory.MCP,
|
|
256
|
+
status=CheckStatus.SKIP,
|
|
257
|
+
message="No MCP servers to test",
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
# Only test first server to avoid long delays
|
|
261
|
+
test_server = config.name if config.name else list(servers.keys())[0]
|
|
262
|
+
server_config = servers.get(test_server)
|
|
263
|
+
|
|
264
|
+
if not server_config:
|
|
265
|
+
return CheckResult(
|
|
266
|
+
id="mcp_server_spawn",
|
|
267
|
+
title="MCP Server Spawn Test",
|
|
268
|
+
category=CheckCategory.MCP,
|
|
269
|
+
status=CheckStatus.SKIP,
|
|
270
|
+
message=f"Server '{test_server}' not found",
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
try:
|
|
274
|
+
import subprocess
|
|
275
|
+
|
|
276
|
+
command = server_config.get("command", "")
|
|
277
|
+
args = server_config.get("args", [])
|
|
278
|
+
|
|
279
|
+
if isinstance(command, str):
|
|
280
|
+
cmd = command.split() + args
|
|
281
|
+
else:
|
|
282
|
+
cmd = [command] + args
|
|
283
|
+
|
|
284
|
+
# Try to start the server with a short timeout
|
|
285
|
+
proc = subprocess.Popen(
|
|
286
|
+
cmd,
|
|
287
|
+
stdout=subprocess.PIPE,
|
|
288
|
+
stderr=subprocess.PIPE,
|
|
289
|
+
env={**os.environ, **server_config.get("env", {})},
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
# Wait briefly to see if it starts
|
|
293
|
+
import time
|
|
294
|
+
time.sleep(1)
|
|
295
|
+
|
|
296
|
+
if proc.poll() is None:
|
|
297
|
+
# Process is still running - success
|
|
298
|
+
proc.terminate()
|
|
299
|
+
proc.wait(timeout=2)
|
|
300
|
+
return CheckResult(
|
|
301
|
+
id="mcp_server_spawn",
|
|
302
|
+
title="MCP Server Spawn Test",
|
|
303
|
+
category=CheckCategory.MCP,
|
|
304
|
+
status=CheckStatus.PASS,
|
|
305
|
+
message=f"Server '{test_server}' started successfully",
|
|
306
|
+
)
|
|
307
|
+
else:
|
|
308
|
+
# Process exited
|
|
309
|
+
stderr = proc.stderr.read().decode()[:200] if proc.stderr else ""
|
|
310
|
+
return CheckResult(
|
|
311
|
+
id="mcp_server_spawn",
|
|
312
|
+
title="MCP Server Spawn Test",
|
|
313
|
+
category=CheckCategory.MCP,
|
|
314
|
+
status=CheckStatus.WARN,
|
|
315
|
+
message=f"Server '{test_server}' exited immediately",
|
|
316
|
+
details=stderr if stderr else "No error output",
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
except FileNotFoundError as e:
|
|
320
|
+
return CheckResult(
|
|
321
|
+
id="mcp_server_spawn",
|
|
322
|
+
title="MCP Server Spawn Test",
|
|
323
|
+
category=CheckCategory.MCP,
|
|
324
|
+
status=CheckStatus.FAIL,
|
|
325
|
+
message=f"Command not found for '{test_server}'",
|
|
326
|
+
details=str(e),
|
|
327
|
+
remediation="Install the required MCP server package",
|
|
328
|
+
)
|
|
329
|
+
except Exception as e:
|
|
330
|
+
return CheckResult(
|
|
331
|
+
id="mcp_server_spawn",
|
|
332
|
+
title="MCP Server Spawn Test",
|
|
333
|
+
category=CheckCategory.MCP,
|
|
334
|
+
status=CheckStatus.WARN,
|
|
335
|
+
message=f"Could not test server '{test_server}'",
|
|
336
|
+
details=str(e)[:200],
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
@register_check(
|
|
341
|
+
id="mcp_praisonai_integration",
|
|
342
|
+
title="PraisonAI MCP Integration",
|
|
343
|
+
description="Check PraisonAI MCP integration",
|
|
344
|
+
category=CheckCategory.MCP,
|
|
345
|
+
severity=CheckSeverity.LOW,
|
|
346
|
+
)
|
|
347
|
+
def check_mcp_praisonai_integration(config: DoctorConfig) -> CheckResult:
|
|
348
|
+
"""Check PraisonAI MCP integration."""
|
|
349
|
+
try:
|
|
350
|
+
from praisonaiagents.mcp import MCP
|
|
351
|
+
return CheckResult(
|
|
352
|
+
id="mcp_praisonai_integration",
|
|
353
|
+
title="PraisonAI MCP Integration",
|
|
354
|
+
category=CheckCategory.MCP,
|
|
355
|
+
status=CheckStatus.PASS,
|
|
356
|
+
message="PraisonAI MCP integration available",
|
|
357
|
+
)
|
|
358
|
+
except ImportError as e:
|
|
359
|
+
return CheckResult(
|
|
360
|
+
id="mcp_praisonai_integration",
|
|
361
|
+
title="PraisonAI MCP Integration",
|
|
362
|
+
category=CheckCategory.MCP,
|
|
363
|
+
status=CheckStatus.SKIP,
|
|
364
|
+
message="MCP integration not available",
|
|
365
|
+
details=str(e),
|
|
366
|
+
remediation="Install with: pip install praisonaiagents[mcp]",
|
|
367
|
+
)
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Memory checks for the Doctor CLI module.
|
|
3
|
+
|
|
4
|
+
Validates memory/session storage and integrity.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
from pathlib import Path
|
|
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 _find_memory_dirs() -> list:
|
|
21
|
+
"""Find memory storage directories."""
|
|
22
|
+
locations = [
|
|
23
|
+
Path.cwd() / ".praison" / "memory",
|
|
24
|
+
Path.cwd() / ".praison" / "sessions",
|
|
25
|
+
Path.home() / ".praison" / "memory",
|
|
26
|
+
Path.home() / ".praison" / "sessions",
|
|
27
|
+
Path.home() / ".config" / "praison" / "memory",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
found = []
|
|
31
|
+
for loc in locations:
|
|
32
|
+
if loc.exists() and loc.is_dir():
|
|
33
|
+
found.append(str(loc))
|
|
34
|
+
|
|
35
|
+
return found
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@register_check(
|
|
39
|
+
id="memory_dirs",
|
|
40
|
+
title="Memory Directories",
|
|
41
|
+
description="Check memory storage directories",
|
|
42
|
+
category=CheckCategory.MEMORY,
|
|
43
|
+
severity=CheckSeverity.INFO,
|
|
44
|
+
)
|
|
45
|
+
def check_memory_dirs(config: DoctorConfig) -> CheckResult:
|
|
46
|
+
"""Check memory storage directories."""
|
|
47
|
+
dirs = _find_memory_dirs()
|
|
48
|
+
|
|
49
|
+
if dirs:
|
|
50
|
+
return CheckResult(
|
|
51
|
+
id="memory_dirs",
|
|
52
|
+
title="Memory Directories",
|
|
53
|
+
category=CheckCategory.MEMORY,
|
|
54
|
+
status=CheckStatus.PASS,
|
|
55
|
+
message=f"Found {len(dirs)} memory directory(ies)",
|
|
56
|
+
details=", ".join(dirs),
|
|
57
|
+
metadata={"directories": dirs},
|
|
58
|
+
)
|
|
59
|
+
else:
|
|
60
|
+
return CheckResult(
|
|
61
|
+
id="memory_dirs",
|
|
62
|
+
title="Memory Directories",
|
|
63
|
+
category=CheckCategory.MEMORY,
|
|
64
|
+
status=CheckStatus.SKIP,
|
|
65
|
+
message="No memory directories found (will be created on first use)",
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@register_check(
|
|
70
|
+
id="memory_files",
|
|
71
|
+
title="Memory Files",
|
|
72
|
+
description="Check memory file integrity",
|
|
73
|
+
category=CheckCategory.MEMORY,
|
|
74
|
+
severity=CheckSeverity.MEDIUM,
|
|
75
|
+
dependencies=["memory_dirs"],
|
|
76
|
+
)
|
|
77
|
+
def check_memory_files(config: DoctorConfig) -> CheckResult:
|
|
78
|
+
"""Check memory file integrity."""
|
|
79
|
+
dirs = _find_memory_dirs()
|
|
80
|
+
|
|
81
|
+
if not dirs:
|
|
82
|
+
return CheckResult(
|
|
83
|
+
id="memory_files",
|
|
84
|
+
title="Memory Files",
|
|
85
|
+
category=CheckCategory.MEMORY,
|
|
86
|
+
status=CheckStatus.SKIP,
|
|
87
|
+
message="No memory directories to check",
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
valid_files = 0
|
|
91
|
+
corrupt_files = []
|
|
92
|
+
total_size = 0
|
|
93
|
+
|
|
94
|
+
for dir_path in dirs:
|
|
95
|
+
memory_dir = Path(dir_path)
|
|
96
|
+
for file_path in memory_dir.rglob("*.json"):
|
|
97
|
+
try:
|
|
98
|
+
import json
|
|
99
|
+
with open(file_path) as f:
|
|
100
|
+
json.load(f)
|
|
101
|
+
valid_files += 1
|
|
102
|
+
total_size += file_path.stat().st_size
|
|
103
|
+
except json.JSONDecodeError:
|
|
104
|
+
corrupt_files.append(str(file_path))
|
|
105
|
+
except Exception:
|
|
106
|
+
pass
|
|
107
|
+
|
|
108
|
+
if corrupt_files:
|
|
109
|
+
return CheckResult(
|
|
110
|
+
id="memory_files",
|
|
111
|
+
title="Memory Files",
|
|
112
|
+
category=CheckCategory.MEMORY,
|
|
113
|
+
status=CheckStatus.WARN,
|
|
114
|
+
message=f"{len(corrupt_files)} corrupt file(s) found",
|
|
115
|
+
details="; ".join(corrupt_files[:3]) + ("..." if len(corrupt_files) > 3 else ""),
|
|
116
|
+
remediation="Remove or repair corrupt memory files",
|
|
117
|
+
metadata={"valid": valid_files, "corrupt": corrupt_files},
|
|
118
|
+
)
|
|
119
|
+
elif valid_files > 0:
|
|
120
|
+
size_kb = total_size / 1024
|
|
121
|
+
return CheckResult(
|
|
122
|
+
id="memory_files",
|
|
123
|
+
title="Memory Files",
|
|
124
|
+
category=CheckCategory.MEMORY,
|
|
125
|
+
status=CheckStatus.PASS,
|
|
126
|
+
message=f"{valid_files} valid memory file(s) ({size_kb:.1f} KB)",
|
|
127
|
+
metadata={"valid_count": valid_files, "total_size_bytes": total_size},
|
|
128
|
+
)
|
|
129
|
+
else:
|
|
130
|
+
return CheckResult(
|
|
131
|
+
id="memory_files",
|
|
132
|
+
title="Memory Files",
|
|
133
|
+
category=CheckCategory.MEMORY,
|
|
134
|
+
status=CheckStatus.SKIP,
|
|
135
|
+
message="No memory files found",
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
@register_check(
|
|
140
|
+
id="memory_sessions",
|
|
141
|
+
title="Session Storage",
|
|
142
|
+
description="Check session storage",
|
|
143
|
+
category=CheckCategory.MEMORY,
|
|
144
|
+
severity=CheckSeverity.INFO,
|
|
145
|
+
)
|
|
146
|
+
def check_memory_sessions(config: DoctorConfig) -> CheckResult:
|
|
147
|
+
"""Check session storage."""
|
|
148
|
+
session_dirs = [
|
|
149
|
+
Path.cwd() / ".praison" / "sessions",
|
|
150
|
+
Path.home() / ".praison" / "sessions",
|
|
151
|
+
]
|
|
152
|
+
|
|
153
|
+
sessions = []
|
|
154
|
+
for dir_path in session_dirs:
|
|
155
|
+
if dir_path.exists():
|
|
156
|
+
for item in dir_path.iterdir():
|
|
157
|
+
if item.is_dir() or item.suffix == ".json":
|
|
158
|
+
sessions.append(item.name)
|
|
159
|
+
|
|
160
|
+
if sessions:
|
|
161
|
+
return CheckResult(
|
|
162
|
+
id="memory_sessions",
|
|
163
|
+
title="Session Storage",
|
|
164
|
+
category=CheckCategory.MEMORY,
|
|
165
|
+
status=CheckStatus.PASS,
|
|
166
|
+
message=f"Found {len(sessions)} saved session(s)",
|
|
167
|
+
metadata={"sessions": sessions[:10]},
|
|
168
|
+
)
|
|
169
|
+
else:
|
|
170
|
+
return CheckResult(
|
|
171
|
+
id="memory_sessions",
|
|
172
|
+
title="Session Storage",
|
|
173
|
+
category=CheckCategory.MEMORY,
|
|
174
|
+
status=CheckStatus.SKIP,
|
|
175
|
+
message="No saved sessions found",
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@register_check(
|
|
180
|
+
id="memory_chromadb",
|
|
181
|
+
title="ChromaDB Memory",
|
|
182
|
+
description="Check ChromaDB vector memory",
|
|
183
|
+
category=CheckCategory.MEMORY,
|
|
184
|
+
severity=CheckSeverity.LOW,
|
|
185
|
+
)
|
|
186
|
+
def check_memory_chromadb(config: DoctorConfig) -> CheckResult:
|
|
187
|
+
"""Check ChromaDB vector memory."""
|
|
188
|
+
chroma_dirs = [
|
|
189
|
+
Path.cwd() / ".praison" / "chroma",
|
|
190
|
+
Path.cwd() / "chroma_db",
|
|
191
|
+
Path.home() / ".praison" / "chroma",
|
|
192
|
+
]
|
|
193
|
+
|
|
194
|
+
found = None
|
|
195
|
+
for dir_path in chroma_dirs:
|
|
196
|
+
if dir_path.exists():
|
|
197
|
+
found = dir_path
|
|
198
|
+
break
|
|
199
|
+
|
|
200
|
+
if found:
|
|
201
|
+
try:
|
|
202
|
+
import chromadb
|
|
203
|
+
# Try to open the database
|
|
204
|
+
client = chromadb.PersistentClient(path=str(found))
|
|
205
|
+
collections = client.list_collections()
|
|
206
|
+
return CheckResult(
|
|
207
|
+
id="memory_chromadb",
|
|
208
|
+
title="ChromaDB Memory",
|
|
209
|
+
category=CheckCategory.MEMORY,
|
|
210
|
+
status=CheckStatus.PASS,
|
|
211
|
+
message=f"ChromaDB found with {len(collections)} collection(s)",
|
|
212
|
+
metadata={"path": str(found), "collections": len(collections)},
|
|
213
|
+
)
|
|
214
|
+
except ImportError:
|
|
215
|
+
return CheckResult(
|
|
216
|
+
id="memory_chromadb",
|
|
217
|
+
title="ChromaDB Memory",
|
|
218
|
+
category=CheckCategory.MEMORY,
|
|
219
|
+
status=CheckStatus.WARN,
|
|
220
|
+
message="ChromaDB directory found but chromadb not installed",
|
|
221
|
+
remediation="Install with: pip install chromadb",
|
|
222
|
+
)
|
|
223
|
+
except Exception as e:
|
|
224
|
+
return CheckResult(
|
|
225
|
+
id="memory_chromadb",
|
|
226
|
+
title="ChromaDB Memory",
|
|
227
|
+
category=CheckCategory.MEMORY,
|
|
228
|
+
status=CheckStatus.WARN,
|
|
229
|
+
message=f"ChromaDB found but cannot open: {type(e).__name__}",
|
|
230
|
+
details=str(e)[:200],
|
|
231
|
+
)
|
|
232
|
+
else:
|
|
233
|
+
return CheckResult(
|
|
234
|
+
id="memory_chromadb",
|
|
235
|
+
title="ChromaDB Memory",
|
|
236
|
+
category=CheckCategory.MEMORY,
|
|
237
|
+
status=CheckStatus.SKIP,
|
|
238
|
+
message="No ChromaDB storage found (optional)",
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
@register_check(
|
|
243
|
+
id="memory_praisonai_module",
|
|
244
|
+
title="PraisonAI Memory Module",
|
|
245
|
+
description="Check PraisonAI memory module",
|
|
246
|
+
category=CheckCategory.MEMORY,
|
|
247
|
+
severity=CheckSeverity.LOW,
|
|
248
|
+
)
|
|
249
|
+
def check_memory_praisonai_module(config: DoctorConfig) -> CheckResult:
|
|
250
|
+
"""Check PraisonAI memory module."""
|
|
251
|
+
try:
|
|
252
|
+
from praisonaiagents.memory import FileMemory, Memory
|
|
253
|
+
return CheckResult(
|
|
254
|
+
id="memory_praisonai_module",
|
|
255
|
+
title="PraisonAI Memory Module",
|
|
256
|
+
category=CheckCategory.MEMORY,
|
|
257
|
+
status=CheckStatus.PASS,
|
|
258
|
+
message="Memory modules available (FileMemory, Memory)",
|
|
259
|
+
)
|
|
260
|
+
except ImportError as e:
|
|
261
|
+
return CheckResult(
|
|
262
|
+
id="memory_praisonai_module",
|
|
263
|
+
title="PraisonAI Memory Module",
|
|
264
|
+
category=CheckCategory.MEMORY,
|
|
265
|
+
status=CheckStatus.WARN,
|
|
266
|
+
message="Memory module import failed",
|
|
267
|
+
details=str(e),
|
|
268
|
+
)
|