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,636 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Persistence CLI feature for PraisonAI.
|
|
3
|
+
|
|
4
|
+
Provides commands for database persistence configuration and management:
|
|
5
|
+
- praisonai persistence doctor - Validate DB connectivity
|
|
6
|
+
- praisonai persistence run - Run agent with persistence
|
|
7
|
+
- praisonai persistence resume - Resume a session
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
import sys
|
|
12
|
+
import logging
|
|
13
|
+
from typing import Optional
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def handle_persistence_command(args: list) -> bool:
|
|
19
|
+
"""
|
|
20
|
+
Handle persistence subcommands.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
args: Command line arguments after 'persistence'
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
True if command was handled, False otherwise
|
|
27
|
+
"""
|
|
28
|
+
if not args:
|
|
29
|
+
print_persistence_help()
|
|
30
|
+
return True
|
|
31
|
+
|
|
32
|
+
subcommand = args[0].lower()
|
|
33
|
+
sub_args = args[1:]
|
|
34
|
+
|
|
35
|
+
if subcommand == "doctor":
|
|
36
|
+
return handle_doctor(sub_args)
|
|
37
|
+
elif subcommand == "run":
|
|
38
|
+
return handle_run(sub_args)
|
|
39
|
+
elif subcommand == "resume":
|
|
40
|
+
return handle_resume(sub_args)
|
|
41
|
+
elif subcommand == "export":
|
|
42
|
+
return handle_export(sub_args)
|
|
43
|
+
elif subcommand == "import":
|
|
44
|
+
return handle_import(sub_args)
|
|
45
|
+
elif subcommand == "migrate":
|
|
46
|
+
return handle_migrate(sub_args)
|
|
47
|
+
elif subcommand == "status":
|
|
48
|
+
return handle_status(sub_args)
|
|
49
|
+
elif subcommand in ("--help", "-h", "help"):
|
|
50
|
+
print_persistence_help()
|
|
51
|
+
return True
|
|
52
|
+
else:
|
|
53
|
+
print(f"Unknown persistence subcommand: {subcommand}")
|
|
54
|
+
print_persistence_help()
|
|
55
|
+
return True
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def print_persistence_help():
|
|
59
|
+
"""Print persistence command help."""
|
|
60
|
+
help_text = """
|
|
61
|
+
PraisonAI Persistence Commands
|
|
62
|
+
==============================
|
|
63
|
+
|
|
64
|
+
Usage: praisonai persistence <command> [options]
|
|
65
|
+
|
|
66
|
+
Commands:
|
|
67
|
+
doctor Validate database connectivity and configuration
|
|
68
|
+
run Run an agent with persistence enabled
|
|
69
|
+
resume Resume an existing session
|
|
70
|
+
|
|
71
|
+
Doctor Command:
|
|
72
|
+
praisonai persistence doctor [options]
|
|
73
|
+
|
|
74
|
+
Options:
|
|
75
|
+
--conversation-url URL Conversation store URL (postgres/mysql/sqlite)
|
|
76
|
+
--knowledge-url URL Knowledge store URL (qdrant/chroma/pinecone)
|
|
77
|
+
--state-url URL State store URL (redis/memory)
|
|
78
|
+
--all Test all configured stores
|
|
79
|
+
|
|
80
|
+
Environment Variables:
|
|
81
|
+
PRAISON_CONVERSATION_URL Default conversation store URL
|
|
82
|
+
PRAISON_KNOWLEDGE_URL Default knowledge store URL
|
|
83
|
+
PRAISON_STATE_URL Default state store URL
|
|
84
|
+
|
|
85
|
+
Run Command:
|
|
86
|
+
praisonai persistence run [options] "prompt"
|
|
87
|
+
|
|
88
|
+
Options:
|
|
89
|
+
--session-id ID Session identifier (auto-generated if not provided)
|
|
90
|
+
--user-id ID User identifier (default: "default")
|
|
91
|
+
--conversation-url URL Conversation store URL
|
|
92
|
+
--knowledge-url URL Knowledge store URL
|
|
93
|
+
--state-url URL State store URL
|
|
94
|
+
--agent-name NAME Agent name (default: "Assistant")
|
|
95
|
+
--agent-instructions TEXT Agent instructions
|
|
96
|
+
--dry-run Show configuration without running
|
|
97
|
+
|
|
98
|
+
Resume Command:
|
|
99
|
+
praisonai persistence resume --session-id ID [options]
|
|
100
|
+
|
|
101
|
+
Options:
|
|
102
|
+
--session-id ID Session to resume (required)
|
|
103
|
+
--conversation-url URL Conversation store URL
|
|
104
|
+
--show-history Display conversation history
|
|
105
|
+
--continue "prompt" Continue with a new prompt
|
|
106
|
+
|
|
107
|
+
Export/Import Commands:
|
|
108
|
+
praisonai persistence export --session-id ID [options]
|
|
109
|
+
praisonai persistence import --file FILE [options]
|
|
110
|
+
|
|
111
|
+
Options:
|
|
112
|
+
--session-id ID Session to export (required for export)
|
|
113
|
+
--conversation-url URL Conversation store URL
|
|
114
|
+
--file FILE File path for export/import (JSONL format)
|
|
115
|
+
--output FILE Output file path (default: session-{id}.jsonl)
|
|
116
|
+
|
|
117
|
+
Examples:
|
|
118
|
+
# Check PostgreSQL connectivity
|
|
119
|
+
praisonai persistence doctor --conversation-url "postgresql://localhost/mydb"
|
|
120
|
+
|
|
121
|
+
# Run agent with persistence
|
|
122
|
+
praisonai persistence run --session-id "my-session" "Hello, remember my name is Alice"
|
|
123
|
+
|
|
124
|
+
# Resume a session
|
|
125
|
+
praisonai persistence resume --session-id "my-session" --show-history
|
|
126
|
+
|
|
127
|
+
# Continue a session
|
|
128
|
+
praisonai persistence resume --session-id "my-session" --continue "What's my name?"
|
|
129
|
+
|
|
130
|
+
# Export a session
|
|
131
|
+
praisonai persistence export --session-id "my-session" --output session.jsonl
|
|
132
|
+
|
|
133
|
+
# Import a session
|
|
134
|
+
praisonai persistence import --file session.jsonl
|
|
135
|
+
"""
|
|
136
|
+
print(help_text)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def parse_persistence_args(args: list) -> dict:
|
|
140
|
+
"""Parse persistence command arguments."""
|
|
141
|
+
config = {
|
|
142
|
+
"session_id": None,
|
|
143
|
+
"user_id": "default",
|
|
144
|
+
"conversation_url": os.getenv("PRAISON_CONVERSATION_URL"),
|
|
145
|
+
"knowledge_url": os.getenv("PRAISON_KNOWLEDGE_URL"),
|
|
146
|
+
"state_url": os.getenv("PRAISON_STATE_URL"),
|
|
147
|
+
"agent_name": "Assistant",
|
|
148
|
+
"agent_instructions": "You are a helpful assistant.",
|
|
149
|
+
"dry_run": False,
|
|
150
|
+
"show_history": False,
|
|
151
|
+
"all_stores": False,
|
|
152
|
+
"prompt": None,
|
|
153
|
+
"continue_prompt": None,
|
|
154
|
+
"output_file": None,
|
|
155
|
+
"input_file": None,
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
i = 0
|
|
159
|
+
while i < len(args):
|
|
160
|
+
arg = args[i]
|
|
161
|
+
|
|
162
|
+
if arg == "--session-id" and i + 1 < len(args):
|
|
163
|
+
config["session_id"] = args[i + 1]
|
|
164
|
+
i += 2
|
|
165
|
+
elif arg == "--user-id" and i + 1 < len(args):
|
|
166
|
+
config["user_id"] = args[i + 1]
|
|
167
|
+
i += 2
|
|
168
|
+
elif arg == "--conversation-url" and i + 1 < len(args):
|
|
169
|
+
config["conversation_url"] = args[i + 1]
|
|
170
|
+
i += 2
|
|
171
|
+
elif arg == "--knowledge-url" and i + 1 < len(args):
|
|
172
|
+
config["knowledge_url"] = args[i + 1]
|
|
173
|
+
i += 2
|
|
174
|
+
elif arg == "--state-url" and i + 1 < len(args):
|
|
175
|
+
config["state_url"] = args[i + 1]
|
|
176
|
+
i += 2
|
|
177
|
+
elif arg == "--agent-name" and i + 1 < len(args):
|
|
178
|
+
config["agent_name"] = args[i + 1]
|
|
179
|
+
i += 2
|
|
180
|
+
elif arg == "--agent-instructions" and i + 1 < len(args):
|
|
181
|
+
config["agent_instructions"] = args[i + 1]
|
|
182
|
+
i += 2
|
|
183
|
+
elif arg == "--dry-run":
|
|
184
|
+
config["dry_run"] = True
|
|
185
|
+
i += 1
|
|
186
|
+
elif arg == "--show-history":
|
|
187
|
+
config["show_history"] = True
|
|
188
|
+
i += 1
|
|
189
|
+
elif arg == "--all":
|
|
190
|
+
config["all_stores"] = True
|
|
191
|
+
i += 1
|
|
192
|
+
elif arg == "--continue" and i + 1 < len(args):
|
|
193
|
+
config["continue_prompt"] = args[i + 1]
|
|
194
|
+
i += 2
|
|
195
|
+
elif arg == "--output" and i + 1 < len(args):
|
|
196
|
+
config["output_file"] = args[i + 1]
|
|
197
|
+
i += 2
|
|
198
|
+
elif arg == "--file" and i + 1 < len(args):
|
|
199
|
+
config["input_file"] = args[i + 1]
|
|
200
|
+
i += 2
|
|
201
|
+
elif not arg.startswith("-"):
|
|
202
|
+
config["prompt"] = arg
|
|
203
|
+
i += 1
|
|
204
|
+
else:
|
|
205
|
+
i += 1
|
|
206
|
+
|
|
207
|
+
return config
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def handle_doctor(args: list) -> bool:
|
|
211
|
+
"""Handle persistence doctor command."""
|
|
212
|
+
config = parse_persistence_args(args)
|
|
213
|
+
|
|
214
|
+
print("=" * 50)
|
|
215
|
+
print("PraisonAI Persistence Doctor")
|
|
216
|
+
print("=" * 50)
|
|
217
|
+
|
|
218
|
+
results = []
|
|
219
|
+
|
|
220
|
+
# Test conversation store
|
|
221
|
+
if config["conversation_url"] or config["all_stores"]:
|
|
222
|
+
url = config["conversation_url"]
|
|
223
|
+
if url:
|
|
224
|
+
print(f"\n[Conversation Store] Testing: {_mask_url(url)}")
|
|
225
|
+
success, msg = _test_conversation_store(url)
|
|
226
|
+
results.append(("Conversation", success, msg))
|
|
227
|
+
print(f" {'✅' if success else '❌'} {msg}")
|
|
228
|
+
else:
|
|
229
|
+
print("\n[Conversation Store] Not configured (set --conversation-url or PRAISON_CONVERSATION_URL)")
|
|
230
|
+
|
|
231
|
+
# Test knowledge store
|
|
232
|
+
if config["knowledge_url"] or config["all_stores"]:
|
|
233
|
+
url = config["knowledge_url"]
|
|
234
|
+
if url:
|
|
235
|
+
print(f"\n[Knowledge Store] Testing: {_mask_url(url)}")
|
|
236
|
+
success, msg = _test_knowledge_store(url)
|
|
237
|
+
results.append(("Knowledge", success, msg))
|
|
238
|
+
print(f" {'✅' if success else '❌'} {msg}")
|
|
239
|
+
else:
|
|
240
|
+
print("\n[Knowledge Store] Not configured (set --knowledge-url or PRAISON_KNOWLEDGE_URL)")
|
|
241
|
+
|
|
242
|
+
# Test state store
|
|
243
|
+
if config["state_url"] or config["all_stores"]:
|
|
244
|
+
url = config["state_url"]
|
|
245
|
+
if url:
|
|
246
|
+
print(f"\n[State Store] Testing: {_mask_url(url)}")
|
|
247
|
+
success, msg = _test_state_store(url)
|
|
248
|
+
results.append(("State", success, msg))
|
|
249
|
+
print(f" {'✅' if success else '❌'} {msg}")
|
|
250
|
+
else:
|
|
251
|
+
print("\n[State Store] Not configured (set --state-url or PRAISON_STATE_URL)")
|
|
252
|
+
|
|
253
|
+
# Summary
|
|
254
|
+
print("\n" + "=" * 50)
|
|
255
|
+
if results:
|
|
256
|
+
passed = sum(1 for _, s, _ in results if s)
|
|
257
|
+
total = len(results)
|
|
258
|
+
print(f"Results: {passed}/{total} stores connected successfully")
|
|
259
|
+
else:
|
|
260
|
+
print("No stores configured. Use --conversation-url, --knowledge-url, or --state-url")
|
|
261
|
+
print("=" * 50)
|
|
262
|
+
|
|
263
|
+
return True
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def handle_run(args: list) -> bool:
|
|
267
|
+
"""Handle persistence run command."""
|
|
268
|
+
config = parse_persistence_args(args)
|
|
269
|
+
|
|
270
|
+
if not config["prompt"]:
|
|
271
|
+
print("Error: No prompt provided")
|
|
272
|
+
print("Usage: praisonai persistence run [options] \"your prompt\"")
|
|
273
|
+
return True
|
|
274
|
+
|
|
275
|
+
if not config["conversation_url"]:
|
|
276
|
+
print("Error: No conversation URL configured")
|
|
277
|
+
print("Set --conversation-url or PRAISON_CONVERSATION_URL")
|
|
278
|
+
return True
|
|
279
|
+
|
|
280
|
+
if config["dry_run"]:
|
|
281
|
+
print("=" * 50)
|
|
282
|
+
print("Dry Run - Configuration")
|
|
283
|
+
print("=" * 50)
|
|
284
|
+
print(f"Session ID: {config['session_id'] or '(auto-generated)'}")
|
|
285
|
+
print(f"User ID: {config['user_id']}")
|
|
286
|
+
print(f"Conversation URL: {_mask_url(config['conversation_url'])}")
|
|
287
|
+
print(f"Agent Name: {config['agent_name']}")
|
|
288
|
+
print(f"Prompt: {config['prompt'][:50]}...")
|
|
289
|
+
return True
|
|
290
|
+
|
|
291
|
+
# Run agent with persistence
|
|
292
|
+
try:
|
|
293
|
+
from praisonaiagents import Agent, db
|
|
294
|
+
|
|
295
|
+
db_instance = db(
|
|
296
|
+
database_url=config["conversation_url"],
|
|
297
|
+
state_url=config["state_url"],
|
|
298
|
+
knowledge_url=config["knowledge_url"],
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
agent = Agent(
|
|
302
|
+
name=config["agent_name"],
|
|
303
|
+
instructions=config["agent_instructions"],
|
|
304
|
+
db=db_instance,
|
|
305
|
+
session_id=config["session_id"],
|
|
306
|
+
verbose=True
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
print(f"\n[Session: {agent.session_id}]")
|
|
310
|
+
response = agent.chat(config["prompt"])
|
|
311
|
+
print(f"\nAgent: {response}")
|
|
312
|
+
|
|
313
|
+
db_instance.close()
|
|
314
|
+
|
|
315
|
+
except Exception as e:
|
|
316
|
+
print(f"Error: {e}")
|
|
317
|
+
return True
|
|
318
|
+
|
|
319
|
+
return True
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
def handle_resume(args: list) -> bool:
|
|
323
|
+
"""Handle persistence resume command."""
|
|
324
|
+
config = parse_persistence_args(args)
|
|
325
|
+
|
|
326
|
+
if not config["session_id"]:
|
|
327
|
+
print("Error: --session-id is required for resume")
|
|
328
|
+
return True
|
|
329
|
+
|
|
330
|
+
if not config["conversation_url"]:
|
|
331
|
+
print("Error: No conversation URL configured")
|
|
332
|
+
print("Set --conversation-url or PRAISON_CONVERSATION_URL")
|
|
333
|
+
return True
|
|
334
|
+
|
|
335
|
+
try:
|
|
336
|
+
from praisonaiagents import db
|
|
337
|
+
|
|
338
|
+
db_instance = db(database_url=config["conversation_url"])
|
|
339
|
+
|
|
340
|
+
# Get session history
|
|
341
|
+
history = db_instance.on_agent_start(
|
|
342
|
+
agent_name="Resume",
|
|
343
|
+
session_id=config["session_id"],
|
|
344
|
+
user_id=config["user_id"]
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
print(f"\n[Session: {config['session_id']}]")
|
|
348
|
+
print(f"Messages in history: {len(history)}")
|
|
349
|
+
|
|
350
|
+
if config["show_history"]:
|
|
351
|
+
print("\n--- Conversation History ---")
|
|
352
|
+
for msg in history:
|
|
353
|
+
role = msg.role.upper()
|
|
354
|
+
content = msg.content[:100] + "..." if len(msg.content) > 100 else msg.content
|
|
355
|
+
print(f"[{role}] {content}")
|
|
356
|
+
print("--- End History ---\n")
|
|
357
|
+
|
|
358
|
+
if config["continue_prompt"]:
|
|
359
|
+
from praisonaiagents import Agent
|
|
360
|
+
|
|
361
|
+
agent = Agent(
|
|
362
|
+
name=config["agent_name"],
|
|
363
|
+
instructions=config["agent_instructions"],
|
|
364
|
+
db=db_instance,
|
|
365
|
+
session_id=config["session_id"],
|
|
366
|
+
verbose=True
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
response = agent.chat(config["continue_prompt"])
|
|
370
|
+
print(f"\nAgent: {response}")
|
|
371
|
+
|
|
372
|
+
db_instance.close()
|
|
373
|
+
|
|
374
|
+
except Exception as e:
|
|
375
|
+
print(f"Error: {e}")
|
|
376
|
+
return True
|
|
377
|
+
|
|
378
|
+
return True
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
def handle_export(args: list) -> bool:
|
|
382
|
+
"""Handle persistence export command."""
|
|
383
|
+
config = parse_persistence_args(args)
|
|
384
|
+
|
|
385
|
+
if not config["session_id"]:
|
|
386
|
+
print("Error: --session-id is required for export")
|
|
387
|
+
return True
|
|
388
|
+
|
|
389
|
+
if not config["conversation_url"]:
|
|
390
|
+
print("Error: No conversation URL configured")
|
|
391
|
+
return True
|
|
392
|
+
|
|
393
|
+
try:
|
|
394
|
+
from praisonaiagents import db
|
|
395
|
+
import json
|
|
396
|
+
|
|
397
|
+
db_instance = db(database_url=config["conversation_url"])
|
|
398
|
+
|
|
399
|
+
# Export session
|
|
400
|
+
data = db_instance.export_session(config["session_id"])
|
|
401
|
+
|
|
402
|
+
if not data:
|
|
403
|
+
print(f"Error: Session {config['session_id']} not found")
|
|
404
|
+
db_instance.close()
|
|
405
|
+
return True
|
|
406
|
+
|
|
407
|
+
# Determine output file
|
|
408
|
+
output_file = config.get("output_file") or f"session-{config['session_id']}.jsonl"
|
|
409
|
+
|
|
410
|
+
with open(output_file, 'w') as f:
|
|
411
|
+
f.write(json.dumps(data, default=str) + '\n')
|
|
412
|
+
|
|
413
|
+
print(f"Exported session to: {output_file}")
|
|
414
|
+
print(f"Messages: {len(data.get('messages', []))}")
|
|
415
|
+
|
|
416
|
+
db_instance.close()
|
|
417
|
+
|
|
418
|
+
except Exception as e:
|
|
419
|
+
print(f"Error: {e}")
|
|
420
|
+
return True
|
|
421
|
+
|
|
422
|
+
return True
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
def handle_import(args: list) -> bool:
|
|
426
|
+
"""Handle persistence import command."""
|
|
427
|
+
config = parse_persistence_args(args)
|
|
428
|
+
|
|
429
|
+
input_file = config.get("input_file")
|
|
430
|
+
if not input_file:
|
|
431
|
+
print("Error: --file is required for import")
|
|
432
|
+
return True
|
|
433
|
+
|
|
434
|
+
if not config["conversation_url"]:
|
|
435
|
+
print("Error: No conversation URL configured")
|
|
436
|
+
return True
|
|
437
|
+
|
|
438
|
+
try:
|
|
439
|
+
from praisonaiagents import db
|
|
440
|
+
import json
|
|
441
|
+
|
|
442
|
+
db_instance = db(database_url=config["conversation_url"])
|
|
443
|
+
|
|
444
|
+
with open(input_file, 'r') as f:
|
|
445
|
+
data = json.loads(f.readline())
|
|
446
|
+
|
|
447
|
+
session_id = db_instance.import_session(data)
|
|
448
|
+
|
|
449
|
+
print(f"Imported session: {session_id}")
|
|
450
|
+
print(f"Messages: {len(data.get('messages', []))}")
|
|
451
|
+
|
|
452
|
+
db_instance.close()
|
|
453
|
+
|
|
454
|
+
except Exception as e:
|
|
455
|
+
print(f"Error: {e}")
|
|
456
|
+
return True
|
|
457
|
+
|
|
458
|
+
return True
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
def handle_migrate(args: list) -> bool:
|
|
462
|
+
"""Handle persistence migrate command."""
|
|
463
|
+
config = parse_persistence_args(args)
|
|
464
|
+
|
|
465
|
+
if not config["conversation_url"] and not config["state_url"]:
|
|
466
|
+
print("Error: No database URL configured")
|
|
467
|
+
print("Set --conversation-url or --state-url")
|
|
468
|
+
return True
|
|
469
|
+
|
|
470
|
+
try:
|
|
471
|
+
from praisonaiagents import db
|
|
472
|
+
from praisonai.persistence.migrations import MigrationManager
|
|
473
|
+
|
|
474
|
+
db_instance = db(
|
|
475
|
+
database_url=config["conversation_url"],
|
|
476
|
+
state_url=config["state_url"]
|
|
477
|
+
)
|
|
478
|
+
|
|
479
|
+
manager = MigrationManager(db_instance)
|
|
480
|
+
|
|
481
|
+
# Check for --up or --down flags
|
|
482
|
+
direction = "up"
|
|
483
|
+
target = None
|
|
484
|
+
for i, arg in enumerate(args):
|
|
485
|
+
if arg == "--down":
|
|
486
|
+
direction = "down"
|
|
487
|
+
elif arg == "--target" and i + 1 < len(args):
|
|
488
|
+
target = args[i + 1]
|
|
489
|
+
|
|
490
|
+
if direction == "up":
|
|
491
|
+
print("Applying pending migrations...")
|
|
492
|
+
applied = manager.migrate_up(target)
|
|
493
|
+
if applied:
|
|
494
|
+
print(f"Applied migrations: {', '.join(applied)}")
|
|
495
|
+
else:
|
|
496
|
+
print("No pending migrations")
|
|
497
|
+
else:
|
|
498
|
+
if not target:
|
|
499
|
+
print("Error: --target required for --down migration")
|
|
500
|
+
return True
|
|
501
|
+
print(f"Rolling back to version {target}...")
|
|
502
|
+
rolled_back = manager.migrate_down(target)
|
|
503
|
+
if rolled_back:
|
|
504
|
+
print(f"Rolled back: {', '.join(rolled_back)}")
|
|
505
|
+
else:
|
|
506
|
+
print("No migrations to rollback")
|
|
507
|
+
|
|
508
|
+
db_instance.close()
|
|
509
|
+
|
|
510
|
+
except Exception as e:
|
|
511
|
+
print(f"Error: {e}")
|
|
512
|
+
return True
|
|
513
|
+
|
|
514
|
+
return True
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
def handle_status(args: list) -> bool:
|
|
518
|
+
"""Handle persistence status command."""
|
|
519
|
+
config = parse_persistence_args(args)
|
|
520
|
+
|
|
521
|
+
if not config["conversation_url"] and not config["state_url"]:
|
|
522
|
+
print("Error: No database URL configured")
|
|
523
|
+
return True
|
|
524
|
+
|
|
525
|
+
try:
|
|
526
|
+
from praisonaiagents import db
|
|
527
|
+
from praisonai.persistence.migrations import MigrationManager
|
|
528
|
+
|
|
529
|
+
db_instance = db(
|
|
530
|
+
database_url=config["conversation_url"],
|
|
531
|
+
state_url=config["state_url"]
|
|
532
|
+
)
|
|
533
|
+
|
|
534
|
+
manager = MigrationManager(db_instance)
|
|
535
|
+
status = manager.get_migration_status()
|
|
536
|
+
|
|
537
|
+
print("\n=== Schema Status ===")
|
|
538
|
+
print(f"Current version: {status['current_version'] or '(not set)'}")
|
|
539
|
+
print(f"Latest version: {status['latest_version']}")
|
|
540
|
+
print(f"Pending: {status['pending_count']} migration(s)")
|
|
541
|
+
|
|
542
|
+
if status['pending_versions']:
|
|
543
|
+
print(f"Pending versions: {', '.join(status['pending_versions'])}")
|
|
544
|
+
|
|
545
|
+
db_instance.close()
|
|
546
|
+
|
|
547
|
+
except Exception as e:
|
|
548
|
+
print(f"Error: {e}")
|
|
549
|
+
return True
|
|
550
|
+
|
|
551
|
+
return True
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
def _mask_url(url: str) -> str:
|
|
555
|
+
"""Mask sensitive parts of URL."""
|
|
556
|
+
if not url:
|
|
557
|
+
return "(not set)"
|
|
558
|
+
|
|
559
|
+
# Mask password in URLs
|
|
560
|
+
import re
|
|
561
|
+
masked = re.sub(r'://([^:]+):([^@]+)@', r'://\1:****@', url)
|
|
562
|
+
return masked
|
|
563
|
+
|
|
564
|
+
|
|
565
|
+
def _test_conversation_store(url: str) -> tuple:
|
|
566
|
+
"""Test conversation store connectivity."""
|
|
567
|
+
try:
|
|
568
|
+
from praisonai.persistence.factory import create_conversation_store
|
|
569
|
+
|
|
570
|
+
# Detect backend
|
|
571
|
+
if "postgresql" in url or "postgres" in url:
|
|
572
|
+
backend = "postgres"
|
|
573
|
+
elif "mysql" in url:
|
|
574
|
+
backend = "mysql"
|
|
575
|
+
elif url.endswith(".db") or "sqlite" in url:
|
|
576
|
+
backend = "sqlite"
|
|
577
|
+
else:
|
|
578
|
+
backend = "sqlite"
|
|
579
|
+
|
|
580
|
+
store = create_conversation_store(backend, url=url)
|
|
581
|
+
|
|
582
|
+
# Try a simple operation
|
|
583
|
+
sessions = store.list_sessions(limit=1)
|
|
584
|
+
store.close()
|
|
585
|
+
|
|
586
|
+
return True, f"Connected ({backend})"
|
|
587
|
+
except Exception as e:
|
|
588
|
+
return False, str(e)
|
|
589
|
+
|
|
590
|
+
|
|
591
|
+
def _test_knowledge_store(url: str) -> tuple:
|
|
592
|
+
"""Test knowledge store connectivity."""
|
|
593
|
+
try:
|
|
594
|
+
from praisonai.persistence.factory import create_knowledge_store
|
|
595
|
+
|
|
596
|
+
# Detect backend
|
|
597
|
+
if "qdrant" in url or ":6333" in url:
|
|
598
|
+
backend = "qdrant"
|
|
599
|
+
elif "chroma" in url:
|
|
600
|
+
backend = "chroma"
|
|
601
|
+
else:
|
|
602
|
+
backend = "qdrant"
|
|
603
|
+
|
|
604
|
+
store = create_knowledge_store(backend, url=url)
|
|
605
|
+
|
|
606
|
+
# Try a simple operation
|
|
607
|
+
exists = store.collection_exists("test_doctor")
|
|
608
|
+
store.close()
|
|
609
|
+
|
|
610
|
+
return True, f"Connected ({backend})"
|
|
611
|
+
except Exception as e:
|
|
612
|
+
return False, str(e)
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
def _test_state_store(url: str) -> tuple:
|
|
616
|
+
"""Test state store connectivity."""
|
|
617
|
+
try:
|
|
618
|
+
from praisonai.persistence.factory import create_state_store
|
|
619
|
+
|
|
620
|
+
# Detect backend
|
|
621
|
+
if "redis" in url:
|
|
622
|
+
backend = "redis"
|
|
623
|
+
else:
|
|
624
|
+
backend = "memory"
|
|
625
|
+
|
|
626
|
+
store = create_state_store(backend, url=url)
|
|
627
|
+
|
|
628
|
+
# Try a simple operation
|
|
629
|
+
store.set("_doctor_test", "ok", ttl=5)
|
|
630
|
+
value = store.get("_doctor_test")
|
|
631
|
+
store.delete("_doctor_test")
|
|
632
|
+
store.close()
|
|
633
|
+
|
|
634
|
+
return True, f"Connected ({backend})"
|
|
635
|
+
except Exception as e:
|
|
636
|
+
return False, str(e)
|