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,256 @@
|
|
|
1
|
+
"""
|
|
2
|
+
LlamaIndex VectorStore adapter implementation of KnowledgeStore.
|
|
3
|
+
|
|
4
|
+
Wraps any LlamaIndex VectorStore for use with PraisonAI.
|
|
5
|
+
|
|
6
|
+
Requires: llama-index-core
|
|
7
|
+
Install: pip install llama-index-core
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import logging
|
|
11
|
+
from typing import Any, Dict, List, Optional
|
|
12
|
+
|
|
13
|
+
from .base import KnowledgeStore, KnowledgeDocument
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class LlamaIndexKnowledgeStore(KnowledgeStore):
|
|
19
|
+
"""
|
|
20
|
+
LlamaIndex VectorStore adapter for knowledge/RAG.
|
|
21
|
+
|
|
22
|
+
Wraps any LlamaIndex VectorStore for use with PraisonAI's interface.
|
|
23
|
+
|
|
24
|
+
Example:
|
|
25
|
+
from llama_index.vector_stores.chroma import ChromaVectorStore
|
|
26
|
+
|
|
27
|
+
li_store = ChromaVectorStore(chroma_collection=collection)
|
|
28
|
+
store = LlamaIndexKnowledgeStore(vector_store=li_store)
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
vector_store: Any = None,
|
|
34
|
+
vector_store_cls: Optional[str] = None,
|
|
35
|
+
vector_store_kwargs: Optional[Dict[str, Any]] = None,
|
|
36
|
+
):
|
|
37
|
+
"""
|
|
38
|
+
Initialize LlamaIndex adapter.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
vector_store: Pre-initialized LlamaIndex VectorStore instance
|
|
42
|
+
vector_store_cls: Class name to import (e.g., "llama_index.vector_stores.chroma.ChromaVectorStore")
|
|
43
|
+
vector_store_kwargs: Kwargs for vector_store initialization
|
|
44
|
+
"""
|
|
45
|
+
self._vector_store = vector_store
|
|
46
|
+
self._vector_store_cls = vector_store_cls
|
|
47
|
+
self._vector_store_kwargs = vector_store_kwargs or {}
|
|
48
|
+
self._initialized = vector_store is not None
|
|
49
|
+
|
|
50
|
+
def _init_client(self):
|
|
51
|
+
"""Initialize vector store lazily."""
|
|
52
|
+
if self._initialized:
|
|
53
|
+
return
|
|
54
|
+
|
|
55
|
+
if not self._vector_store_cls:
|
|
56
|
+
raise ValueError(
|
|
57
|
+
"Either vector_store or vector_store_cls must be provided"
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# Dynamic import of vector store class
|
|
61
|
+
parts = self._vector_store_cls.rsplit(".", 1)
|
|
62
|
+
if len(parts) == 2:
|
|
63
|
+
module_name, class_name = parts
|
|
64
|
+
import importlib
|
|
65
|
+
module = importlib.import_module(module_name)
|
|
66
|
+
cls = getattr(module, class_name)
|
|
67
|
+
self._vector_store = cls(**self._vector_store_kwargs)
|
|
68
|
+
else:
|
|
69
|
+
raise ValueError(f"Invalid vector_store_cls: {self._vector_store_cls}")
|
|
70
|
+
|
|
71
|
+
self._initialized = True
|
|
72
|
+
|
|
73
|
+
def create_collection(
|
|
74
|
+
self,
|
|
75
|
+
name: str,
|
|
76
|
+
dimension: int = 1536,
|
|
77
|
+
distance: str = "cosine",
|
|
78
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
79
|
+
) -> None:
|
|
80
|
+
"""Create collection (handled by underlying vector store)."""
|
|
81
|
+
self._init_client()
|
|
82
|
+
logger.info("Collection creation handled by LlamaIndex vector store")
|
|
83
|
+
|
|
84
|
+
def delete_collection(self, name: str) -> bool:
|
|
85
|
+
"""Delete collection."""
|
|
86
|
+
self._init_client()
|
|
87
|
+
try:
|
|
88
|
+
if hasattr(self._vector_store, 'delete'):
|
|
89
|
+
self._vector_store.delete(delete_all=True)
|
|
90
|
+
return True
|
|
91
|
+
logger.warning("Underlying vector store doesn't support delete")
|
|
92
|
+
return False
|
|
93
|
+
except Exception as e:
|
|
94
|
+
logger.error(f"Failed to delete collection: {e}")
|
|
95
|
+
return False
|
|
96
|
+
|
|
97
|
+
def collection_exists(self, name: str) -> bool:
|
|
98
|
+
"""Check if collection exists."""
|
|
99
|
+
self._init_client()
|
|
100
|
+
return self._vector_store is not None
|
|
101
|
+
|
|
102
|
+
def list_collections(self) -> List[str]:
|
|
103
|
+
"""List collections."""
|
|
104
|
+
self._init_client()
|
|
105
|
+
return ["default"]
|
|
106
|
+
|
|
107
|
+
def insert(
|
|
108
|
+
self,
|
|
109
|
+
collection: str,
|
|
110
|
+
documents: List[KnowledgeDocument]
|
|
111
|
+
) -> List[str]:
|
|
112
|
+
"""Insert documents."""
|
|
113
|
+
self._init_client()
|
|
114
|
+
|
|
115
|
+
try:
|
|
116
|
+
from llama_index.core.schema import TextNode
|
|
117
|
+
except ImportError:
|
|
118
|
+
raise ImportError(
|
|
119
|
+
"llama-index-core is required. Install with: pip install llama-index-core"
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
nodes = []
|
|
123
|
+
ids = []
|
|
124
|
+
for doc in documents:
|
|
125
|
+
node = TextNode(
|
|
126
|
+
text=doc.content,
|
|
127
|
+
id_=doc.id,
|
|
128
|
+
metadata={
|
|
129
|
+
**(doc.metadata or {}),
|
|
130
|
+
"content_hash": doc.content_hash,
|
|
131
|
+
"created_at": doc.created_at,
|
|
132
|
+
},
|
|
133
|
+
embedding=doc.embedding
|
|
134
|
+
)
|
|
135
|
+
nodes.append(node)
|
|
136
|
+
ids.append(doc.id)
|
|
137
|
+
|
|
138
|
+
if hasattr(self._vector_store, 'add'):
|
|
139
|
+
self._vector_store.add(nodes)
|
|
140
|
+
else:
|
|
141
|
+
logger.warning("Vector store doesn't support add")
|
|
142
|
+
|
|
143
|
+
return ids
|
|
144
|
+
|
|
145
|
+
def upsert(
|
|
146
|
+
self,
|
|
147
|
+
collection: str,
|
|
148
|
+
documents: List[KnowledgeDocument]
|
|
149
|
+
) -> List[str]:
|
|
150
|
+
"""Upsert documents."""
|
|
151
|
+
return self.insert(collection, documents)
|
|
152
|
+
|
|
153
|
+
def search(
|
|
154
|
+
self,
|
|
155
|
+
collection: str,
|
|
156
|
+
query_embedding: List[float],
|
|
157
|
+
limit: int = 5,
|
|
158
|
+
filters: Optional[Dict[str, Any]] = None,
|
|
159
|
+
score_threshold: Optional[float] = None
|
|
160
|
+
) -> List[KnowledgeDocument]:
|
|
161
|
+
"""Search for similar documents."""
|
|
162
|
+
self._init_client()
|
|
163
|
+
|
|
164
|
+
try:
|
|
165
|
+
from llama_index.core.vector_stores import VectorStoreQuery
|
|
166
|
+
except ImportError:
|
|
167
|
+
raise ImportError(
|
|
168
|
+
"llama-index-core is required. Install with: pip install llama-index-core"
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
try:
|
|
172
|
+
query = VectorStoreQuery(
|
|
173
|
+
query_embedding=query_embedding,
|
|
174
|
+
similarity_top_k=limit,
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
result = self._vector_store.query(query)
|
|
178
|
+
|
|
179
|
+
documents = []
|
|
180
|
+
for i, node in enumerate(result.nodes or []):
|
|
181
|
+
score = result.similarities[i] if result.similarities else None
|
|
182
|
+
if score_threshold and score and score < score_threshold:
|
|
183
|
+
continue
|
|
184
|
+
|
|
185
|
+
metadata = node.metadata or {}
|
|
186
|
+
if score:
|
|
187
|
+
metadata["score"] = score
|
|
188
|
+
|
|
189
|
+
documents.append(KnowledgeDocument(
|
|
190
|
+
id=node.node_id or node.id_,
|
|
191
|
+
content=node.text or node.get_content(),
|
|
192
|
+
embedding=node.embedding,
|
|
193
|
+
metadata=metadata,
|
|
194
|
+
content_hash=metadata.get("content_hash"),
|
|
195
|
+
created_at=metadata.get("created_at", 0)
|
|
196
|
+
))
|
|
197
|
+
|
|
198
|
+
return documents
|
|
199
|
+
except Exception as e:
|
|
200
|
+
logger.error(f"Search failed: {e}")
|
|
201
|
+
return []
|
|
202
|
+
|
|
203
|
+
def get(
|
|
204
|
+
self,
|
|
205
|
+
collection: str,
|
|
206
|
+
ids: List[str]
|
|
207
|
+
) -> List[KnowledgeDocument]:
|
|
208
|
+
"""Get documents by IDs."""
|
|
209
|
+
self._init_client()
|
|
210
|
+
|
|
211
|
+
documents = []
|
|
212
|
+
for doc_id in ids:
|
|
213
|
+
try:
|
|
214
|
+
if hasattr(self._vector_store, 'get'):
|
|
215
|
+
node = self._vector_store.get(doc_id)
|
|
216
|
+
if node:
|
|
217
|
+
metadata = node.metadata or {}
|
|
218
|
+
documents.append(KnowledgeDocument(
|
|
219
|
+
id=node.node_id or node.id_,
|
|
220
|
+
content=node.text or node.get_content(),
|
|
221
|
+
embedding=node.embedding,
|
|
222
|
+
metadata=metadata
|
|
223
|
+
))
|
|
224
|
+
except Exception as e:
|
|
225
|
+
logger.warning(f"Get by ID failed for {doc_id}: {e}")
|
|
226
|
+
|
|
227
|
+
return documents
|
|
228
|
+
|
|
229
|
+
def delete(
|
|
230
|
+
self,
|
|
231
|
+
collection: str,
|
|
232
|
+
ids: Optional[List[str]] = None,
|
|
233
|
+
filters: Optional[Dict[str, Any]] = None
|
|
234
|
+
) -> int:
|
|
235
|
+
"""Delete documents."""
|
|
236
|
+
self._init_client()
|
|
237
|
+
|
|
238
|
+
if ids and hasattr(self._vector_store, 'delete'):
|
|
239
|
+
try:
|
|
240
|
+
self._vector_store.delete(ref_doc_id=ids[0] if len(ids) == 1 else None)
|
|
241
|
+
return len(ids)
|
|
242
|
+
except Exception as e:
|
|
243
|
+
logger.error(f"Delete failed: {e}")
|
|
244
|
+
|
|
245
|
+
return 0
|
|
246
|
+
|
|
247
|
+
def count(self, collection: str) -> int:
|
|
248
|
+
"""Count documents."""
|
|
249
|
+
self._init_client()
|
|
250
|
+
logger.warning("LlamaIndex vector stores don't typically support counting")
|
|
251
|
+
return -1
|
|
252
|
+
|
|
253
|
+
def close(self) -> None:
|
|
254
|
+
"""Close the client."""
|
|
255
|
+
self._vector_store = None
|
|
256
|
+
self._initialized = False
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Milvus implementation of KnowledgeStore.
|
|
3
|
+
|
|
4
|
+
Requires: pymilvus
|
|
5
|
+
Install: pip install pymilvus
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from typing import Any, Dict, List, Optional
|
|
10
|
+
|
|
11
|
+
from .base import KnowledgeStore, KnowledgeDocument
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class MilvusKnowledgeStore(KnowledgeStore):
|
|
17
|
+
"""
|
|
18
|
+
Milvus-based knowledge store for vector search.
|
|
19
|
+
|
|
20
|
+
Example:
|
|
21
|
+
store = MilvusKnowledgeStore(
|
|
22
|
+
host="localhost",
|
|
23
|
+
port=19530
|
|
24
|
+
)
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
url: Optional[str] = None,
|
|
30
|
+
host: str = "localhost",
|
|
31
|
+
port: int = 19530,
|
|
32
|
+
token: Optional[str] = None,
|
|
33
|
+
db_name: str = "default",
|
|
34
|
+
):
|
|
35
|
+
try:
|
|
36
|
+
from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType, utility
|
|
37
|
+
except ImportError:
|
|
38
|
+
raise ImportError(
|
|
39
|
+
"pymilvus is required for Milvus support. "
|
|
40
|
+
"Install with: pip install pymilvus"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
self._pymilvus = {
|
|
44
|
+
"connections": connections,
|
|
45
|
+
"Collection": Collection,
|
|
46
|
+
"FieldSchema": FieldSchema,
|
|
47
|
+
"CollectionSchema": CollectionSchema,
|
|
48
|
+
"DataType": DataType,
|
|
49
|
+
"utility": utility,
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if url:
|
|
53
|
+
# Parse milvus://host:port
|
|
54
|
+
from urllib.parse import urlparse
|
|
55
|
+
parsed = urlparse(url)
|
|
56
|
+
host = parsed.hostname or host
|
|
57
|
+
port = parsed.port or port
|
|
58
|
+
|
|
59
|
+
connections.connect(
|
|
60
|
+
alias="default",
|
|
61
|
+
host=host,
|
|
62
|
+
port=port,
|
|
63
|
+
token=token,
|
|
64
|
+
db_name=db_name,
|
|
65
|
+
)
|
|
66
|
+
logger.info(f"Connected to Milvus at {host}:{port}")
|
|
67
|
+
|
|
68
|
+
def create_collection(
|
|
69
|
+
self,
|
|
70
|
+
name: str,
|
|
71
|
+
dimension: int,
|
|
72
|
+
distance: str = "cosine",
|
|
73
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
74
|
+
) -> None:
|
|
75
|
+
"""Create a new collection."""
|
|
76
|
+
FieldSchema = self._pymilvus["FieldSchema"]
|
|
77
|
+
CollectionSchema = self._pymilvus["CollectionSchema"]
|
|
78
|
+
DataType = self._pymilvus["DataType"]
|
|
79
|
+
Collection = self._pymilvus["Collection"]
|
|
80
|
+
|
|
81
|
+
fields = [
|
|
82
|
+
FieldSchema(name="id", dtype=DataType.VARCHAR, is_primary=True, max_length=256),
|
|
83
|
+
FieldSchema(name="content", dtype=DataType.VARCHAR, max_length=65535),
|
|
84
|
+
FieldSchema(name="content_hash", dtype=DataType.VARCHAR, max_length=64),
|
|
85
|
+
FieldSchema(name="created_at", dtype=DataType.DOUBLE),
|
|
86
|
+
FieldSchema(name="vector", dtype=DataType.FLOAT_VECTOR, dim=dimension),
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
schema = CollectionSchema(fields=fields, description="PraisonAI knowledge store")
|
|
90
|
+
collection = Collection(name=name, schema=schema)
|
|
91
|
+
|
|
92
|
+
# Create index
|
|
93
|
+
metric_map = {"cosine": "COSINE", "euclidean": "L2", "dot": "IP"}
|
|
94
|
+
index_params = {
|
|
95
|
+
"metric_type": metric_map.get(distance, "COSINE"),
|
|
96
|
+
"index_type": "HNSW",
|
|
97
|
+
"params": {"M": 16, "efConstruction": 256}
|
|
98
|
+
}
|
|
99
|
+
collection.create_index(field_name="vector", index_params=index_params)
|
|
100
|
+
logger.info(f"Created Milvus collection: {name}")
|
|
101
|
+
|
|
102
|
+
def delete_collection(self, name: str) -> bool:
|
|
103
|
+
"""Delete a collection."""
|
|
104
|
+
utility = self._pymilvus["utility"]
|
|
105
|
+
try:
|
|
106
|
+
utility.drop_collection(name)
|
|
107
|
+
return True
|
|
108
|
+
except Exception as e:
|
|
109
|
+
logger.warning(f"Failed to delete collection {name}: {e}")
|
|
110
|
+
return False
|
|
111
|
+
|
|
112
|
+
def collection_exists(self, name: str) -> bool:
|
|
113
|
+
"""Check if a collection exists."""
|
|
114
|
+
utility = self._pymilvus["utility"]
|
|
115
|
+
return utility.has_collection(name)
|
|
116
|
+
|
|
117
|
+
def list_collections(self) -> List[str]:
|
|
118
|
+
"""List all collections."""
|
|
119
|
+
utility = self._pymilvus["utility"]
|
|
120
|
+
return utility.list_collections()
|
|
121
|
+
|
|
122
|
+
def insert(
|
|
123
|
+
self,
|
|
124
|
+
collection: str,
|
|
125
|
+
documents: List[KnowledgeDocument]
|
|
126
|
+
) -> List[str]:
|
|
127
|
+
"""Insert documents."""
|
|
128
|
+
Collection = self._pymilvus["Collection"]
|
|
129
|
+
col = Collection(collection)
|
|
130
|
+
col.load()
|
|
131
|
+
|
|
132
|
+
data = [
|
|
133
|
+
[doc.id for doc in documents],
|
|
134
|
+
[doc.content for doc in documents],
|
|
135
|
+
[doc.content_hash or "" for doc in documents],
|
|
136
|
+
[doc.created_at for doc in documents],
|
|
137
|
+
[doc.embedding for doc in documents],
|
|
138
|
+
]
|
|
139
|
+
|
|
140
|
+
col.insert(data)
|
|
141
|
+
col.flush()
|
|
142
|
+
return [doc.id for doc in documents]
|
|
143
|
+
|
|
144
|
+
def upsert(
|
|
145
|
+
self,
|
|
146
|
+
collection: str,
|
|
147
|
+
documents: List[KnowledgeDocument]
|
|
148
|
+
) -> List[str]:
|
|
149
|
+
"""Insert or update documents."""
|
|
150
|
+
Collection = self._pymilvus["Collection"]
|
|
151
|
+
col = Collection(collection)
|
|
152
|
+
col.load()
|
|
153
|
+
|
|
154
|
+
data = [
|
|
155
|
+
[doc.id for doc in documents],
|
|
156
|
+
[doc.content for doc in documents],
|
|
157
|
+
[doc.content_hash or "" for doc in documents],
|
|
158
|
+
[doc.created_at for doc in documents],
|
|
159
|
+
[doc.embedding for doc in documents],
|
|
160
|
+
]
|
|
161
|
+
|
|
162
|
+
col.upsert(data)
|
|
163
|
+
col.flush()
|
|
164
|
+
return [doc.id for doc in documents]
|
|
165
|
+
|
|
166
|
+
def search(
|
|
167
|
+
self,
|
|
168
|
+
collection: str,
|
|
169
|
+
query_embedding: List[float],
|
|
170
|
+
limit: int = 5,
|
|
171
|
+
filters: Optional[Dict[str, Any]] = None,
|
|
172
|
+
score_threshold: Optional[float] = None
|
|
173
|
+
) -> List[KnowledgeDocument]:
|
|
174
|
+
"""Search for similar documents."""
|
|
175
|
+
Collection = self._pymilvus["Collection"]
|
|
176
|
+
col = Collection(collection)
|
|
177
|
+
col.load()
|
|
178
|
+
|
|
179
|
+
search_params = {"metric_type": "COSINE", "params": {"ef": 64}}
|
|
180
|
+
|
|
181
|
+
expr = None
|
|
182
|
+
if filters:
|
|
183
|
+
conditions = [f'{k} == "{v}"' for k, v in filters.items()]
|
|
184
|
+
expr = " and ".join(conditions)
|
|
185
|
+
|
|
186
|
+
results = col.search(
|
|
187
|
+
data=[query_embedding],
|
|
188
|
+
anns_field="vector",
|
|
189
|
+
param=search_params,
|
|
190
|
+
limit=limit,
|
|
191
|
+
expr=expr,
|
|
192
|
+
output_fields=["id", "content", "content_hash", "created_at"],
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
documents = []
|
|
196
|
+
for hits in results:
|
|
197
|
+
for hit in hits:
|
|
198
|
+
if score_threshold and hit.score < score_threshold:
|
|
199
|
+
continue
|
|
200
|
+
|
|
201
|
+
doc = KnowledgeDocument(
|
|
202
|
+
id=hit.entity.get("id"),
|
|
203
|
+
content=hit.entity.get("content", ""),
|
|
204
|
+
embedding=None,
|
|
205
|
+
metadata={},
|
|
206
|
+
content_hash=hit.entity.get("content_hash"),
|
|
207
|
+
created_at=hit.entity.get("created_at", 0),
|
|
208
|
+
)
|
|
209
|
+
documents.append(doc)
|
|
210
|
+
|
|
211
|
+
return documents
|
|
212
|
+
|
|
213
|
+
def get(
|
|
214
|
+
self,
|
|
215
|
+
collection: str,
|
|
216
|
+
ids: List[str]
|
|
217
|
+
) -> List[KnowledgeDocument]:
|
|
218
|
+
"""Get documents by IDs."""
|
|
219
|
+
Collection = self._pymilvus["Collection"]
|
|
220
|
+
col = Collection(collection)
|
|
221
|
+
col.load()
|
|
222
|
+
|
|
223
|
+
id_list = ", ".join([f'"{i}"' for i in ids])
|
|
224
|
+
expr = f"id in [{id_list}]"
|
|
225
|
+
|
|
226
|
+
results = col.query(
|
|
227
|
+
expr=expr,
|
|
228
|
+
output_fields=["id", "content", "content_hash", "created_at", "vector"],
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
documents = []
|
|
232
|
+
for row in results:
|
|
233
|
+
doc = KnowledgeDocument(
|
|
234
|
+
id=row["id"],
|
|
235
|
+
content=row.get("content", ""),
|
|
236
|
+
embedding=row.get("vector"),
|
|
237
|
+
metadata={},
|
|
238
|
+
content_hash=row.get("content_hash"),
|
|
239
|
+
created_at=row.get("created_at", 0),
|
|
240
|
+
)
|
|
241
|
+
documents.append(doc)
|
|
242
|
+
|
|
243
|
+
return documents
|
|
244
|
+
|
|
245
|
+
def delete(
|
|
246
|
+
self,
|
|
247
|
+
collection: str,
|
|
248
|
+
ids: Optional[List[str]] = None,
|
|
249
|
+
filters: Optional[Dict[str, Any]] = None
|
|
250
|
+
) -> int:
|
|
251
|
+
"""Delete documents."""
|
|
252
|
+
Collection = self._pymilvus["Collection"]
|
|
253
|
+
col = Collection(collection)
|
|
254
|
+
col.load()
|
|
255
|
+
|
|
256
|
+
if ids:
|
|
257
|
+
id_list = ", ".join([f'"{i}"' for i in ids])
|
|
258
|
+
expr = f"id in [{id_list}]"
|
|
259
|
+
col.delete(expr)
|
|
260
|
+
return len(ids)
|
|
261
|
+
elif filters:
|
|
262
|
+
conditions = [f'{k} == "{v}"' for k, v in filters.items()]
|
|
263
|
+
expr = " and ".join(conditions)
|
|
264
|
+
col.delete(expr)
|
|
265
|
+
return -1
|
|
266
|
+
return 0
|
|
267
|
+
|
|
268
|
+
def count(self, collection: str) -> int:
|
|
269
|
+
"""Count documents."""
|
|
270
|
+
Collection = self._pymilvus["Collection"]
|
|
271
|
+
col = Collection(collection)
|
|
272
|
+
return col.num_entities
|
|
273
|
+
|
|
274
|
+
def close(self) -> None:
|
|
275
|
+
"""Close the store."""
|
|
276
|
+
connections = self._pymilvus["connections"]
|
|
277
|
+
connections.disconnect("default")
|