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,287 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SurrealDB implementation of ConversationStore.
|
|
3
|
+
|
|
4
|
+
Requires: surrealdb
|
|
5
|
+
Install: pip install surrealdb
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
import logging
|
|
10
|
+
from typing import List, Optional
|
|
11
|
+
|
|
12
|
+
from .base import ConversationStore, ConversationSession, ConversationMessage
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class SurrealDBConversationStore(ConversationStore):
|
|
18
|
+
"""
|
|
19
|
+
SurrealDB-based conversation store.
|
|
20
|
+
|
|
21
|
+
SurrealDB is a multi-model database supporting SQL-like queries.
|
|
22
|
+
|
|
23
|
+
Example:
|
|
24
|
+
store = SurrealDBConversationStore(
|
|
25
|
+
url="ws://localhost:8000/rpc",
|
|
26
|
+
namespace="praisonai",
|
|
27
|
+
database="conversations"
|
|
28
|
+
)
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
SCHEMA_VERSION = "1.0.0"
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
url: str = "ws://localhost:8000/rpc",
|
|
36
|
+
namespace: str = "praisonai",
|
|
37
|
+
database: str = "conversations",
|
|
38
|
+
username: Optional[str] = None,
|
|
39
|
+
password: Optional[str] = None,
|
|
40
|
+
table_prefix: str = "praison_",
|
|
41
|
+
auto_create_tables: bool = True,
|
|
42
|
+
):
|
|
43
|
+
try:
|
|
44
|
+
from surrealdb import Surreal
|
|
45
|
+
except ImportError:
|
|
46
|
+
raise ImportError(
|
|
47
|
+
"surrealdb is required for SurrealDB support. "
|
|
48
|
+
"Install with: pip install surrealdb"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
self._Surreal = Surreal
|
|
52
|
+
self.url = url
|
|
53
|
+
self.namespace = namespace
|
|
54
|
+
self.database = database
|
|
55
|
+
self.username = username
|
|
56
|
+
self.password = password
|
|
57
|
+
self.table_prefix = table_prefix
|
|
58
|
+
self.sessions_table = f"{table_prefix}sessions"
|
|
59
|
+
self.messages_table = f"{table_prefix}messages"
|
|
60
|
+
self._client = None
|
|
61
|
+
|
|
62
|
+
# Note: SurrealDB Python client is async, we'll use sync wrapper
|
|
63
|
+
self._init_sync()
|
|
64
|
+
|
|
65
|
+
def _init_sync(self):
|
|
66
|
+
"""Initialize synchronously using asyncio."""
|
|
67
|
+
import asyncio
|
|
68
|
+
|
|
69
|
+
async def _init():
|
|
70
|
+
self._client = self._Surreal(self.url)
|
|
71
|
+
await self._client.connect()
|
|
72
|
+
if self.username and self.password:
|
|
73
|
+
await self._client.signin({"user": self.username, "pass": self.password})
|
|
74
|
+
await self._client.use(self.namespace, self.database)
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
loop = asyncio.get_event_loop()
|
|
78
|
+
except RuntimeError:
|
|
79
|
+
loop = asyncio.new_event_loop()
|
|
80
|
+
asyncio.set_event_loop(loop)
|
|
81
|
+
|
|
82
|
+
loop.run_until_complete(_init())
|
|
83
|
+
|
|
84
|
+
def _run_sync(self, coro):
|
|
85
|
+
"""Run async coroutine synchronously."""
|
|
86
|
+
import asyncio
|
|
87
|
+
try:
|
|
88
|
+
loop = asyncio.get_event_loop()
|
|
89
|
+
except RuntimeError:
|
|
90
|
+
loop = asyncio.new_event_loop()
|
|
91
|
+
asyncio.set_event_loop(loop)
|
|
92
|
+
return loop.run_until_complete(coro)
|
|
93
|
+
|
|
94
|
+
def create_session(self, session: ConversationSession) -> ConversationSession:
|
|
95
|
+
data = {
|
|
96
|
+
"session_id": session.session_id,
|
|
97
|
+
"user_id": session.user_id,
|
|
98
|
+
"agent_id": session.agent_id,
|
|
99
|
+
"name": session.name,
|
|
100
|
+
"state": session.state,
|
|
101
|
+
"metadata": session.metadata,
|
|
102
|
+
"created_at": session.created_at,
|
|
103
|
+
"updated_at": session.updated_at,
|
|
104
|
+
}
|
|
105
|
+
self._run_sync(self._client.create(self.sessions_table, data))
|
|
106
|
+
return session
|
|
107
|
+
|
|
108
|
+
def get_session(self, session_id: str) -> Optional[ConversationSession]:
|
|
109
|
+
result = self._run_sync(
|
|
110
|
+
self._client.query(
|
|
111
|
+
f"SELECT * FROM {self.sessions_table} WHERE session_id = $sid",
|
|
112
|
+
{"sid": session_id}
|
|
113
|
+
)
|
|
114
|
+
)
|
|
115
|
+
if not result or not result[0].get("result"):
|
|
116
|
+
return None
|
|
117
|
+
row = result[0]["result"][0]
|
|
118
|
+
return ConversationSession(
|
|
119
|
+
session_id=row["session_id"],
|
|
120
|
+
user_id=row.get("user_id"),
|
|
121
|
+
agent_id=row.get("agent_id"),
|
|
122
|
+
name=row.get("name"),
|
|
123
|
+
state=row.get("state"),
|
|
124
|
+
metadata=row.get("metadata"),
|
|
125
|
+
created_at=row.get("created_at"),
|
|
126
|
+
updated_at=row.get("updated_at"),
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
def update_session(self, session: ConversationSession) -> ConversationSession:
|
|
130
|
+
self._run_sync(
|
|
131
|
+
self._client.query(
|
|
132
|
+
f"""UPDATE {self.sessions_table} SET
|
|
133
|
+
user_id = $user_id, agent_id = $agent_id, name = $name,
|
|
134
|
+
state = $state, metadata = $metadata, updated_at = $updated_at
|
|
135
|
+
WHERE session_id = $session_id""",
|
|
136
|
+
{
|
|
137
|
+
"session_id": session.session_id,
|
|
138
|
+
"user_id": session.user_id,
|
|
139
|
+
"agent_id": session.agent_id,
|
|
140
|
+
"name": session.name,
|
|
141
|
+
"state": session.state,
|
|
142
|
+
"metadata": session.metadata,
|
|
143
|
+
"updated_at": session.updated_at,
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
)
|
|
147
|
+
return session
|
|
148
|
+
|
|
149
|
+
def delete_session(self, session_id: str) -> bool:
|
|
150
|
+
self._run_sync(
|
|
151
|
+
self._client.query(
|
|
152
|
+
f"DELETE FROM {self.messages_table} WHERE session_id = $sid",
|
|
153
|
+
{"sid": session_id}
|
|
154
|
+
)
|
|
155
|
+
)
|
|
156
|
+
result = self._run_sync(
|
|
157
|
+
self._client.query(
|
|
158
|
+
f"DELETE FROM {self.sessions_table} WHERE session_id = $sid",
|
|
159
|
+
{"sid": session_id}
|
|
160
|
+
)
|
|
161
|
+
)
|
|
162
|
+
return True
|
|
163
|
+
|
|
164
|
+
def list_sessions(
|
|
165
|
+
self,
|
|
166
|
+
user_id: Optional[str] = None,
|
|
167
|
+
agent_id: Optional[str] = None,
|
|
168
|
+
limit: int = 100,
|
|
169
|
+
offset: int = 0
|
|
170
|
+
) -> List[ConversationSession]:
|
|
171
|
+
conditions = []
|
|
172
|
+
params = {"limit": limit, "offset": offset}
|
|
173
|
+
|
|
174
|
+
if user_id:
|
|
175
|
+
conditions.append("user_id = $user_id")
|
|
176
|
+
params["user_id"] = user_id
|
|
177
|
+
if agent_id:
|
|
178
|
+
conditions.append("agent_id = $agent_id")
|
|
179
|
+
params["agent_id"] = agent_id
|
|
180
|
+
|
|
181
|
+
where = "WHERE " + " AND ".join(conditions) if conditions else ""
|
|
182
|
+
|
|
183
|
+
result = self._run_sync(
|
|
184
|
+
self._client.query(
|
|
185
|
+
f"SELECT * FROM {self.sessions_table} {where} ORDER BY updated_at DESC LIMIT $limit START $offset",
|
|
186
|
+
params
|
|
187
|
+
)
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
if not result or not result[0].get("result"):
|
|
191
|
+
return []
|
|
192
|
+
|
|
193
|
+
return [
|
|
194
|
+
ConversationSession(
|
|
195
|
+
session_id=row["session_id"],
|
|
196
|
+
user_id=row.get("user_id"),
|
|
197
|
+
agent_id=row.get("agent_id"),
|
|
198
|
+
name=row.get("name"),
|
|
199
|
+
state=row.get("state"),
|
|
200
|
+
metadata=row.get("metadata"),
|
|
201
|
+
created_at=row.get("created_at"),
|
|
202
|
+
updated_at=row.get("updated_at"),
|
|
203
|
+
)
|
|
204
|
+
for row in result[0]["result"]
|
|
205
|
+
]
|
|
206
|
+
|
|
207
|
+
def add_message(self, session_id: str, message: ConversationMessage) -> ConversationMessage:
|
|
208
|
+
message.session_id = session_id
|
|
209
|
+
data = {
|
|
210
|
+
"id": message.id,
|
|
211
|
+
"session_id": session_id,
|
|
212
|
+
"role": message.role,
|
|
213
|
+
"content": message.content,
|
|
214
|
+
"tool_calls": message.tool_calls,
|
|
215
|
+
"tool_call_id": message.tool_call_id,
|
|
216
|
+
"metadata": message.metadata,
|
|
217
|
+
"created_at": message.created_at,
|
|
218
|
+
}
|
|
219
|
+
self._run_sync(self._client.create(self.messages_table, data))
|
|
220
|
+
return message
|
|
221
|
+
|
|
222
|
+
def get_messages(
|
|
223
|
+
self,
|
|
224
|
+
session_id: str,
|
|
225
|
+
limit: Optional[int] = None,
|
|
226
|
+
before: Optional[float] = None,
|
|
227
|
+
after: Optional[float] = None
|
|
228
|
+
) -> List[ConversationMessage]:
|
|
229
|
+
conditions = ["session_id = $session_id"]
|
|
230
|
+
params = {"session_id": session_id}
|
|
231
|
+
|
|
232
|
+
if before:
|
|
233
|
+
conditions.append("created_at < $before")
|
|
234
|
+
params["before"] = before
|
|
235
|
+
if after:
|
|
236
|
+
conditions.append("created_at > $after")
|
|
237
|
+
params["after"] = after
|
|
238
|
+
|
|
239
|
+
where = "WHERE " + " AND ".join(conditions)
|
|
240
|
+
limit_clause = f"LIMIT {limit}" if limit else ""
|
|
241
|
+
|
|
242
|
+
result = self._run_sync(
|
|
243
|
+
self._client.query(
|
|
244
|
+
f"SELECT * FROM {self.messages_table} {where} ORDER BY created_at ASC {limit_clause}",
|
|
245
|
+
params
|
|
246
|
+
)
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
if not result or not result[0].get("result"):
|
|
250
|
+
return []
|
|
251
|
+
|
|
252
|
+
return [
|
|
253
|
+
ConversationMessage(
|
|
254
|
+
id=row["id"],
|
|
255
|
+
session_id=row["session_id"],
|
|
256
|
+
role=row["role"],
|
|
257
|
+
content=row.get("content", ""),
|
|
258
|
+
tool_calls=row.get("tool_calls"),
|
|
259
|
+
tool_call_id=row.get("tool_call_id"),
|
|
260
|
+
metadata=row.get("metadata"),
|
|
261
|
+
created_at=row.get("created_at"),
|
|
262
|
+
)
|
|
263
|
+
for row in result[0]["result"]
|
|
264
|
+
]
|
|
265
|
+
|
|
266
|
+
def delete_messages(self, session_id: str, message_ids: Optional[List[str]] = None) -> int:
|
|
267
|
+
if message_ids:
|
|
268
|
+
self._run_sync(
|
|
269
|
+
self._client.query(
|
|
270
|
+
f"DELETE FROM {self.messages_table} WHERE session_id = $sid AND id IN $ids",
|
|
271
|
+
{"sid": session_id, "ids": message_ids}
|
|
272
|
+
)
|
|
273
|
+
)
|
|
274
|
+
return len(message_ids)
|
|
275
|
+
else:
|
|
276
|
+
self._run_sync(
|
|
277
|
+
self._client.query(
|
|
278
|
+
f"DELETE FROM {self.messages_table} WHERE session_id = $sid",
|
|
279
|
+
{"sid": session_id}
|
|
280
|
+
)
|
|
281
|
+
)
|
|
282
|
+
return -1
|
|
283
|
+
|
|
284
|
+
def close(self) -> None:
|
|
285
|
+
if self._client:
|
|
286
|
+
self._run_sync(self._client.close())
|
|
287
|
+
self._client = None
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Factory functions for creating store instances.
|
|
3
|
+
|
|
4
|
+
Provides lazy loading of backend implementations to avoid importing
|
|
5
|
+
unused dependencies.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from typing import Any, Dict, Optional
|
|
10
|
+
|
|
11
|
+
from .config import PersistenceConfig
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def create_conversation_store(
|
|
17
|
+
backend: str,
|
|
18
|
+
url: Optional[str] = None,
|
|
19
|
+
**options: Any
|
|
20
|
+
):
|
|
21
|
+
"""
|
|
22
|
+
Create a ConversationStore instance.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
backend: Backend type (postgres, mysql, sqlite, singlestore, supabase, surrealdb)
|
|
26
|
+
url: Connection URL
|
|
27
|
+
**options: Backend-specific options
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
ConversationStore instance
|
|
31
|
+
|
|
32
|
+
Example:
|
|
33
|
+
store = create_conversation_store(
|
|
34
|
+
"postgres",
|
|
35
|
+
url="postgresql://localhost:5432/praisonai"
|
|
36
|
+
)
|
|
37
|
+
"""
|
|
38
|
+
backend = backend.lower()
|
|
39
|
+
|
|
40
|
+
if backend == "postgres":
|
|
41
|
+
from .conversation.postgres import PostgresConversationStore
|
|
42
|
+
return PostgresConversationStore(url=url, **options)
|
|
43
|
+
|
|
44
|
+
elif backend == "mysql":
|
|
45
|
+
from .conversation.mysql import MySQLConversationStore
|
|
46
|
+
return MySQLConversationStore(url=url, **options)
|
|
47
|
+
|
|
48
|
+
elif backend == "sqlite":
|
|
49
|
+
from .conversation.sqlite import SQLiteConversationStore
|
|
50
|
+
path = url or options.pop("path", None)
|
|
51
|
+
return SQLiteConversationStore(path=path, **options)
|
|
52
|
+
|
|
53
|
+
elif backend == "singlestore":
|
|
54
|
+
from .conversation.singlestore import SingleStoreConversationStore
|
|
55
|
+
return SingleStoreConversationStore(url=url, **options)
|
|
56
|
+
|
|
57
|
+
elif backend == "supabase":
|
|
58
|
+
from .conversation.supabase import SupabaseConversationStore
|
|
59
|
+
return SupabaseConversationStore(url=url, **options)
|
|
60
|
+
|
|
61
|
+
elif backend == "surrealdb":
|
|
62
|
+
from .conversation.surrealdb import SurrealDBConversationStore
|
|
63
|
+
return SurrealDBConversationStore(url=url, **options)
|
|
64
|
+
|
|
65
|
+
elif backend == "json":
|
|
66
|
+
from .conversation.json_store import JSONConversationStore
|
|
67
|
+
path = url or options.pop("path", None) or "./praisonai_conversations"
|
|
68
|
+
return JSONConversationStore(path=path, **options)
|
|
69
|
+
|
|
70
|
+
elif backend in ("async_postgres", "asyncpg", "postgres_async"):
|
|
71
|
+
from .conversation.async_postgres import AsyncPostgresConversationStore
|
|
72
|
+
return AsyncPostgresConversationStore(url=url, **options)
|
|
73
|
+
|
|
74
|
+
elif backend in ("async_sqlite", "aiosqlite", "sqlite_async"):
|
|
75
|
+
from .conversation.async_sqlite import AsyncSQLiteConversationStore
|
|
76
|
+
path = url or options.pop("path", None)
|
|
77
|
+
return AsyncSQLiteConversationStore(path=path, **options)
|
|
78
|
+
|
|
79
|
+
elif backend in ("async_mysql", "aiomysql", "mysql_async"):
|
|
80
|
+
from .conversation.async_mysql import AsyncMySQLConversationStore
|
|
81
|
+
return AsyncMySQLConversationStore(url=url, **options)
|
|
82
|
+
|
|
83
|
+
else:
|
|
84
|
+
raise ValueError(
|
|
85
|
+
f"Unknown conversation store backend: {backend}. "
|
|
86
|
+
f"Supported: postgres, mysql, sqlite, json, singlestore, supabase, surrealdb, "
|
|
87
|
+
f"async_postgres, async_sqlite, async_mysql"
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def create_knowledge_store(
|
|
92
|
+
backend: str,
|
|
93
|
+
url: Optional[str] = None,
|
|
94
|
+
**options: Any
|
|
95
|
+
):
|
|
96
|
+
"""
|
|
97
|
+
Create a KnowledgeStore instance.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
backend: Backend type (qdrant, pinecone, chroma, weaviate, lancedb, milvus, pgvector, redis, cassandra, clickhouse)
|
|
101
|
+
url: Connection URL
|
|
102
|
+
**options: Backend-specific options
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
KnowledgeStore instance
|
|
106
|
+
|
|
107
|
+
Example:
|
|
108
|
+
store = create_knowledge_store(
|
|
109
|
+
"qdrant",
|
|
110
|
+
url="http://localhost:6333"
|
|
111
|
+
)
|
|
112
|
+
"""
|
|
113
|
+
backend = backend.lower()
|
|
114
|
+
|
|
115
|
+
if backend == "qdrant":
|
|
116
|
+
from .knowledge.qdrant import QdrantKnowledgeStore
|
|
117
|
+
return QdrantKnowledgeStore(url=url, **options)
|
|
118
|
+
|
|
119
|
+
elif backend == "pinecone":
|
|
120
|
+
from .knowledge.pinecone import PineconeKnowledgeStore
|
|
121
|
+
return PineconeKnowledgeStore(**options)
|
|
122
|
+
|
|
123
|
+
elif backend == "chroma":
|
|
124
|
+
from .knowledge.chroma import ChromaKnowledgeStore
|
|
125
|
+
path = url or options.pop("path", None)
|
|
126
|
+
return ChromaKnowledgeStore(path=path, **options)
|
|
127
|
+
|
|
128
|
+
elif backend == "weaviate":
|
|
129
|
+
from .knowledge.weaviate import WeaviateKnowledgeStore
|
|
130
|
+
return WeaviateKnowledgeStore(url=url, **options)
|
|
131
|
+
|
|
132
|
+
elif backend == "lancedb":
|
|
133
|
+
from .knowledge.lancedb import LanceDBKnowledgeStore
|
|
134
|
+
path = url or options.pop("path", None)
|
|
135
|
+
return LanceDBKnowledgeStore(path=path, **options)
|
|
136
|
+
|
|
137
|
+
elif backend == "milvus":
|
|
138
|
+
from .knowledge.milvus import MilvusKnowledgeStore
|
|
139
|
+
return MilvusKnowledgeStore(url=url, **options)
|
|
140
|
+
|
|
141
|
+
elif backend == "pgvector":
|
|
142
|
+
from .knowledge.pgvector import PGVectorKnowledgeStore
|
|
143
|
+
return PGVectorKnowledgeStore(url=url, **options)
|
|
144
|
+
|
|
145
|
+
elif backend == "redis":
|
|
146
|
+
from .knowledge.redis_vector import RedisVectorKnowledgeStore
|
|
147
|
+
return RedisVectorKnowledgeStore(url=url, **options)
|
|
148
|
+
|
|
149
|
+
elif backend == "cassandra":
|
|
150
|
+
from .knowledge.cassandra import CassandraKnowledgeStore
|
|
151
|
+
return CassandraKnowledgeStore(**options)
|
|
152
|
+
|
|
153
|
+
elif backend == "clickhouse":
|
|
154
|
+
from .knowledge.clickhouse import ClickHouseKnowledgeStore
|
|
155
|
+
return ClickHouseKnowledgeStore(**options)
|
|
156
|
+
|
|
157
|
+
elif backend == "couchbase":
|
|
158
|
+
from .knowledge.couchbase import CouchbaseKnowledgeStore
|
|
159
|
+
return CouchbaseKnowledgeStore(**options)
|
|
160
|
+
|
|
161
|
+
elif backend in ("mongodb_vector", "mongodb_atlas", "mongo_vector"):
|
|
162
|
+
from .knowledge.mongodb_vector import MongoDBVectorKnowledgeStore
|
|
163
|
+
return MongoDBVectorKnowledgeStore(url=url, **options)
|
|
164
|
+
|
|
165
|
+
elif backend in ("singlestore_vector", "singlestore_v"):
|
|
166
|
+
from .knowledge.singlestore_vector import SingleStoreVectorKnowledgeStore
|
|
167
|
+
return SingleStoreVectorKnowledgeStore(url=url, **options)
|
|
168
|
+
|
|
169
|
+
elif backend in ("surrealdb_vector", "surrealdb_v"):
|
|
170
|
+
from .knowledge.surrealdb_vector import SurrealDBVectorKnowledgeStore
|
|
171
|
+
return SurrealDBVectorKnowledgeStore(url=url, **options)
|
|
172
|
+
|
|
173
|
+
elif backend in ("upstash_vector", "upstash_v"):
|
|
174
|
+
from .knowledge.upstash_vector import UpstashVectorKnowledgeStore
|
|
175
|
+
return UpstashVectorKnowledgeStore(url=url, **options)
|
|
176
|
+
|
|
177
|
+
elif backend == "lightrag":
|
|
178
|
+
from .knowledge.lightrag_adapter import LightRAGKnowledgeStore
|
|
179
|
+
return LightRAGKnowledgeStore(**options)
|
|
180
|
+
|
|
181
|
+
elif backend in ("langchain", "langchain_adapter"):
|
|
182
|
+
from .knowledge.langchain_adapter import LangChainKnowledgeStore
|
|
183
|
+
return LangChainKnowledgeStore(**options)
|
|
184
|
+
|
|
185
|
+
elif backend in ("llamaindex", "llama_index", "llamaindex_adapter"):
|
|
186
|
+
from .knowledge.llamaindex_adapter import LlamaIndexKnowledgeStore
|
|
187
|
+
return LlamaIndexKnowledgeStore(**options)
|
|
188
|
+
|
|
189
|
+
elif backend in ("cosmosdb", "cosmos", "azure_cosmos", "cosmosdb_vector"):
|
|
190
|
+
from .knowledge.cosmosdb_vector import CosmosDBVectorKnowledgeStore
|
|
191
|
+
return CosmosDBVectorKnowledgeStore(**options)
|
|
192
|
+
|
|
193
|
+
else:
|
|
194
|
+
raise ValueError(
|
|
195
|
+
f"Unknown knowledge store backend: {backend}. "
|
|
196
|
+
f"Supported: qdrant, pinecone, chroma, weaviate, lancedb, milvus, pgvector, redis, cassandra, clickhouse, "
|
|
197
|
+
f"couchbase, mongodb_vector, singlestore_vector, surrealdb_vector, upstash_vector, lightrag, langchain, llamaindex, cosmosdb"
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def create_state_store(
|
|
202
|
+
backend: str,
|
|
203
|
+
url: Optional[str] = None,
|
|
204
|
+
**options: Any
|
|
205
|
+
):
|
|
206
|
+
"""
|
|
207
|
+
Create a StateStore instance.
|
|
208
|
+
|
|
209
|
+
Args:
|
|
210
|
+
backend: Backend type (redis, dynamodb, firestore, mongodb, upstash, memory)
|
|
211
|
+
url: Connection URL
|
|
212
|
+
**options: Backend-specific options
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
StateStore instance
|
|
216
|
+
|
|
217
|
+
Example:
|
|
218
|
+
store = create_state_store(
|
|
219
|
+
"redis",
|
|
220
|
+
url="redis://localhost:6379"
|
|
221
|
+
)
|
|
222
|
+
"""
|
|
223
|
+
backend = backend.lower()
|
|
224
|
+
|
|
225
|
+
if backend == "redis":
|
|
226
|
+
from .state.redis import RedisStateStore
|
|
227
|
+
return RedisStateStore(url=url, **options)
|
|
228
|
+
|
|
229
|
+
elif backend == "dynamodb":
|
|
230
|
+
from .state.dynamodb import DynamoDBStateStore
|
|
231
|
+
return DynamoDBStateStore(**options)
|
|
232
|
+
|
|
233
|
+
elif backend == "firestore":
|
|
234
|
+
from .state.firestore import FirestoreStateStore
|
|
235
|
+
return FirestoreStateStore(**options)
|
|
236
|
+
|
|
237
|
+
elif backend == "mongodb":
|
|
238
|
+
from .state.mongodb import MongoDBStateStore
|
|
239
|
+
return MongoDBStateStore(url=url, **options)
|
|
240
|
+
|
|
241
|
+
elif backend == "upstash":
|
|
242
|
+
from .state.upstash import UpstashStateStore
|
|
243
|
+
return UpstashStateStore(url=url, **options)
|
|
244
|
+
|
|
245
|
+
elif backend == "memory":
|
|
246
|
+
from .state.memory import MemoryStateStore
|
|
247
|
+
return MemoryStateStore(**options)
|
|
248
|
+
|
|
249
|
+
elif backend == "gcs":
|
|
250
|
+
from .state.gcs import GCSStateStore
|
|
251
|
+
bucket = options.pop("bucket_name", None) or options.pop("bucket", None)
|
|
252
|
+
if not bucket:
|
|
253
|
+
raise ValueError("GCS state store requires 'bucket_name' option")
|
|
254
|
+
return GCSStateStore(bucket_name=bucket, **options)
|
|
255
|
+
|
|
256
|
+
elif backend in ("async_mongodb", "motor", "mongodb_async"):
|
|
257
|
+
from .state.async_mongodb import AsyncMongoDBStateStore
|
|
258
|
+
return AsyncMongoDBStateStore(url=url, **options)
|
|
259
|
+
|
|
260
|
+
else:
|
|
261
|
+
raise ValueError(
|
|
262
|
+
f"Unknown state store backend: {backend}. "
|
|
263
|
+
f"Supported: redis, dynamodb, firestore, mongodb, upstash, memory, gcs, async_mongodb"
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def create_stores_from_config(config: PersistenceConfig) -> Dict[str, Any]:
|
|
268
|
+
"""
|
|
269
|
+
Create all configured stores from a PersistenceConfig.
|
|
270
|
+
|
|
271
|
+
Returns:
|
|
272
|
+
Dict with keys: conversation, knowledge, state (values may be None)
|
|
273
|
+
"""
|
|
274
|
+
stores = {
|
|
275
|
+
"conversation": None,
|
|
276
|
+
"knowledge": None,
|
|
277
|
+
"state": None,
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if config.conversation_store:
|
|
281
|
+
stores["conversation"] = create_conversation_store(
|
|
282
|
+
config.conversation_store,
|
|
283
|
+
url=config.conversation_url,
|
|
284
|
+
**config.conversation_options
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
if config.knowledge_store:
|
|
288
|
+
stores["knowledge"] = create_knowledge_store(
|
|
289
|
+
config.knowledge_store,
|
|
290
|
+
url=config.knowledge_url,
|
|
291
|
+
**config.knowledge_options
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
if config.state_store:
|
|
295
|
+
stores["state"] = create_state_store(
|
|
296
|
+
config.state_store,
|
|
297
|
+
url=config.state_url,
|
|
298
|
+
**config.state_options
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
return stores
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Agent hooks for automatic persistence integration.
|
|
3
|
+
|
|
4
|
+
Provides wrapper functions to add persistence capabilities to PraisonAI agents
|
|
5
|
+
without modifying the core SDK.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .agent_hooks import (
|
|
9
|
+
wrap_agent_with_persistence,
|
|
10
|
+
PersistentAgent,
|
|
11
|
+
create_persistent_session,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"wrap_agent_with_persistence",
|
|
16
|
+
"PersistentAgent",
|
|
17
|
+
"create_persistent_session",
|
|
18
|
+
]
|