vanna 0.7.9__py3-none-any.whl → 2.0.0rc1__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.
- vanna/__init__.py +167 -395
- vanna/agents/__init__.py +7 -0
- vanna/capabilities/__init__.py +17 -0
- vanna/capabilities/agent_memory/__init__.py +21 -0
- vanna/capabilities/agent_memory/base.py +103 -0
- vanna/capabilities/agent_memory/models.py +53 -0
- vanna/capabilities/file_system/__init__.py +14 -0
- vanna/capabilities/file_system/base.py +71 -0
- vanna/capabilities/file_system/models.py +25 -0
- vanna/capabilities/sql_runner/__init__.py +13 -0
- vanna/capabilities/sql_runner/base.py +37 -0
- vanna/capabilities/sql_runner/models.py +13 -0
- vanna/components/__init__.py +92 -0
- vanna/components/base.py +11 -0
- vanna/components/rich/__init__.py +83 -0
- vanna/components/rich/containers/__init__.py +7 -0
- vanna/components/rich/containers/card.py +20 -0
- vanna/components/rich/data/__init__.py +9 -0
- vanna/components/rich/data/chart.py +17 -0
- vanna/components/rich/data/dataframe.py +93 -0
- vanna/components/rich/feedback/__init__.py +21 -0
- vanna/components/rich/feedback/badge.py +16 -0
- vanna/components/rich/feedback/icon_text.py +14 -0
- vanna/components/rich/feedback/log_viewer.py +41 -0
- vanna/components/rich/feedback/notification.py +19 -0
- vanna/components/rich/feedback/progress.py +37 -0
- vanna/components/rich/feedback/status_card.py +28 -0
- vanna/components/rich/feedback/status_indicator.py +14 -0
- vanna/components/rich/interactive/__init__.py +21 -0
- vanna/components/rich/interactive/button.py +95 -0
- vanna/components/rich/interactive/task_list.py +58 -0
- vanna/components/rich/interactive/ui_state.py +93 -0
- vanna/components/rich/specialized/__init__.py +7 -0
- vanna/components/rich/specialized/artifact.py +20 -0
- vanna/components/rich/text.py +16 -0
- vanna/components/simple/__init__.py +15 -0
- vanna/components/simple/image.py +15 -0
- vanna/components/simple/link.py +15 -0
- vanna/components/simple/text.py +11 -0
- vanna/core/__init__.py +193 -0
- vanna/core/_compat.py +19 -0
- vanna/core/agent/__init__.py +10 -0
- vanna/core/agent/agent.py +1407 -0
- vanna/core/agent/config.py +123 -0
- vanna/core/audit/__init__.py +28 -0
- vanna/core/audit/base.py +299 -0
- vanna/core/audit/models.py +131 -0
- vanna/core/component_manager.py +329 -0
- vanna/core/components.py +53 -0
- vanna/core/enhancer/__init__.py +11 -0
- vanna/core/enhancer/base.py +94 -0
- vanna/core/enhancer/default.py +118 -0
- vanna/core/enricher/__init__.py +10 -0
- vanna/core/enricher/base.py +59 -0
- vanna/core/errors.py +47 -0
- vanna/core/evaluation/__init__.py +81 -0
- vanna/core/evaluation/base.py +186 -0
- vanna/core/evaluation/dataset.py +254 -0
- vanna/core/evaluation/evaluators.py +376 -0
- vanna/core/evaluation/report.py +289 -0
- vanna/core/evaluation/runner.py +313 -0
- vanna/core/filter/__init__.py +10 -0
- vanna/core/filter/base.py +67 -0
- vanna/core/lifecycle/__init__.py +10 -0
- vanna/core/lifecycle/base.py +83 -0
- vanna/core/llm/__init__.py +16 -0
- vanna/core/llm/base.py +40 -0
- vanna/core/llm/models.py +61 -0
- vanna/core/middleware/__init__.py +10 -0
- vanna/core/middleware/base.py +69 -0
- vanna/core/observability/__init__.py +11 -0
- vanna/core/observability/base.py +88 -0
- vanna/core/observability/models.py +47 -0
- vanna/core/recovery/__init__.py +11 -0
- vanna/core/recovery/base.py +84 -0
- vanna/core/recovery/models.py +32 -0
- vanna/core/registry.py +278 -0
- vanna/core/rich_component.py +156 -0
- vanna/core/simple_component.py +27 -0
- vanna/core/storage/__init__.py +14 -0
- vanna/core/storage/base.py +46 -0
- vanna/core/storage/models.py +46 -0
- vanna/core/system_prompt/__init__.py +13 -0
- vanna/core/system_prompt/base.py +36 -0
- vanna/core/system_prompt/default.py +157 -0
- vanna/core/tool/__init__.py +18 -0
- vanna/core/tool/base.py +70 -0
- vanna/core/tool/models.py +84 -0
- vanna/core/user/__init__.py +17 -0
- vanna/core/user/base.py +29 -0
- vanna/core/user/models.py +25 -0
- vanna/core/user/request_context.py +70 -0
- vanna/core/user/resolver.py +42 -0
- vanna/core/validation.py +164 -0
- vanna/core/workflow/__init__.py +12 -0
- vanna/core/workflow/base.py +254 -0
- vanna/core/workflow/default.py +789 -0
- vanna/examples/__init__.py +1 -0
- vanna/examples/__main__.py +44 -0
- vanna/examples/anthropic_quickstart.py +80 -0
- vanna/examples/artifact_example.py +293 -0
- vanna/examples/claude_sqlite_example.py +236 -0
- vanna/examples/coding_agent_example.py +300 -0
- vanna/examples/custom_system_prompt_example.py +174 -0
- vanna/examples/default_workflow_handler_example.py +208 -0
- vanna/examples/email_auth_example.py +340 -0
- vanna/examples/evaluation_example.py +269 -0
- vanna/examples/extensibility_example.py +262 -0
- vanna/examples/minimal_example.py +67 -0
- vanna/examples/mock_auth_example.py +227 -0
- vanna/examples/mock_custom_tool.py +311 -0
- vanna/examples/mock_quickstart.py +79 -0
- vanna/examples/mock_quota_example.py +145 -0
- vanna/examples/mock_rich_components_demo.py +396 -0
- vanna/examples/mock_sqlite_example.py +223 -0
- vanna/examples/openai_quickstart.py +83 -0
- vanna/examples/primitive_components_demo.py +305 -0
- vanna/examples/quota_lifecycle_example.py +139 -0
- vanna/examples/visualization_example.py +251 -0
- vanna/integrations/__init__.py +17 -0
- vanna/integrations/anthropic/__init__.py +9 -0
- vanna/integrations/anthropic/llm.py +270 -0
- vanna/integrations/azureopenai/__init__.py +9 -0
- vanna/integrations/azureopenai/llm.py +329 -0
- vanna/integrations/azuresearch/__init__.py +7 -0
- vanna/integrations/azuresearch/agent_memory.py +413 -0
- vanna/integrations/bigquery/__init__.py +5 -0
- vanna/integrations/bigquery/sql_runner.py +81 -0
- vanna/integrations/chromadb/__init__.py +104 -0
- vanna/integrations/chromadb/agent_memory.py +416 -0
- vanna/integrations/clickhouse/__init__.py +5 -0
- vanna/integrations/clickhouse/sql_runner.py +82 -0
- vanna/integrations/duckdb/__init__.py +5 -0
- vanna/integrations/duckdb/sql_runner.py +65 -0
- vanna/integrations/faiss/__init__.py +7 -0
- vanna/integrations/faiss/agent_memory.py +431 -0
- vanna/integrations/google/__init__.py +9 -0
- vanna/integrations/google/gemini.py +370 -0
- vanna/integrations/hive/__init__.py +5 -0
- vanna/integrations/hive/sql_runner.py +87 -0
- vanna/integrations/local/__init__.py +17 -0
- vanna/integrations/local/agent_memory/__init__.py +7 -0
- vanna/integrations/local/agent_memory/in_memory.py +285 -0
- vanna/integrations/local/audit.py +59 -0
- vanna/integrations/local/file_system.py +242 -0
- vanna/integrations/local/file_system_conversation_store.py +255 -0
- vanna/integrations/local/storage.py +62 -0
- vanna/integrations/marqo/__init__.py +7 -0
- vanna/integrations/marqo/agent_memory.py +354 -0
- vanna/integrations/milvus/__init__.py +7 -0
- vanna/integrations/milvus/agent_memory.py +458 -0
- vanna/integrations/mock/__init__.py +9 -0
- vanna/integrations/mock/llm.py +65 -0
- vanna/integrations/mssql/__init__.py +5 -0
- vanna/integrations/mssql/sql_runner.py +66 -0
- vanna/integrations/mysql/__init__.py +5 -0
- vanna/integrations/mysql/sql_runner.py +92 -0
- vanna/integrations/ollama/__init__.py +7 -0
- vanna/integrations/ollama/llm.py +252 -0
- vanna/integrations/openai/__init__.py +10 -0
- vanna/integrations/openai/llm.py +267 -0
- vanna/integrations/openai/responses.py +163 -0
- vanna/integrations/opensearch/__init__.py +7 -0
- vanna/integrations/opensearch/agent_memory.py +411 -0
- vanna/integrations/oracle/__init__.py +5 -0
- vanna/integrations/oracle/sql_runner.py +75 -0
- vanna/integrations/pinecone/__init__.py +7 -0
- vanna/integrations/pinecone/agent_memory.py +329 -0
- vanna/integrations/plotly/__init__.py +5 -0
- vanna/integrations/plotly/chart_generator.py +313 -0
- vanna/integrations/postgres/__init__.py +9 -0
- vanna/integrations/postgres/sql_runner.py +112 -0
- vanna/integrations/premium/agent_memory/__init__.py +7 -0
- vanna/integrations/premium/agent_memory/premium.py +186 -0
- vanna/integrations/presto/__init__.py +5 -0
- vanna/integrations/presto/sql_runner.py +107 -0
- vanna/integrations/qdrant/__init__.py +7 -0
- vanna/integrations/qdrant/agent_memory.py +439 -0
- vanna/integrations/snowflake/__init__.py +5 -0
- vanna/integrations/snowflake/sql_runner.py +147 -0
- vanna/integrations/sqlite/__init__.py +9 -0
- vanna/integrations/sqlite/sql_runner.py +65 -0
- vanna/integrations/weaviate/__init__.py +7 -0
- vanna/integrations/weaviate/agent_memory.py +428 -0
- vanna/{ZhipuAI → legacy/ZhipuAI}/ZhipuAI_embeddings.py +11 -11
- vanna/legacy/__init__.py +403 -0
- vanna/legacy/adapter.py +463 -0
- vanna/{advanced → legacy/advanced}/__init__.py +3 -1
- vanna/{anthropic → legacy/anthropic}/anthropic_chat.py +9 -7
- vanna/{azuresearch → legacy/azuresearch}/azuresearch_vector.py +79 -41
- vanna/{base → legacy/base}/base.py +224 -217
- vanna/legacy/bedrock/__init__.py +1 -0
- vanna/{bedrock → legacy/bedrock}/bedrock_converse.py +13 -12
- vanna/{chromadb → legacy/chromadb}/chromadb_vector.py +3 -1
- vanna/legacy/cohere/__init__.py +2 -0
- vanna/{cohere → legacy/cohere}/cohere_chat.py +19 -14
- vanna/{cohere → legacy/cohere}/cohere_embeddings.py +25 -19
- vanna/{deepseek → legacy/deepseek}/deepseek_chat.py +5 -6
- vanna/legacy/faiss/__init__.py +1 -0
- vanna/{faiss → legacy/faiss}/faiss.py +113 -59
- vanna/{flask → legacy/flask}/__init__.py +84 -43
- vanna/{flask → legacy/flask}/assets.py +5 -5
- vanna/{flask → legacy/flask}/auth.py +5 -4
- vanna/{google → legacy/google}/bigquery_vector.py +75 -42
- vanna/{google → legacy/google}/gemini_chat.py +7 -3
- vanna/{hf → legacy/hf}/hf.py +0 -1
- vanna/{milvus → legacy/milvus}/milvus_vector.py +58 -35
- vanna/{mock → legacy/mock}/llm.py +0 -1
- vanna/legacy/mock/vectordb.py +67 -0
- vanna/legacy/ollama/ollama.py +110 -0
- vanna/{openai → legacy/openai}/openai_chat.py +2 -6
- vanna/legacy/opensearch/opensearch_vector.py +369 -0
- vanna/legacy/opensearch/opensearch_vector_semantic.py +200 -0
- vanna/legacy/oracle/oracle_vector.py +584 -0
- vanna/{pgvector → legacy/pgvector}/pgvector.py +42 -13
- vanna/{qdrant → legacy/qdrant}/qdrant.py +2 -6
- vanna/legacy/qianfan/Qianfan_Chat.py +170 -0
- vanna/legacy/qianfan/Qianfan_embeddings.py +36 -0
- vanna/legacy/qianwen/QianwenAI_chat.py +132 -0
- vanna/{remote.py → legacy/remote.py} +28 -26
- vanna/{utils.py → legacy/utils.py} +6 -11
- vanna/{vannadb → legacy/vannadb}/vannadb_vector.py +115 -46
- vanna/{vllm → legacy/vllm}/vllm.py +5 -6
- vanna/{weaviate → legacy/weaviate}/weaviate_vector.py +59 -40
- vanna/{xinference → legacy/xinference}/xinference.py +6 -6
- vanna/py.typed +0 -0
- vanna/servers/__init__.py +16 -0
- vanna/servers/__main__.py +8 -0
- vanna/servers/base/__init__.py +18 -0
- vanna/servers/base/chat_handler.py +65 -0
- vanna/servers/base/models.py +111 -0
- vanna/servers/base/rich_chat_handler.py +141 -0
- vanna/servers/base/templates.py +331 -0
- vanna/servers/cli/__init__.py +7 -0
- vanna/servers/cli/server_runner.py +204 -0
- vanna/servers/fastapi/__init__.py +7 -0
- vanna/servers/fastapi/app.py +163 -0
- vanna/servers/fastapi/routes.py +183 -0
- vanna/servers/flask/__init__.py +7 -0
- vanna/servers/flask/app.py +132 -0
- vanna/servers/flask/routes.py +137 -0
- vanna/tools/__init__.py +41 -0
- vanna/tools/agent_memory.py +322 -0
- vanna/tools/file_system.py +879 -0
- vanna/tools/python.py +222 -0
- vanna/tools/run_sql.py +165 -0
- vanna/tools/visualize_data.py +195 -0
- vanna/utils/__init__.py +0 -0
- vanna/web_components/__init__.py +44 -0
- vanna-2.0.0rc1.dist-info/METADATA +868 -0
- vanna-2.0.0rc1.dist-info/RECORD +289 -0
- vanna-2.0.0rc1.dist-info/entry_points.txt +3 -0
- vanna/bedrock/__init__.py +0 -1
- vanna/cohere/__init__.py +0 -2
- vanna/faiss/__init__.py +0 -1
- vanna/mock/vectordb.py +0 -55
- vanna/ollama/ollama.py +0 -103
- vanna/opensearch/opensearch_vector.py +0 -392
- vanna/opensearch/opensearch_vector_semantic.py +0 -175
- vanna/oracle/oracle_vector.py +0 -585
- vanna/qianfan/Qianfan_Chat.py +0 -165
- vanna/qianfan/Qianfan_embeddings.py +0 -36
- vanna/qianwen/QianwenAI_chat.py +0 -133
- vanna-0.7.9.dist-info/METADATA +0 -408
- vanna-0.7.9.dist-info/RECORD +0 -79
- /vanna/{ZhipuAI → legacy/ZhipuAI}/ZhipuAI_Chat.py +0 -0
- /vanna/{ZhipuAI → legacy/ZhipuAI}/__init__.py +0 -0
- /vanna/{anthropic → legacy/anthropic}/__init__.py +0 -0
- /vanna/{azuresearch → legacy/azuresearch}/__init__.py +0 -0
- /vanna/{base → legacy/base}/__init__.py +0 -0
- /vanna/{chromadb → legacy/chromadb}/__init__.py +0 -0
- /vanna/{deepseek → legacy/deepseek}/__init__.py +0 -0
- /vanna/{exceptions → legacy/exceptions}/__init__.py +0 -0
- /vanna/{google → legacy/google}/__init__.py +0 -0
- /vanna/{hf → legacy/hf}/__init__.py +0 -0
- /vanna/{local.py → legacy/local.py} +0 -0
- /vanna/{marqo → legacy/marqo}/__init__.py +0 -0
- /vanna/{marqo → legacy/marqo}/marqo.py +0 -0
- /vanna/{milvus → legacy/milvus}/__init__.py +0 -0
- /vanna/{mistral → legacy/mistral}/__init__.py +0 -0
- /vanna/{mistral → legacy/mistral}/mistral.py +0 -0
- /vanna/{mock → legacy/mock}/__init__.py +0 -0
- /vanna/{mock → legacy/mock}/embedding.py +0 -0
- /vanna/{ollama → legacy/ollama}/__init__.py +0 -0
- /vanna/{openai → legacy/openai}/__init__.py +0 -0
- /vanna/{openai → legacy/openai}/openai_embeddings.py +0 -0
- /vanna/{opensearch → legacy/opensearch}/__init__.py +0 -0
- /vanna/{oracle → legacy/oracle}/__init__.py +0 -0
- /vanna/{pgvector → legacy/pgvector}/__init__.py +0 -0
- /vanna/{pinecone → legacy/pinecone}/__init__.py +0 -0
- /vanna/{pinecone → legacy/pinecone}/pinecone_vector.py +0 -0
- /vanna/{qdrant → legacy/qdrant}/__init__.py +0 -0
- /vanna/{qianfan → legacy/qianfan}/__init__.py +0 -0
- /vanna/{qianwen → legacy/qianwen}/QianwenAI_embeddings.py +0 -0
- /vanna/{qianwen → legacy/qianwen}/__init__.py +0 -0
- /vanna/{types → legacy/types}/__init__.py +0 -0
- /vanna/{vannadb → legacy/vannadb}/__init__.py +0 -0
- /vanna/{vllm → legacy/vllm}/__init__.py +0 -0
- /vanna/{weaviate → legacy/weaviate}/__init__.py +0 -0
- /vanna/{xinference → legacy/xinference}/__init__.py +0 -0
- {vanna-0.7.9.dist-info → vanna-2.0.0rc1.dist-info}/WHEEL +0 -0
- {vanna-0.7.9.dist-info → vanna-2.0.0rc1.dist-info}/licenses/LICENSE +0 -0
vanna/legacy/adapter.py
ADDED
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Legacy VannaBase adapter for the Vanna Agents framework.
|
|
3
|
+
|
|
4
|
+
This module provides a LegacyVannaAdapter that bridges legacy VannaBase objects
|
|
5
|
+
with the new ToolRegistry system by auto-registering legacy methods as tools
|
|
6
|
+
with appropriate group-based access control.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Any, Dict, List, Optional
|
|
10
|
+
|
|
11
|
+
import pandas as pd
|
|
12
|
+
|
|
13
|
+
from ..capabilities.agent_memory import (
|
|
14
|
+
AgentMemory,
|
|
15
|
+
TextMemory,
|
|
16
|
+
TextMemorySearchResult,
|
|
17
|
+
ToolMemory,
|
|
18
|
+
ToolMemorySearchResult,
|
|
19
|
+
)
|
|
20
|
+
from ..capabilities.sql_runner import SqlRunner, RunSqlToolArgs
|
|
21
|
+
from ..core.registry import ToolRegistry
|
|
22
|
+
from ..core.tool import Tool, ToolContext, ToolResult
|
|
23
|
+
from ..core.user import User
|
|
24
|
+
from ..tools.agent_memory import (
|
|
25
|
+
SaveQuestionToolArgsTool,
|
|
26
|
+
SearchSavedCorrectToolUsesTool,
|
|
27
|
+
)
|
|
28
|
+
from ..tools.run_sql import RunSqlTool
|
|
29
|
+
from .base.base import VannaBase
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class LegacySqlRunner(SqlRunner):
|
|
33
|
+
"""SqlRunner implementation that wraps a legacy VannaBase instance.
|
|
34
|
+
|
|
35
|
+
This class bridges the new SqlRunner interface with legacy VannaBase
|
|
36
|
+
run_sql methods, allowing legacy database connections to work with
|
|
37
|
+
the new tool-based architecture.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def __init__(self, vn: VannaBase):
|
|
41
|
+
"""Initialize with a legacy VannaBase instance.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
vn: The legacy VannaBase instance with an initialized run_sql method
|
|
45
|
+
"""
|
|
46
|
+
self.vn = vn
|
|
47
|
+
|
|
48
|
+
async def run_sql(self, args: RunSqlToolArgs, context: ToolContext) -> pd.DataFrame:
|
|
49
|
+
"""Execute SQL query using the legacy VannaBase run_sql method.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
args: SQL query arguments containing the SQL string
|
|
53
|
+
context: Tool execution context (not used by legacy implementation)
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
DataFrame with query results
|
|
57
|
+
|
|
58
|
+
Raises:
|
|
59
|
+
Exception: If query execution fails
|
|
60
|
+
"""
|
|
61
|
+
# Call the legacy VannaBase run_sql method
|
|
62
|
+
# The legacy method is synchronous, so we call it directly
|
|
63
|
+
return self.vn.run_sql(args.sql)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class LegacyVannaAdapter(ToolRegistry, AgentMemory):
|
|
67
|
+
"""Adapter that wraps a legacy VannaBase object and exposes its methods as tools.
|
|
68
|
+
|
|
69
|
+
This adapter automatically registers specific VannaBase methods as tools in the
|
|
70
|
+
registry with configurable group-based access control. This allows legacy Vanna
|
|
71
|
+
instances to work seamlessly with the new Agents framework.
|
|
72
|
+
|
|
73
|
+
Features:
|
|
74
|
+
- Auto-registers legacy methods as tools
|
|
75
|
+
- Configurable group-based permissions ('user', 'admin', etc.)
|
|
76
|
+
- Seamless integration with ToolRegistry
|
|
77
|
+
- Implements AgentMemory interface
|
|
78
|
+
- Preserves legacy VannaBase functionality
|
|
79
|
+
|
|
80
|
+
Example:
|
|
81
|
+
```python
|
|
82
|
+
from vanna.legacy.base import VannaBase
|
|
83
|
+
from vanna.legacy.adapter import LegacyVannaAdapter
|
|
84
|
+
|
|
85
|
+
# Initialize your legacy Vanna instance
|
|
86
|
+
vn = VannaBase(config={"model": "gpt-4"})
|
|
87
|
+
vn.connect_to_postgres(...)
|
|
88
|
+
|
|
89
|
+
# Create adapter and auto-register tools
|
|
90
|
+
adapter = LegacyVannaAdapter(vn)
|
|
91
|
+
|
|
92
|
+
# Tools are now available through the registry
|
|
93
|
+
schemas = await adapter.get_schemas(user)
|
|
94
|
+
```
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
def __init__(
|
|
98
|
+
self,
|
|
99
|
+
vn: VannaBase,
|
|
100
|
+
audit_logger: Optional[Any] = None,
|
|
101
|
+
audit_config: Optional[Any] = None,
|
|
102
|
+
) -> None:
|
|
103
|
+
"""Initialize the adapter with a legacy VannaBase instance.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
vanna: The legacy VannaBase instance to wrap
|
|
107
|
+
audit_logger: Optional audit logger for tool execution tracking
|
|
108
|
+
audit_config: Optional audit configuration
|
|
109
|
+
"""
|
|
110
|
+
ToolRegistry.__init__(
|
|
111
|
+
self, audit_logger=audit_logger, audit_config=audit_config
|
|
112
|
+
)
|
|
113
|
+
self.vn = vn
|
|
114
|
+
self._register_tools()
|
|
115
|
+
|
|
116
|
+
def _register_tools(self) -> None:
|
|
117
|
+
"""Register legacy VannaBase methods as tools with appropriate permissions.
|
|
118
|
+
|
|
119
|
+
Registers the following tools:
|
|
120
|
+
- RunSqlTool: Wraps the legacy run_sql method via LegacySqlRunner
|
|
121
|
+
- SaveQuestionToolArgsTool: Wraps add_question_sql via LegacyAgentMemory
|
|
122
|
+
- SearchSavedCorrectToolUsesTool: Wraps get_similar_question_sql via LegacyAgentMemory
|
|
123
|
+
"""
|
|
124
|
+
# Create a LegacySqlRunner to wrap the VannaBase run_sql method
|
|
125
|
+
sql_runner = LegacySqlRunner(self.vn)
|
|
126
|
+
|
|
127
|
+
# Register the RunSqlTool with user and admin access
|
|
128
|
+
run_sql_tool = RunSqlTool(sql_runner)
|
|
129
|
+
self.register_local_tool(run_sql_tool, access_groups=["user", "admin"])
|
|
130
|
+
|
|
131
|
+
# Register memory tools using the internal _agent_memory instance
|
|
132
|
+
# SaveQuestionToolArgsTool - for saving question-tool-args patterns (admin only)
|
|
133
|
+
save_memory_tool = SaveQuestionToolArgsTool()
|
|
134
|
+
self.register_local_tool(save_memory_tool, access_groups=["admin"])
|
|
135
|
+
|
|
136
|
+
# SearchSavedCorrectToolUsesTool - for searching similar patterns (user and admin)
|
|
137
|
+
search_memory_tool = SearchSavedCorrectToolUsesTool()
|
|
138
|
+
self.register_local_tool(search_memory_tool, access_groups=["user", "admin"])
|
|
139
|
+
|
|
140
|
+
# AgentMemory interface implementation
|
|
141
|
+
|
|
142
|
+
async def save_tool_usage(
|
|
143
|
+
self,
|
|
144
|
+
question: str,
|
|
145
|
+
tool_name: str,
|
|
146
|
+
args: Dict[str, Any],
|
|
147
|
+
context: ToolContext,
|
|
148
|
+
success: bool = True,
|
|
149
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
150
|
+
) -> None:
|
|
151
|
+
"""Save a tool usage pattern by storing it as a question-sql pair.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
question: The user question
|
|
155
|
+
tool_name: Name of the tool that was used
|
|
156
|
+
args: Arguments passed to the tool
|
|
157
|
+
context: Tool execution context (not used by legacy implementation)
|
|
158
|
+
success: Whether the tool execution was successful
|
|
159
|
+
metadata: Additional metadata (not used by legacy implementation)
|
|
160
|
+
"""
|
|
161
|
+
# For legacy compatibility, we primarily care about SQL queries
|
|
162
|
+
# Extract SQL from args if this was a run_sql tool
|
|
163
|
+
if tool_name == "run_sql" and "sql" in args:
|
|
164
|
+
sql = args["sql"]
|
|
165
|
+
# Call the legacy add_question_sql method
|
|
166
|
+
# The legacy method is synchronous, so we call it directly
|
|
167
|
+
self.vn.add_question_sql(question=question, sql=sql)
|
|
168
|
+
|
|
169
|
+
async def search_similar_usage(
|
|
170
|
+
self,
|
|
171
|
+
question: str,
|
|
172
|
+
context: ToolContext,
|
|
173
|
+
*,
|
|
174
|
+
limit: int = 10,
|
|
175
|
+
similarity_threshold: float = 0.7,
|
|
176
|
+
tool_name_filter: Optional[str] = None,
|
|
177
|
+
) -> List[ToolMemorySearchResult]:
|
|
178
|
+
"""Search for similar tool usage patterns using legacy question-sql lookup.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
question: The question to search for
|
|
182
|
+
context: Tool execution context (not used by legacy implementation)
|
|
183
|
+
limit: Maximum number of results (not directly supported by legacy)
|
|
184
|
+
similarity_threshold: Minimum similarity score (not directly supported by legacy)
|
|
185
|
+
tool_name_filter: Filter by tool name (not directly supported by legacy)
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
List of memory search results with similar question-sql pairs
|
|
189
|
+
"""
|
|
190
|
+
# Call the legacy get_similar_question_sql method
|
|
191
|
+
similar_results = self.vn.get_similar_question_sql(question=question)
|
|
192
|
+
|
|
193
|
+
# Convert legacy results to ToolMemorySearchResult format
|
|
194
|
+
memory_results = []
|
|
195
|
+
for idx, result in enumerate(similar_results):
|
|
196
|
+
# Legacy results are typically dicts with 'question' and 'sql' keys
|
|
197
|
+
if isinstance(result, dict) and "question" in result and "sql" in result:
|
|
198
|
+
tool_memory = ToolMemory(
|
|
199
|
+
memory_id=None, # Legacy doesn't provide IDs
|
|
200
|
+
question=result["question"],
|
|
201
|
+
tool_name="run_sql",
|
|
202
|
+
args={"sql": result["sql"]},
|
|
203
|
+
success=True,
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
# Assign a simple rank-based similarity score
|
|
207
|
+
# Legacy system doesn't provide actual similarity scores
|
|
208
|
+
similarity_score = 1.0 - (idx * 0.1) # Decreasing score by rank
|
|
209
|
+
similarity_score = max(similarity_score, 0.0)
|
|
210
|
+
|
|
211
|
+
memory_results.append(
|
|
212
|
+
ToolMemorySearchResult(
|
|
213
|
+
memory=tool_memory,
|
|
214
|
+
similarity_score=similarity_score,
|
|
215
|
+
rank=idx + 1,
|
|
216
|
+
)
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
return memory_results[:limit]
|
|
220
|
+
|
|
221
|
+
async def save_text_memory(self, content: str, context: ToolContext) -> TextMemory:
|
|
222
|
+
"""Save text memory using legacy add_documentation method.
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
content: The documentation content to save
|
|
226
|
+
context: Tool execution context (not used by legacy implementation)
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
TextMemory object with the saved content
|
|
230
|
+
"""
|
|
231
|
+
# Call the legacy add_documentation method
|
|
232
|
+
# The legacy method is synchronous, so we call it directly
|
|
233
|
+
doc_id = self.vn.add_documentation(documentation=content)
|
|
234
|
+
|
|
235
|
+
return TextMemory(
|
|
236
|
+
memory_id=doc_id,
|
|
237
|
+
content=content,
|
|
238
|
+
timestamp=None, # Legacy doesn't provide timestamps
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
async def search_text_memories(
|
|
242
|
+
self,
|
|
243
|
+
query: str,
|
|
244
|
+
context: ToolContext,
|
|
245
|
+
*,
|
|
246
|
+
limit: int = 10,
|
|
247
|
+
similarity_threshold: float = 0.7,
|
|
248
|
+
) -> List[TextMemorySearchResult]:
|
|
249
|
+
"""Search text memories using legacy get_related_documentation method.
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
query: The query to search for
|
|
253
|
+
context: Tool execution context (not used by legacy implementation)
|
|
254
|
+
limit: Maximum number of results (not directly supported by legacy)
|
|
255
|
+
similarity_threshold: Minimum similarity score (not directly supported by legacy)
|
|
256
|
+
|
|
257
|
+
Returns:
|
|
258
|
+
List of text memory search results
|
|
259
|
+
"""
|
|
260
|
+
# Call the legacy get_related_documentation method
|
|
261
|
+
related_docs = self.vn.get_related_documentation(question=query)
|
|
262
|
+
|
|
263
|
+
# Convert legacy results to TextMemorySearchResult format
|
|
264
|
+
memory_results = []
|
|
265
|
+
for idx, doc in enumerate(related_docs):
|
|
266
|
+
# Legacy results are typically strings or dicts
|
|
267
|
+
if isinstance(doc, str):
|
|
268
|
+
content = doc
|
|
269
|
+
doc_id = None
|
|
270
|
+
elif isinstance(doc, dict):
|
|
271
|
+
content = str(doc.get("documentation", doc.get("content", str(doc))))
|
|
272
|
+
doc_id = doc.get("id")
|
|
273
|
+
else:
|
|
274
|
+
content = str(doc)
|
|
275
|
+
doc_id = None
|
|
276
|
+
|
|
277
|
+
# Create TextMemory object
|
|
278
|
+
text_memory = TextMemory(
|
|
279
|
+
memory_id=doc_id,
|
|
280
|
+
content=content,
|
|
281
|
+
timestamp=None, # Legacy doesn't provide timestamps
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
# Assign a simple rank-based similarity score
|
|
285
|
+
# Legacy system doesn't provide actual similarity scores
|
|
286
|
+
similarity_score = 1.0 - (idx * 0.1) # Decreasing score by rank
|
|
287
|
+
similarity_score = max(similarity_score, 0.0)
|
|
288
|
+
|
|
289
|
+
if similarity_score >= similarity_threshold:
|
|
290
|
+
memory_results.append(
|
|
291
|
+
TextMemorySearchResult(
|
|
292
|
+
memory=text_memory,
|
|
293
|
+
similarity_score=similarity_score,
|
|
294
|
+
rank=idx + 1,
|
|
295
|
+
)
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
return memory_results[:limit]
|
|
299
|
+
|
|
300
|
+
async def get_recent_memories(
|
|
301
|
+
self, context: ToolContext, limit: int = 10
|
|
302
|
+
) -> List[ToolMemory]:
|
|
303
|
+
"""Get recently added memories.
|
|
304
|
+
|
|
305
|
+
Note: Legacy VannaBase does not provide a direct way to get recent memories,
|
|
306
|
+
so we retrieve using a blank string which typically returns the most relevant
|
|
307
|
+
or recent items from the vector store.
|
|
308
|
+
|
|
309
|
+
Args:
|
|
310
|
+
context: Tool execution context
|
|
311
|
+
limit: Maximum number of memories to return
|
|
312
|
+
|
|
313
|
+
Returns:
|
|
314
|
+
List of recently added tool memories
|
|
315
|
+
"""
|
|
316
|
+
# Use blank string retrieval to get recent/relevant memories
|
|
317
|
+
similar_results = self.vn.get_similar_question_sql(question="")
|
|
318
|
+
|
|
319
|
+
# Convert legacy results to ToolMemory format
|
|
320
|
+
memories = []
|
|
321
|
+
for idx, result in enumerate(similar_results[:limit]):
|
|
322
|
+
# Legacy results are typically dicts with 'question' and 'sql' keys
|
|
323
|
+
if isinstance(result, dict) and "question" in result and "sql" in result:
|
|
324
|
+
tool_memory = ToolMemory(
|
|
325
|
+
memory_id=None, # Legacy doesn't provide IDs
|
|
326
|
+
question=result["question"],
|
|
327
|
+
tool_name="run_sql",
|
|
328
|
+
args={"sql": result["sql"]},
|
|
329
|
+
success=True,
|
|
330
|
+
)
|
|
331
|
+
memories.append(tool_memory)
|
|
332
|
+
|
|
333
|
+
return memories
|
|
334
|
+
|
|
335
|
+
async def get_recent_text_memories(
|
|
336
|
+
self, context: ToolContext, limit: int = 10
|
|
337
|
+
) -> List[TextMemory]:
|
|
338
|
+
"""Fetch recently stored text memories.
|
|
339
|
+
|
|
340
|
+
Note: Legacy VannaBase does not provide a direct way to get recent text memories,
|
|
341
|
+
so we retrieve using a blank string which typically returns the most relevant
|
|
342
|
+
or recent items from the vector store.
|
|
343
|
+
|
|
344
|
+
Args:
|
|
345
|
+
context: Tool execution context
|
|
346
|
+
limit: Maximum number of memories to return
|
|
347
|
+
|
|
348
|
+
Returns:
|
|
349
|
+
List of recently added text memories
|
|
350
|
+
"""
|
|
351
|
+
# Use blank string retrieval to get recent/relevant documentation
|
|
352
|
+
related_docs = self.vn.get_related_documentation(question="")
|
|
353
|
+
|
|
354
|
+
# Convert legacy results to TextMemory format
|
|
355
|
+
memories = []
|
|
356
|
+
for doc in related_docs[:limit]:
|
|
357
|
+
# Legacy results are typically strings or dicts
|
|
358
|
+
if isinstance(doc, str):
|
|
359
|
+
content = doc
|
|
360
|
+
doc_id = None
|
|
361
|
+
elif isinstance(doc, dict):
|
|
362
|
+
content = str(doc.get("documentation", doc.get("content", str(doc))))
|
|
363
|
+
doc_id = doc.get("id")
|
|
364
|
+
else:
|
|
365
|
+
content = str(doc)
|
|
366
|
+
doc_id = None
|
|
367
|
+
|
|
368
|
+
# Create TextMemory object
|
|
369
|
+
text_memory = TextMemory(
|
|
370
|
+
memory_id=doc_id,
|
|
371
|
+
content=content,
|
|
372
|
+
timestamp=None, # Legacy doesn't provide timestamps
|
|
373
|
+
)
|
|
374
|
+
memories.append(text_memory)
|
|
375
|
+
|
|
376
|
+
return memories
|
|
377
|
+
|
|
378
|
+
async def delete_by_id(self, context: ToolContext, memory_id: str) -> bool:
|
|
379
|
+
"""Delete a memory by its ID using legacy remove_training_data method.
|
|
380
|
+
|
|
381
|
+
Args:
|
|
382
|
+
context: Tool execution context
|
|
383
|
+
memory_id: ID of the memory to delete
|
|
384
|
+
|
|
385
|
+
Returns:
|
|
386
|
+
True if the memory was deleted, False otherwise
|
|
387
|
+
"""
|
|
388
|
+
# Call the legacy remove_training_data method
|
|
389
|
+
# The legacy method is synchronous, so we call it directly
|
|
390
|
+
return self.vn.remove_training_data(id=memory_id)
|
|
391
|
+
|
|
392
|
+
async def delete_text_memory(self, context: ToolContext, memory_id: str) -> bool:
|
|
393
|
+
"""Delete a text memory by its ID using legacy remove_training_data method.
|
|
394
|
+
|
|
395
|
+
Args:
|
|
396
|
+
context: Tool execution context
|
|
397
|
+
memory_id: ID of the text memory to delete
|
|
398
|
+
|
|
399
|
+
Returns:
|
|
400
|
+
True if the text memory was deleted, False otherwise
|
|
401
|
+
"""
|
|
402
|
+
# Call the legacy remove_training_data method
|
|
403
|
+
# The legacy method is synchronous, so we call it directly
|
|
404
|
+
return self.vn.remove_training_data(id=memory_id)
|
|
405
|
+
|
|
406
|
+
async def clear_memories(
|
|
407
|
+
self,
|
|
408
|
+
context: ToolContext,
|
|
409
|
+
tool_name: Optional[str] = None,
|
|
410
|
+
before_date: Optional[str] = None,
|
|
411
|
+
) -> int:
|
|
412
|
+
"""Clear stored memories.
|
|
413
|
+
|
|
414
|
+
Note: Legacy VannaBase does not provide a direct clear method,
|
|
415
|
+
so this operation is not supported.
|
|
416
|
+
|
|
417
|
+
Args:
|
|
418
|
+
context: Tool execution context
|
|
419
|
+
tool_name: Optional tool name filter
|
|
420
|
+
before_date: Optional date filter
|
|
421
|
+
|
|
422
|
+
Returns:
|
|
423
|
+
0 (operation not supported by legacy)
|
|
424
|
+
"""
|
|
425
|
+
return 0
|
|
426
|
+
|
|
427
|
+
# Example stub for a tool wrapper (to be expanded)
|
|
428
|
+
# You can copy and customize this pattern for each tool you want to expose
|
|
429
|
+
"""
|
|
430
|
+
class ExampleTool(Tool[ExampleToolArgs]):
|
|
431
|
+
def __init__(self, vanna: VannaBase):
|
|
432
|
+
self.vanna = vanna
|
|
433
|
+
|
|
434
|
+
@property
|
|
435
|
+
def name(self) -> str:
|
|
436
|
+
return "example_tool"
|
|
437
|
+
|
|
438
|
+
@property
|
|
439
|
+
def description(self) -> str:
|
|
440
|
+
return "Example tool description"
|
|
441
|
+
|
|
442
|
+
@property
|
|
443
|
+
def access_groups(self) -> List[str]:
|
|
444
|
+
# This is optional - will be overridden by register_local_tool
|
|
445
|
+
return []
|
|
446
|
+
|
|
447
|
+
def get_args_schema(self) -> type[ExampleToolArgs]:
|
|
448
|
+
return ExampleToolArgs
|
|
449
|
+
|
|
450
|
+
async def execute(
|
|
451
|
+
self,
|
|
452
|
+
context: ToolContext,
|
|
453
|
+
args: ExampleToolArgs
|
|
454
|
+
) -> ToolResult:
|
|
455
|
+
# Call the legacy VannaBase method
|
|
456
|
+
result = self.vanna.example_method(args.param1, args.param2)
|
|
457
|
+
|
|
458
|
+
return ToolResult(
|
|
459
|
+
success=True,
|
|
460
|
+
result_for_llm=result,
|
|
461
|
+
ui_component=None,
|
|
462
|
+
)
|
|
463
|
+
"""
|
|
@@ -10,7 +10,9 @@ class VannaAdvanced(ABC):
|
|
|
10
10
|
pass
|
|
11
11
|
|
|
12
12
|
@abstractmethod
|
|
13
|
-
def create_function(
|
|
13
|
+
def create_function(
|
|
14
|
+
self, question: str, sql: str, plotly_code: str, **kwargs
|
|
15
|
+
) -> dict:
|
|
14
16
|
pass
|
|
15
17
|
|
|
16
18
|
@abstractmethod
|
|
@@ -8,7 +8,7 @@ from ..base import VannaBase
|
|
|
8
8
|
class Anthropic_Chat(VannaBase):
|
|
9
9
|
def __init__(self, client=None, config=None):
|
|
10
10
|
VannaBase.__init__(self, config=config)
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
# default parameters - can be overrided using config
|
|
13
13
|
self.temperature = 0.7
|
|
14
14
|
self.max_tokens = 500
|
|
@@ -26,7 +26,7 @@ class Anthropic_Chat(VannaBase):
|
|
|
26
26
|
if config is None and client is None:
|
|
27
27
|
self.client = anthropic.Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
|
|
28
28
|
return
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
if "api_key" in config:
|
|
31
31
|
self.client = anthropic.Anthropic(api_key=config["api_key"])
|
|
32
32
|
|
|
@@ -58,14 +58,16 @@ class Anthropic_Chat(VannaBase):
|
|
|
58
58
|
)
|
|
59
59
|
# claude required system message is a single filed
|
|
60
60
|
# https://docs.anthropic.com/claude/reference/messages_post
|
|
61
|
-
system_message =
|
|
61
|
+
system_message = ""
|
|
62
62
|
no_system_prompt = []
|
|
63
63
|
for prompt_message in prompt:
|
|
64
|
-
role = prompt_message[
|
|
65
|
-
if role ==
|
|
66
|
-
system_message = prompt_message[
|
|
64
|
+
role = prompt_message["role"]
|
|
65
|
+
if role == "system":
|
|
66
|
+
system_message = prompt_message["content"]
|
|
67
67
|
else:
|
|
68
|
-
no_system_prompt.append(
|
|
68
|
+
no_system_prompt.append(
|
|
69
|
+
{"role": role, "content": prompt_message["content"]}
|
|
70
|
+
)
|
|
69
71
|
|
|
70
72
|
response = self.client.messages.create(
|
|
71
73
|
model=self.config["model"],
|