asksql 2.1.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.
Files changed (291) hide show
  1. asksql-2.1.0.dist-info/METADATA +517 -0
  2. asksql-2.1.0.dist-info/RECORD +291 -0
  3. asksql-2.1.0.dist-info/WHEEL +4 -0
  4. asksql-2.1.0.dist-info/entry_points.txt +4 -0
  5. asksql-2.1.0.dist-info/licenses/LICENSE +21 -0
  6. vanna/__init__.py +172 -0
  7. vanna/agents/__init__.py +7 -0
  8. vanna/capabilities/__init__.py +17 -0
  9. vanna/capabilities/agent_memory/__init__.py +21 -0
  10. vanna/capabilities/agent_memory/base.py +103 -0
  11. vanna/capabilities/agent_memory/models.py +53 -0
  12. vanna/capabilities/file_system/__init__.py +14 -0
  13. vanna/capabilities/file_system/base.py +71 -0
  14. vanna/capabilities/file_system/models.py +25 -0
  15. vanna/capabilities/sql_runner/__init__.py +13 -0
  16. vanna/capabilities/sql_runner/base.py +37 -0
  17. vanna/capabilities/sql_runner/models.py +13 -0
  18. vanna/components/__init__.py +92 -0
  19. vanna/components/base.py +11 -0
  20. vanna/components/rich/__init__.py +83 -0
  21. vanna/components/rich/containers/__init__.py +7 -0
  22. vanna/components/rich/containers/card.py +20 -0
  23. vanna/components/rich/data/__init__.py +9 -0
  24. vanna/components/rich/data/chart.py +17 -0
  25. vanna/components/rich/data/dataframe.py +93 -0
  26. vanna/components/rich/feedback/__init__.py +21 -0
  27. vanna/components/rich/feedback/badge.py +16 -0
  28. vanna/components/rich/feedback/icon_text.py +14 -0
  29. vanna/components/rich/feedback/log_viewer.py +41 -0
  30. vanna/components/rich/feedback/notification.py +19 -0
  31. vanna/components/rich/feedback/progress.py +37 -0
  32. vanna/components/rich/feedback/status_card.py +28 -0
  33. vanna/components/rich/feedback/status_indicator.py +14 -0
  34. vanna/components/rich/interactive/__init__.py +21 -0
  35. vanna/components/rich/interactive/button.py +95 -0
  36. vanna/components/rich/interactive/task_list.py +58 -0
  37. vanna/components/rich/interactive/ui_state.py +93 -0
  38. vanna/components/rich/specialized/__init__.py +7 -0
  39. vanna/components/rich/specialized/artifact.py +20 -0
  40. vanna/components/rich/text.py +16 -0
  41. vanna/components/simple/__init__.py +15 -0
  42. vanna/components/simple/image.py +15 -0
  43. vanna/components/simple/link.py +15 -0
  44. vanna/components/simple/text.py +11 -0
  45. vanna/core/__init__.py +193 -0
  46. vanna/core/_compat.py +19 -0
  47. vanna/core/agent/__init__.py +10 -0
  48. vanna/core/agent/agent.py +1407 -0
  49. vanna/core/agent/config.py +123 -0
  50. vanna/core/audit/__init__.py +28 -0
  51. vanna/core/audit/base.py +299 -0
  52. vanna/core/audit/models.py +131 -0
  53. vanna/core/component_manager.py +329 -0
  54. vanna/core/components.py +53 -0
  55. vanna/core/enhancer/__init__.py +11 -0
  56. vanna/core/enhancer/base.py +94 -0
  57. vanna/core/enhancer/default.py +118 -0
  58. vanna/core/enricher/__init__.py +10 -0
  59. vanna/core/enricher/base.py +59 -0
  60. vanna/core/errors.py +47 -0
  61. vanna/core/evaluation/__init__.py +81 -0
  62. vanna/core/evaluation/base.py +186 -0
  63. vanna/core/evaluation/dataset.py +254 -0
  64. vanna/core/evaluation/evaluators.py +376 -0
  65. vanna/core/evaluation/report.py +289 -0
  66. vanna/core/evaluation/runner.py +313 -0
  67. vanna/core/filter/__init__.py +10 -0
  68. vanna/core/filter/base.py +67 -0
  69. vanna/core/lifecycle/__init__.py +10 -0
  70. vanna/core/lifecycle/base.py +83 -0
  71. vanna/core/llm/__init__.py +16 -0
  72. vanna/core/llm/base.py +40 -0
  73. vanna/core/llm/models.py +61 -0
  74. vanna/core/middleware/__init__.py +10 -0
  75. vanna/core/middleware/base.py +69 -0
  76. vanna/core/observability/__init__.py +11 -0
  77. vanna/core/observability/base.py +88 -0
  78. vanna/core/observability/models.py +47 -0
  79. vanna/core/recovery/__init__.py +11 -0
  80. vanna/core/recovery/base.py +84 -0
  81. vanna/core/recovery/models.py +32 -0
  82. vanna/core/registry.py +278 -0
  83. vanna/core/rich_component.py +156 -0
  84. vanna/core/simple_component.py +27 -0
  85. vanna/core/storage/__init__.py +14 -0
  86. vanna/core/storage/base.py +46 -0
  87. vanna/core/storage/models.py +46 -0
  88. vanna/core/system_prompt/__init__.py +13 -0
  89. vanna/core/system_prompt/base.py +36 -0
  90. vanna/core/system_prompt/default.py +157 -0
  91. vanna/core/tool/__init__.py +18 -0
  92. vanna/core/tool/base.py +70 -0
  93. vanna/core/tool/models.py +84 -0
  94. vanna/core/user/__init__.py +17 -0
  95. vanna/core/user/base.py +29 -0
  96. vanna/core/user/models.py +25 -0
  97. vanna/core/user/request_context.py +70 -0
  98. vanna/core/user/resolver.py +42 -0
  99. vanna/core/validation.py +164 -0
  100. vanna/core/workflow/__init__.py +12 -0
  101. vanna/core/workflow/base.py +254 -0
  102. vanna/core/workflow/default.py +789 -0
  103. vanna/examples/__init__.py +1 -0
  104. vanna/examples/__main__.py +44 -0
  105. vanna/examples/anthropic_quickstart.py +80 -0
  106. vanna/examples/artifact_example.py +293 -0
  107. vanna/examples/claude_sqlite_example.py +236 -0
  108. vanna/examples/coding_agent_example.py +300 -0
  109. vanna/examples/custom_system_prompt_example.py +174 -0
  110. vanna/examples/default_workflow_handler_example.py +208 -0
  111. vanna/examples/email_auth_example.py +340 -0
  112. vanna/examples/evaluation_example.py +269 -0
  113. vanna/examples/extensibility_example.py +262 -0
  114. vanna/examples/minimal_example.py +67 -0
  115. vanna/examples/mock_auth_example.py +227 -0
  116. vanna/examples/mock_custom_tool.py +311 -0
  117. vanna/examples/mock_quickstart.py +79 -0
  118. vanna/examples/mock_quota_example.py +145 -0
  119. vanna/examples/mock_rich_components_demo.py +396 -0
  120. vanna/examples/mock_sqlite_example.py +223 -0
  121. vanna/examples/openai_quickstart.py +83 -0
  122. vanna/examples/primitive_components_demo.py +305 -0
  123. vanna/examples/quota_lifecycle_example.py +139 -0
  124. vanna/examples/visualization_example.py +251 -0
  125. vanna/integrations/__init__.py +17 -0
  126. vanna/integrations/anthropic/__init__.py +9 -0
  127. vanna/integrations/anthropic/llm.py +270 -0
  128. vanna/integrations/azureopenai/__init__.py +9 -0
  129. vanna/integrations/azureopenai/llm.py +329 -0
  130. vanna/integrations/azuresearch/__init__.py +7 -0
  131. vanna/integrations/azuresearch/agent_memory.py +413 -0
  132. vanna/integrations/bigquery/__init__.py +5 -0
  133. vanna/integrations/bigquery/sql_runner.py +81 -0
  134. vanna/integrations/chromadb/__init__.py +104 -0
  135. vanna/integrations/chromadb/agent_memory.py +488 -0
  136. vanna/integrations/clickhouse/__init__.py +5 -0
  137. vanna/integrations/clickhouse/sql_runner.py +82 -0
  138. vanna/integrations/duckdb/__init__.py +5 -0
  139. vanna/integrations/duckdb/sql_runner.py +65 -0
  140. vanna/integrations/faiss/__init__.py +7 -0
  141. vanna/integrations/faiss/agent_memory.py +435 -0
  142. vanna/integrations/google/__init__.py +9 -0
  143. vanna/integrations/google/gemini.py +370 -0
  144. vanna/integrations/hive/__init__.py +5 -0
  145. vanna/integrations/hive/sql_runner.py +87 -0
  146. vanna/integrations/local/__init__.py +17 -0
  147. vanna/integrations/local/agent_memory/__init__.py +7 -0
  148. vanna/integrations/local/agent_memory/in_memory.py +285 -0
  149. vanna/integrations/local/audit.py +59 -0
  150. vanna/integrations/local/file_system.py +242 -0
  151. vanna/integrations/local/file_system_conversation_store.py +255 -0
  152. vanna/integrations/local/storage.py +62 -0
  153. vanna/integrations/marqo/__init__.py +7 -0
  154. vanna/integrations/marqo/agent_memory.py +354 -0
  155. vanna/integrations/milvus/__init__.py +7 -0
  156. vanna/integrations/milvus/agent_memory.py +458 -0
  157. vanna/integrations/mock/__init__.py +9 -0
  158. vanna/integrations/mock/llm.py +65 -0
  159. vanna/integrations/mssql/__init__.py +5 -0
  160. vanna/integrations/mssql/sql_runner.py +66 -0
  161. vanna/integrations/mysql/__init__.py +5 -0
  162. vanna/integrations/mysql/sql_runner.py +92 -0
  163. vanna/integrations/ollama/__init__.py +7 -0
  164. vanna/integrations/ollama/llm.py +252 -0
  165. vanna/integrations/openai/__init__.py +10 -0
  166. vanna/integrations/openai/llm.py +267 -0
  167. vanna/integrations/openai/responses.py +163 -0
  168. vanna/integrations/opensearch/__init__.py +7 -0
  169. vanna/integrations/opensearch/agent_memory.py +411 -0
  170. vanna/integrations/oracle/__init__.py +5 -0
  171. vanna/integrations/oracle/sql_runner.py +75 -0
  172. vanna/integrations/pinecone/__init__.py +7 -0
  173. vanna/integrations/pinecone/agent_memory.py +329 -0
  174. vanna/integrations/plotly/__init__.py +5 -0
  175. vanna/integrations/plotly/chart_generator.py +313 -0
  176. vanna/integrations/postgres/__init__.py +9 -0
  177. vanna/integrations/postgres/sql_runner.py +112 -0
  178. vanna/integrations/premium/agent_memory/__init__.py +7 -0
  179. vanna/integrations/premium/agent_memory/premium.py +186 -0
  180. vanna/integrations/presto/__init__.py +5 -0
  181. vanna/integrations/presto/sql_runner.py +107 -0
  182. vanna/integrations/qdrant/__init__.py +7 -0
  183. vanna/integrations/qdrant/agent_memory.py +466 -0
  184. vanna/integrations/snowflake/__init__.py +5 -0
  185. vanna/integrations/snowflake/sql_runner.py +147 -0
  186. vanna/integrations/sqlite/__init__.py +9 -0
  187. vanna/integrations/sqlite/sql_runner.py +65 -0
  188. vanna/integrations/weaviate/__init__.py +7 -0
  189. vanna/integrations/weaviate/agent_memory.py +428 -0
  190. vanna/legacy/ZhipuAI/ZhipuAI_Chat.py +233 -0
  191. vanna/legacy/ZhipuAI/ZhipuAI_embeddings.py +79 -0
  192. vanna/legacy/ZhipuAI/__init__.py +2 -0
  193. vanna/legacy/__init__.py +403 -0
  194. vanna/legacy/adapter.py +468 -0
  195. vanna/legacy/advanced/__init__.py +28 -0
  196. vanna/legacy/anthropic/__init__.py +1 -0
  197. vanna/legacy/anthropic/anthropic_chat.py +80 -0
  198. vanna/legacy/azuresearch/__init__.py +1 -0
  199. vanna/legacy/azuresearch/azuresearch_vector.py +274 -0
  200. vanna/legacy/base/__init__.py +1 -0
  201. vanna/legacy/base/base.py +2133 -0
  202. vanna/legacy/base/safe_exec.py +190 -0
  203. vanna/legacy/bedrock/__init__.py +1 -0
  204. vanna/legacy/bedrock/bedrock_converse.py +86 -0
  205. vanna/legacy/chromadb/__init__.py +1 -0
  206. vanna/legacy/chromadb/chromadb_vector.py +259 -0
  207. vanna/legacy/cohere/__init__.py +2 -0
  208. vanna/legacy/cohere/cohere_chat.py +99 -0
  209. vanna/legacy/cohere/cohere_embeddings.py +77 -0
  210. vanna/legacy/deepseek/__init__.py +1 -0
  211. vanna/legacy/deepseek/deepseek_chat.py +59 -0
  212. vanna/legacy/exceptions/__init__.py +46 -0
  213. vanna/legacy/faiss/__init__.py +1 -0
  214. vanna/legacy/faiss/faiss.py +230 -0
  215. vanna/legacy/flask/__init__.py +1355 -0
  216. vanna/legacy/flask/assets.py +58 -0
  217. vanna/legacy/flask/auth.py +56 -0
  218. vanna/legacy/google/__init__.py +2 -0
  219. vanna/legacy/google/bigquery_vector.py +293 -0
  220. vanna/legacy/google/gemini_chat.py +78 -0
  221. vanna/legacy/hf/__init__.py +1 -0
  222. vanna/legacy/hf/hf.py +80 -0
  223. vanna/legacy/local.py +8 -0
  224. vanna/legacy/marqo/__init__.py +1 -0
  225. vanna/legacy/marqo/marqo.py +168 -0
  226. vanna/legacy/milvus/__init__.py +1 -0
  227. vanna/legacy/milvus/milvus_vector.py +328 -0
  228. vanna/legacy/mistral/__init__.py +1 -0
  229. vanna/legacy/mistral/mistral.py +51 -0
  230. vanna/legacy/mock/__init__.py +3 -0
  231. vanna/legacy/mock/embedding.py +11 -0
  232. vanna/legacy/mock/llm.py +18 -0
  233. vanna/legacy/mock/vectordb.py +67 -0
  234. vanna/legacy/ollama/__init__.py +1 -0
  235. vanna/legacy/ollama/ollama.py +110 -0
  236. vanna/legacy/openai/__init__.py +2 -0
  237. vanna/legacy/openai/openai_chat.py +124 -0
  238. vanna/legacy/openai/openai_embeddings.py +46 -0
  239. vanna/legacy/opensearch/__init__.py +2 -0
  240. vanna/legacy/opensearch/opensearch_vector.py +369 -0
  241. vanna/legacy/opensearch/opensearch_vector_semantic.py +200 -0
  242. vanna/legacy/oracle/__init__.py +1 -0
  243. vanna/legacy/oracle/oracle_vector.py +584 -0
  244. vanna/legacy/pgvector/__init__.py +1 -0
  245. vanna/legacy/pgvector/pgvector.py +282 -0
  246. vanna/legacy/pinecone/__init__.py +3 -0
  247. vanna/legacy/pinecone/pinecone_vector.py +275 -0
  248. vanna/legacy/qdrant/__init__.py +3 -0
  249. vanna/legacy/qdrant/qdrant.py +329 -0
  250. vanna/legacy/qianfan/Qianfan_Chat.py +170 -0
  251. vanna/legacy/qianfan/Qianfan_embeddings.py +36 -0
  252. vanna/legacy/qianfan/__init__.py +2 -0
  253. vanna/legacy/qianwen/QianwenAI_chat.py +132 -0
  254. vanna/legacy/qianwen/QianwenAI_embeddings.py +46 -0
  255. vanna/legacy/qianwen/__init__.py +2 -0
  256. vanna/legacy/remote.py +79 -0
  257. vanna/legacy/types/__init__.py +292 -0
  258. vanna/legacy/utils.py +72 -0
  259. vanna/legacy/vannadb/__init__.py +1 -0
  260. vanna/legacy/vannadb/vannadb_vector.py +468 -0
  261. vanna/legacy/vllm/__init__.py +1 -0
  262. vanna/legacy/vllm/vllm.py +97 -0
  263. vanna/legacy/weaviate/__init__.py +1 -0
  264. vanna/legacy/weaviate/weaviate_vector.py +194 -0
  265. vanna/legacy/xinference/__init__.py +1 -0
  266. vanna/legacy/xinference/xinference.py +53 -0
  267. vanna/py.typed +0 -0
  268. vanna/servers/__init__.py +16 -0
  269. vanna/servers/__main__.py +8 -0
  270. vanna/servers/base/__init__.py +18 -0
  271. vanna/servers/base/chat_handler.py +65 -0
  272. vanna/servers/base/models.py +111 -0
  273. vanna/servers/base/rich_chat_handler.py +141 -0
  274. vanna/servers/base/templates.py +331 -0
  275. vanna/servers/cli/__init__.py +7 -0
  276. vanna/servers/cli/server_runner.py +204 -0
  277. vanna/servers/fastapi/__init__.py +7 -0
  278. vanna/servers/fastapi/app.py +163 -0
  279. vanna/servers/fastapi/routes.py +183 -0
  280. vanna/servers/flask/__init__.py +7 -0
  281. vanna/servers/flask/app.py +132 -0
  282. vanna/servers/flask/routes.py +137 -0
  283. vanna/tools/__init__.py +41 -0
  284. vanna/tools/agent_memory.py +322 -0
  285. vanna/tools/file_system.py +879 -0
  286. vanna/tools/python.py +222 -0
  287. vanna/tools/run_sql.py +173 -0
  288. vanna/tools/visualize_data.py +195 -0
  289. vanna/utils/__init__.py +0 -0
  290. vanna/utils/sql_safety.py +84 -0
  291. vanna/web_components/__init__.py +44 -0
@@ -0,0 +1,194 @@
1
+ import weaviate
2
+ import weaviate.classes as wvc
3
+ from fastembed import TextEmbedding
4
+
5
+ from vanna.base import VannaBase
6
+
7
+
8
+ class WeaviateDatabase(VannaBase):
9
+ def __init__(self, config=None):
10
+ """
11
+ Initialize the VannaEnhanced class with the provided configuration.
12
+
13
+ :param config: Dictionary containing configuration parameters.
14
+
15
+ params:
16
+ weaviate_url (str): Weaviate cluster URL while using weaviate cloud,
17
+ weaviate_api_key (str): Weaviate API key while using weaviate cloud,
18
+ weaviate_port (num): Weaviate port while using local weaviate,
19
+ weaviate_grpc (num): Weaviate gRPC port while using local weaviate,
20
+ fastembed_model (str): Fastembed model name for text embeddings. BAAI/bge-small-en-v1.5 by default.
21
+
22
+ """
23
+ super().__init__(config=config)
24
+
25
+ if config is None:
26
+ raise ValueError("config is required")
27
+
28
+ self.n_results = config.get("n_results", 3)
29
+ self.fastembed_model = config.get("fastembed_model", "BAAI/bge-small-en-v1.5")
30
+ self.weaviate_api_key = config.get("weaviate_api_key")
31
+ self.weaviate_url = config.get("weaviate_url")
32
+ self.weaviate_port = config.get("weaviate_port")
33
+ self.weaviate_grpc_port = config.get("weaviate_grpc", 50051)
34
+
35
+ if not self.weaviate_api_key and not self.weaviate_port:
36
+ raise ValueError("Add proper credentials to connect to weaviate")
37
+
38
+ self.weaviate_client = self._initialize_weaviate_client()
39
+ self.embeddings = TextEmbedding(model_name=self.fastembed_model)
40
+
41
+ self.training_data_cluster = {
42
+ "sql": "SQLTrainingDataEntry",
43
+ "ddl": "DDLEntry",
44
+ "doc": "DocumentationEntry",
45
+ }
46
+
47
+ self._create_collections_if_not_exist()
48
+
49
+ def _create_collections_if_not_exist(self):
50
+ properties_dict = {
51
+ self.training_data_cluster["ddl"]: [
52
+ wvc.config.Property(
53
+ name="description", data_type=wvc.config.DataType.TEXT
54
+ ),
55
+ ],
56
+ self.training_data_cluster["doc"]: [
57
+ wvc.config.Property(
58
+ name="description", data_type=wvc.config.DataType.TEXT
59
+ ),
60
+ ],
61
+ self.training_data_cluster["sql"]: [
62
+ wvc.config.Property(name="sql", data_type=wvc.config.DataType.TEXT),
63
+ wvc.config.Property(
64
+ name="natural_language_question", data_type=wvc.config.DataType.TEXT
65
+ ),
66
+ ],
67
+ }
68
+
69
+ for cluster, properties in properties_dict.items():
70
+ if not self.weaviate_client.collections.exists(cluster):
71
+ self.weaviate_client.collections.create(
72
+ name=cluster, properties=properties
73
+ )
74
+
75
+ def _initialize_weaviate_client(self):
76
+ if self.weaviate_api_key:
77
+ return weaviate.connect_to_wcs(
78
+ cluster_url=self.weaviate_url,
79
+ auth_credentials=weaviate.auth.AuthApiKey(self.weaviate_api_key),
80
+ additional_config=weaviate.config.AdditionalConfig(timeout=(10, 300)),
81
+ skip_init_checks=True,
82
+ )
83
+ else:
84
+ return weaviate.connect_to_local(
85
+ port=self.weaviate_port,
86
+ grpc_port=self.weaviate_grpc_port,
87
+ additional_config=weaviate.config.AdditionalConfig(timeout=(10, 300)),
88
+ skip_init_checks=True,
89
+ )
90
+
91
+ def generate_embedding(self, data: str, **kwargs):
92
+ embedding_model = TextEmbedding(model_name=self.fastembed_model)
93
+ embedding = next(embedding_model.embed(data))
94
+ return embedding.tolist()
95
+
96
+ def _insert_data(self, cluster_key: str, data_object: dict, vector: list) -> str:
97
+ self.weaviate_client.connect()
98
+ response = self.weaviate_client.collections.get(
99
+ self.training_data_cluster[cluster_key]
100
+ ).data.insert(properties=data_object, vector=vector)
101
+ self.weaviate_client.close()
102
+ return response
103
+
104
+ def add_ddl(self, ddl: str, **kwargs) -> str:
105
+ data_object = {
106
+ "description": ddl,
107
+ }
108
+ response = self._insert_data("ddl", data_object, self.generate_embedding(ddl))
109
+ return f"{response}-ddl"
110
+
111
+ def add_documentation(self, doc: str, **kwargs) -> str:
112
+ data_object = {
113
+ "description": doc,
114
+ }
115
+ response = self._insert_data("doc", data_object, self.generate_embedding(doc))
116
+ return f"{response}-doc"
117
+
118
+ def add_question_sql(self, question: str, sql: str, **kwargs) -> str:
119
+ data_object = {
120
+ "sql": sql,
121
+ "natural_language_question": question,
122
+ }
123
+ response = self._insert_data(
124
+ "sql", data_object, self.generate_embedding(question)
125
+ )
126
+ return f"{response}-sql"
127
+
128
+ def _query_collection(
129
+ self, cluster_key: str, vector_input: list, return_properties: list
130
+ ) -> list:
131
+ self.weaviate_client.connect()
132
+ collection = self.weaviate_client.collections.get(
133
+ self.training_data_cluster[cluster_key]
134
+ )
135
+ response = collection.query.near_vector(
136
+ near_vector=vector_input,
137
+ limit=self.n_results,
138
+ return_properties=return_properties,
139
+ )
140
+ response_list = [item.properties for item in response.objects]
141
+ self.weaviate_client.close()
142
+ return response_list
143
+
144
+ def get_related_ddl(self, question: str, **kwargs) -> list:
145
+ vector_input = self.generate_embedding(question)
146
+ response_list = self._query_collection("ddl", vector_input, ["description"])
147
+ return [item["description"] for item in response_list]
148
+
149
+ def get_related_documentation(self, question: str, **kwargs) -> list:
150
+ vector_input = self.generate_embedding(question)
151
+ response_list = self._query_collection("doc", vector_input, ["description"])
152
+ return [item["description"] for item in response_list]
153
+
154
+ def get_similar_question_sql(self, question: str, **kwargs) -> list:
155
+ vector_input = self.generate_embedding(question)
156
+ response_list = self._query_collection(
157
+ "sql", vector_input, ["sql", "natural_language_question"]
158
+ )
159
+ return [
160
+ {"question": item["natural_language_question"], "sql": item["sql"]}
161
+ for item in response_list
162
+ ]
163
+
164
+ def get_training_data(self, **kwargs) -> list:
165
+ self.weaviate_client.connect()
166
+ combined_response_list = []
167
+ for collection_name in self.training_data_cluster.values():
168
+ if self.weaviate_client.collections.exists(collection_name):
169
+ collection = self.weaviate_client.collections.get(collection_name)
170
+ response_list = [item.properties for item in collection.iterator()]
171
+ combined_response_list.extend(response_list)
172
+ self.weaviate_client.close()
173
+ return combined_response_list
174
+
175
+ def remove_training_data(self, id: str, **kwargs) -> bool:
176
+ self.weaviate_client.connect()
177
+ success = False
178
+ if id.endswith("-sql"):
179
+ id = id.replace("-sql", "")
180
+ success = self.weaviate_client.collections.get(
181
+ self.training_data_cluster["sql"]
182
+ ).data.delete_by_id(id)
183
+ elif id.endswith("-ddl"):
184
+ id = id.replace("-ddl", "")
185
+ success = self.weaviate_client.collections.get(
186
+ self.training_data_cluster["ddl"]
187
+ ).data.delete_by_id(id)
188
+ elif id.endswith("-doc"):
189
+ id = id.replace("-doc", "")
190
+ success = self.weaviate_client.collections.get(
191
+ self.training_data_cluster["doc"]
192
+ ).data.delete_by_id(id)
193
+ self.weaviate_client.close()
194
+ return success
@@ -0,0 +1 @@
1
+ from .xinference import Xinference
@@ -0,0 +1,53 @@
1
+ from xinference_client.client.restful.restful_client import (
2
+ Client,
3
+ RESTfulChatModelHandle,
4
+ )
5
+
6
+ from ..base import VannaBase
7
+
8
+
9
+ class Xinference(VannaBase):
10
+ def __init__(self, config=None):
11
+ VannaBase.__init__(self, config=config)
12
+
13
+ if not config or "base_url" not in config:
14
+ raise ValueError("config must contain at least Xinference base_url")
15
+
16
+ base_url = config["base_url"]
17
+ api_key = config.get("api_key", "not empty")
18
+ self.xinference_client = Client(base_url=base_url, api_key=api_key)
19
+
20
+ def system_message(self, message: str) -> any:
21
+ return {"role": "system", "content": message}
22
+
23
+ def user_message(self, message: str) -> any:
24
+ return {"role": "user", "content": message}
25
+
26
+ def assistant_message(self, message: str) -> any:
27
+ return {"role": "assistant", "content": message}
28
+
29
+ def submit_prompt(self, prompt, **kwargs) -> str:
30
+ if prompt is None:
31
+ raise Exception("Prompt is None")
32
+
33
+ if len(prompt) == 0:
34
+ raise Exception("Prompt is empty")
35
+
36
+ num_tokens = 0
37
+ for message in prompt:
38
+ num_tokens += len(message["content"]) / 4
39
+
40
+ model_uid = kwargs.get("model_uid") or self.config.get("model_uid", None)
41
+ if model_uid is None:
42
+ raise ValueError("model_uid is required")
43
+
44
+ xinference_model = self.xinference_client.get_model(model_uid)
45
+ if isinstance(xinference_model, RESTfulChatModelHandle):
46
+ print(f"Using model_uid {model_uid} for {num_tokens} tokens (approx)")
47
+
48
+ response = xinference_model.chat(prompt)
49
+ return response["choices"][0]["message"]["content"]
50
+ else:
51
+ raise NotImplementedError(
52
+ f"Xinference model handle type {type(xinference_model)} is not supported, required RESTfulChatModelHandle"
53
+ )
vanna/py.typed ADDED
File without changes
@@ -0,0 +1,16 @@
1
+ """
2
+ Server implementations for the Vanna Agents framework.
3
+
4
+ This module provides Flask and FastAPI server factories for serving
5
+ Vanna agents over HTTP with SSE, WebSocket, and polling endpoints.
6
+ """
7
+
8
+ from .base import ChatHandler, ChatRequest, ChatStreamChunk
9
+ from .cli.server_runner import ExampleAgentLoader
10
+
11
+ __all__ = [
12
+ "ChatHandler",
13
+ "ChatRequest",
14
+ "ChatStreamChunk",
15
+ "ExampleAgentLoader",
16
+ ]
@@ -0,0 +1,8 @@
1
+ """
2
+ Entry point for running Vanna Agents servers.
3
+ """
4
+
5
+ from .cli.server_runner import main
6
+
7
+ if __name__ == "__main__":
8
+ main()
@@ -0,0 +1,18 @@
1
+ """
2
+ Base server components for the Vanna Agents framework.
3
+
4
+ This module provides framework-agnostic components for handling chat
5
+ requests and responses.
6
+ """
7
+
8
+ from .chat_handler import ChatHandler
9
+ from .models import ChatRequest, ChatStreamChunk, ChatResponse
10
+ from .templates import INDEX_HTML
11
+
12
+ __all__ = [
13
+ "ChatHandler",
14
+ "ChatRequest",
15
+ "ChatStreamChunk",
16
+ "ChatResponse",
17
+ "INDEX_HTML",
18
+ ]
@@ -0,0 +1,65 @@
1
+ """
2
+ Framework-agnostic chat handling logic.
3
+ """
4
+
5
+ import uuid
6
+ from typing import AsyncGenerator, List
7
+
8
+ from ...core import Agent
9
+ from .models import ChatRequest, ChatResponse, ChatStreamChunk
10
+
11
+
12
+ class ChatHandler:
13
+ """Core chat handling logic - framework agnostic."""
14
+
15
+ def __init__(
16
+ self,
17
+ agent: Agent,
18
+ ):
19
+ """Initialize chat handler.
20
+
21
+ Args:
22
+ agent: The agent to handle chat requests
23
+ """
24
+ self.agent = agent
25
+
26
+ async def handle_stream(
27
+ self, request: ChatRequest
28
+ ) -> AsyncGenerator[ChatStreamChunk, None]:
29
+ """Stream chat responses.
30
+
31
+ Args:
32
+ request: Chat request
33
+
34
+ Yields:
35
+ Chat stream chunks
36
+ """
37
+ conversation_id = request.conversation_id or self._generate_conversation_id()
38
+ # Use request_id from client for tracking, or use the one generated internally
39
+ request_id = request.request_id or str(uuid.uuid4())
40
+
41
+ async for component in self.agent.send_message(
42
+ request_context=request.request_context,
43
+ message=request.message,
44
+ conversation_id=conversation_id,
45
+ ):
46
+ yield ChatStreamChunk.from_component(component, conversation_id, request_id)
47
+
48
+ async def handle_poll(self, request: ChatRequest) -> ChatResponse:
49
+ """Handle polling-based chat.
50
+
51
+ Args:
52
+ request: Chat request
53
+
54
+ Returns:
55
+ Complete chat response
56
+ """
57
+ chunks = []
58
+ async for chunk in self.handle_stream(request):
59
+ chunks.append(chunk)
60
+
61
+ return ChatResponse.from_chunks(chunks)
62
+
63
+ def _generate_conversation_id(self) -> str:
64
+ """Generate new conversation ID."""
65
+ return f"conv_{uuid.uuid4().hex[:8]}"
@@ -0,0 +1,111 @@
1
+ """
2
+ Request and response models for server endpoints.
3
+ """
4
+
5
+ import time
6
+ import uuid
7
+ from typing import Any, Dict, List, Optional, Union
8
+
9
+ from pydantic import BaseModel, Field
10
+
11
+ from ...components import UiComponent, RichComponent
12
+ from ...core.component_manager import ComponentUpdate
13
+ from ...core.user.request_context import RequestContext
14
+
15
+
16
+ class ChatRequest(BaseModel):
17
+ """Request model for chat endpoints."""
18
+
19
+ message: str = Field(description="User message")
20
+ conversation_id: Optional[str] = Field(default=None, description="Conversation ID")
21
+ request_id: Optional[str] = Field(
22
+ default=None, description="Request ID for tracing"
23
+ )
24
+ request_context: RequestContext = Field(
25
+ default_factory=RequestContext,
26
+ description="Request context for user resolution",
27
+ )
28
+ metadata: Dict[str, Any] = Field(
29
+ default_factory=dict, description="Additional metadata"
30
+ )
31
+
32
+
33
+ class ChatStreamChunk(BaseModel):
34
+ """Single chunk in a streaming chat response."""
35
+
36
+ rich: Dict[str, Any] = Field(description="Rich component data for advanced UIs")
37
+ simple: Optional[Dict[str, Any]] = Field(
38
+ default=None, description="Simple component data for basic UIs"
39
+ )
40
+
41
+ # Stream metadata
42
+ conversation_id: str = Field(description="Conversation ID")
43
+ request_id: str = Field(description="Request ID")
44
+ timestamp: float = Field(default_factory=time.time, description="Timestamp")
45
+
46
+ @classmethod
47
+ def from_component(
48
+ cls,
49
+ component: Union[UiComponent, RichComponent],
50
+ conversation_id: str,
51
+ request_id: str,
52
+ ) -> "ChatStreamChunk":
53
+ """Create chunk from UI component or rich component."""
54
+
55
+ if isinstance(component, UiComponent):
56
+ # Full UiComponent with both rich and simple
57
+ rich_data = component.rich_component.serialize_for_frontend()
58
+ simple_data = None
59
+ if component.simple_component:
60
+ simple_data = component.simple_component.serialize_for_frontend()
61
+
62
+ return cls(
63
+ rich=rich_data,
64
+ simple=simple_data,
65
+ conversation_id=conversation_id,
66
+ request_id=request_id,
67
+ )
68
+
69
+ # Rich component only (no simple fallback)
70
+ rich_data = component.serialize_for_frontend()
71
+ return cls(
72
+ rich=rich_data,
73
+ simple=None,
74
+ conversation_id=conversation_id,
75
+ request_id=request_id,
76
+ )
77
+
78
+ @classmethod
79
+ def from_component_update(
80
+ cls, update: ComponentUpdate, conversation_id: str, request_id: str
81
+ ) -> "ChatStreamChunk":
82
+ """Create chunk from component update."""
83
+ update_payload = update.serialize_for_frontend()
84
+ return cls(
85
+ rich=update_payload,
86
+ simple=None, # Component updates don't have simple representations
87
+ conversation_id=conversation_id,
88
+ request_id=request_id,
89
+ )
90
+
91
+
92
+ class ChatResponse(BaseModel):
93
+ """Complete chat response for polling endpoints."""
94
+
95
+ chunks: List[ChatStreamChunk] = Field(description="Response chunks")
96
+ conversation_id: str = Field(description="Conversation ID")
97
+ request_id: str = Field(description="Request ID")
98
+ total_chunks: int = Field(description="Total number of chunks")
99
+
100
+ @classmethod
101
+ def from_chunks(cls, chunks: List[ChatStreamChunk]) -> "ChatResponse":
102
+ """Create response from chunks."""
103
+ if not chunks:
104
+ return cls(chunks=[], conversation_id="", request_id="", total_chunks=0)
105
+
106
+ return cls(
107
+ chunks=chunks,
108
+ conversation_id=chunks[0].conversation_id,
109
+ request_id=chunks[0].request_id,
110
+ total_chunks=len(chunks),
111
+ )
@@ -0,0 +1,141 @@
1
+ # """
2
+ # Rich component-aware chat handling logic.
3
+ # """
4
+
5
+ # import uuid
6
+ # from typing import AsyncGenerator, Callable, List, Optional, Union
7
+
8
+ # from ...core import Agent, User
9
+ # from ...core.rich_components import RichComponent
10
+ # from ...core.component_manager import ComponentManager, ComponentUpdate
11
+ # from .models import ChatRequest, ChatResponse, ChatStreamChunk
12
+
13
+
14
+ # class RichChatHandler:
15
+ # """Rich component-aware chat handling logic."""
16
+
17
+ # def __init__(
18
+ # self,
19
+ # agent: Agent,
20
+ # default_user_factory: Optional[Callable[[Optional[str]], User]] = None,
21
+ # ):
22
+ # """Initialize rich chat handler.
23
+
24
+ # Args:
25
+ # agent: The agent to handle chat requests
26
+ # default_user_factory: Function to create default user from user_id
27
+ # """
28
+ # self.agent = agent
29
+ # self.default_user_factory = default_user_factory or self._create_default_user
30
+ # self.component_managers: dict[str, ComponentManager] = {} # Per conversation
31
+
32
+ # async def handle_stream(
33
+ # self, request: ChatRequest
34
+ # ) -> AsyncGenerator[ChatStreamChunk, None]:
35
+ # """Stream chat responses with rich component support.
36
+
37
+ # Args:
38
+ # request: Chat request
39
+
40
+ # Yields:
41
+ # Chat stream chunks including rich component updates
42
+ # """
43
+ # user = self._resolve_user(request.user_id)
44
+ # conversation_id = request.conversation_id or self._generate_conversation_id()
45
+ # request_id = request.request_id or str(uuid.uuid4())
46
+
47
+ # # Get or create component manager for this conversation
48
+ # if conversation_id not in self.component_managers:
49
+ # self.component_managers[conversation_id] = ComponentManager()
50
+
51
+ # component_manager = self.component_managers[conversation_id]
52
+
53
+ # async for component in self.agent.send_message(
54
+ # conversation_id=conversation_id,
55
+ # user=user,
56
+ # message=request.message,
57
+ # request_id=request_id,
58
+ # ):
59
+ # if isinstance(component, RichComponent):
60
+ # # Handle rich component through manager
61
+ # update = component_manager.emit(component)
62
+ # yield ChatStreamChunk.from_component_update(update, conversation_id, request_id)
63
+ # else:
64
+ # # Handle legacy components
65
+ # yield ChatStreamChunk.from_component(component, conversation_id, request_id)
66
+
67
+ # async def handle_poll(self, request: ChatRequest) -> ChatResponse:
68
+ # """Handle polling request with rich component support.
69
+
70
+ # Args:
71
+ # request: Chat request
72
+
73
+ # Returns:
74
+ # Complete chat response with all components
75
+ # """
76
+ # chunks: List[ChatStreamChunk] = []
77
+
78
+ # async for chunk in self.handle_stream(request):
79
+ # chunks.append(chunk)
80
+
81
+ # return ChatResponse.from_chunks(chunks)
82
+
83
+ # def get_component_manager(self, conversation_id: str) -> Optional[ComponentManager]:
84
+ # """Get the component manager for a conversation."""
85
+ # return self.component_managers.get(conversation_id)
86
+
87
+ # def get_component(self, conversation_id: str, component_id: str) -> Optional[RichComponent]:
88
+ # """Get a specific component from a conversation."""
89
+ # manager = self.get_component_manager(conversation_id)
90
+ # return manager.get_component(component_id) if manager else None
91
+
92
+ # def get_all_components(self, conversation_id: str) -> List[RichComponent]:
93
+ # """Get all components in a conversation."""
94
+ # manager = self.get_component_manager(conversation_id)
95
+ # return manager.get_all_components() if manager else []
96
+
97
+ # def update_component(
98
+ # self,
99
+ # conversation_id: str,
100
+ # component_id: str,
101
+ # **updates
102
+ # ) -> Optional[ComponentUpdate]:
103
+ # """Update a component in a conversation."""
104
+ # manager = self.get_component_manager(conversation_id)
105
+ # return manager.update_component(component_id, **updates) if manager else None
106
+
107
+ # def remove_component(
108
+ # self,
109
+ # conversation_id: str,
110
+ # component_id: str
111
+ # ) -> Optional[ComponentUpdate]:
112
+ # """Remove a component from a conversation."""
113
+ # manager = self.get_component_manager(conversation_id)
114
+ # return manager.remove_component(component_id) if manager else None
115
+
116
+ # def clear_conversation_components(self, conversation_id: str):
117
+ # """Clear all components for a conversation."""
118
+ # if conversation_id in self.component_managers:
119
+ # del self.component_managers[conversation_id]
120
+
121
+ # def _resolve_user(self, user_id: Optional[str]) -> User:
122
+ # """Resolve user from ID or create default."""
123
+ # if user_id:
124
+ # # In a real implementation, you'd fetch from a user store
125
+ # return User(id=user_id, username=f"user_{user_id}", email="", permissions=[])
126
+
127
+ # return self.default_user_factory(user_id)
128
+
129
+ # def _create_default_user(self, user_id: Optional[str]) -> User:
130
+ # """Create a default user."""
131
+ # user_id = user_id or "anonymous"
132
+ # return User(
133
+ # id=user_id,
134
+ # username=f"user_{user_id}",
135
+ # email="",
136
+ # permissions=[]
137
+ # )
138
+
139
+ # def _generate_conversation_id(self) -> str:
140
+ # """Generate a new conversation ID."""
141
+ # return str(uuid.uuid4())