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.
Files changed (302) hide show
  1. vanna/__init__.py +167 -395
  2. vanna/agents/__init__.py +7 -0
  3. vanna/capabilities/__init__.py +17 -0
  4. vanna/capabilities/agent_memory/__init__.py +21 -0
  5. vanna/capabilities/agent_memory/base.py +103 -0
  6. vanna/capabilities/agent_memory/models.py +53 -0
  7. vanna/capabilities/file_system/__init__.py +14 -0
  8. vanna/capabilities/file_system/base.py +71 -0
  9. vanna/capabilities/file_system/models.py +25 -0
  10. vanna/capabilities/sql_runner/__init__.py +13 -0
  11. vanna/capabilities/sql_runner/base.py +37 -0
  12. vanna/capabilities/sql_runner/models.py +13 -0
  13. vanna/components/__init__.py +92 -0
  14. vanna/components/base.py +11 -0
  15. vanna/components/rich/__init__.py +83 -0
  16. vanna/components/rich/containers/__init__.py +7 -0
  17. vanna/components/rich/containers/card.py +20 -0
  18. vanna/components/rich/data/__init__.py +9 -0
  19. vanna/components/rich/data/chart.py +17 -0
  20. vanna/components/rich/data/dataframe.py +93 -0
  21. vanna/components/rich/feedback/__init__.py +21 -0
  22. vanna/components/rich/feedback/badge.py +16 -0
  23. vanna/components/rich/feedback/icon_text.py +14 -0
  24. vanna/components/rich/feedback/log_viewer.py +41 -0
  25. vanna/components/rich/feedback/notification.py +19 -0
  26. vanna/components/rich/feedback/progress.py +37 -0
  27. vanna/components/rich/feedback/status_card.py +28 -0
  28. vanna/components/rich/feedback/status_indicator.py +14 -0
  29. vanna/components/rich/interactive/__init__.py +21 -0
  30. vanna/components/rich/interactive/button.py +95 -0
  31. vanna/components/rich/interactive/task_list.py +58 -0
  32. vanna/components/rich/interactive/ui_state.py +93 -0
  33. vanna/components/rich/specialized/__init__.py +7 -0
  34. vanna/components/rich/specialized/artifact.py +20 -0
  35. vanna/components/rich/text.py +16 -0
  36. vanna/components/simple/__init__.py +15 -0
  37. vanna/components/simple/image.py +15 -0
  38. vanna/components/simple/link.py +15 -0
  39. vanna/components/simple/text.py +11 -0
  40. vanna/core/__init__.py +193 -0
  41. vanna/core/_compat.py +19 -0
  42. vanna/core/agent/__init__.py +10 -0
  43. vanna/core/agent/agent.py +1407 -0
  44. vanna/core/agent/config.py +123 -0
  45. vanna/core/audit/__init__.py +28 -0
  46. vanna/core/audit/base.py +299 -0
  47. vanna/core/audit/models.py +131 -0
  48. vanna/core/component_manager.py +329 -0
  49. vanna/core/components.py +53 -0
  50. vanna/core/enhancer/__init__.py +11 -0
  51. vanna/core/enhancer/base.py +94 -0
  52. vanna/core/enhancer/default.py +118 -0
  53. vanna/core/enricher/__init__.py +10 -0
  54. vanna/core/enricher/base.py +59 -0
  55. vanna/core/errors.py +47 -0
  56. vanna/core/evaluation/__init__.py +81 -0
  57. vanna/core/evaluation/base.py +186 -0
  58. vanna/core/evaluation/dataset.py +254 -0
  59. vanna/core/evaluation/evaluators.py +376 -0
  60. vanna/core/evaluation/report.py +289 -0
  61. vanna/core/evaluation/runner.py +313 -0
  62. vanna/core/filter/__init__.py +10 -0
  63. vanna/core/filter/base.py +67 -0
  64. vanna/core/lifecycle/__init__.py +10 -0
  65. vanna/core/lifecycle/base.py +83 -0
  66. vanna/core/llm/__init__.py +16 -0
  67. vanna/core/llm/base.py +40 -0
  68. vanna/core/llm/models.py +61 -0
  69. vanna/core/middleware/__init__.py +10 -0
  70. vanna/core/middleware/base.py +69 -0
  71. vanna/core/observability/__init__.py +11 -0
  72. vanna/core/observability/base.py +88 -0
  73. vanna/core/observability/models.py +47 -0
  74. vanna/core/recovery/__init__.py +11 -0
  75. vanna/core/recovery/base.py +84 -0
  76. vanna/core/recovery/models.py +32 -0
  77. vanna/core/registry.py +278 -0
  78. vanna/core/rich_component.py +156 -0
  79. vanna/core/simple_component.py +27 -0
  80. vanna/core/storage/__init__.py +14 -0
  81. vanna/core/storage/base.py +46 -0
  82. vanna/core/storage/models.py +46 -0
  83. vanna/core/system_prompt/__init__.py +13 -0
  84. vanna/core/system_prompt/base.py +36 -0
  85. vanna/core/system_prompt/default.py +157 -0
  86. vanna/core/tool/__init__.py +18 -0
  87. vanna/core/tool/base.py +70 -0
  88. vanna/core/tool/models.py +84 -0
  89. vanna/core/user/__init__.py +17 -0
  90. vanna/core/user/base.py +29 -0
  91. vanna/core/user/models.py +25 -0
  92. vanna/core/user/request_context.py +70 -0
  93. vanna/core/user/resolver.py +42 -0
  94. vanna/core/validation.py +164 -0
  95. vanna/core/workflow/__init__.py +12 -0
  96. vanna/core/workflow/base.py +254 -0
  97. vanna/core/workflow/default.py +789 -0
  98. vanna/examples/__init__.py +1 -0
  99. vanna/examples/__main__.py +44 -0
  100. vanna/examples/anthropic_quickstart.py +80 -0
  101. vanna/examples/artifact_example.py +293 -0
  102. vanna/examples/claude_sqlite_example.py +236 -0
  103. vanna/examples/coding_agent_example.py +300 -0
  104. vanna/examples/custom_system_prompt_example.py +174 -0
  105. vanna/examples/default_workflow_handler_example.py +208 -0
  106. vanna/examples/email_auth_example.py +340 -0
  107. vanna/examples/evaluation_example.py +269 -0
  108. vanna/examples/extensibility_example.py +262 -0
  109. vanna/examples/minimal_example.py +67 -0
  110. vanna/examples/mock_auth_example.py +227 -0
  111. vanna/examples/mock_custom_tool.py +311 -0
  112. vanna/examples/mock_quickstart.py +79 -0
  113. vanna/examples/mock_quota_example.py +145 -0
  114. vanna/examples/mock_rich_components_demo.py +396 -0
  115. vanna/examples/mock_sqlite_example.py +223 -0
  116. vanna/examples/openai_quickstart.py +83 -0
  117. vanna/examples/primitive_components_demo.py +305 -0
  118. vanna/examples/quota_lifecycle_example.py +139 -0
  119. vanna/examples/visualization_example.py +251 -0
  120. vanna/integrations/__init__.py +17 -0
  121. vanna/integrations/anthropic/__init__.py +9 -0
  122. vanna/integrations/anthropic/llm.py +270 -0
  123. vanna/integrations/azureopenai/__init__.py +9 -0
  124. vanna/integrations/azureopenai/llm.py +329 -0
  125. vanna/integrations/azuresearch/__init__.py +7 -0
  126. vanna/integrations/azuresearch/agent_memory.py +413 -0
  127. vanna/integrations/bigquery/__init__.py +5 -0
  128. vanna/integrations/bigquery/sql_runner.py +81 -0
  129. vanna/integrations/chromadb/__init__.py +104 -0
  130. vanna/integrations/chromadb/agent_memory.py +416 -0
  131. vanna/integrations/clickhouse/__init__.py +5 -0
  132. vanna/integrations/clickhouse/sql_runner.py +82 -0
  133. vanna/integrations/duckdb/__init__.py +5 -0
  134. vanna/integrations/duckdb/sql_runner.py +65 -0
  135. vanna/integrations/faiss/__init__.py +7 -0
  136. vanna/integrations/faiss/agent_memory.py +431 -0
  137. vanna/integrations/google/__init__.py +9 -0
  138. vanna/integrations/google/gemini.py +370 -0
  139. vanna/integrations/hive/__init__.py +5 -0
  140. vanna/integrations/hive/sql_runner.py +87 -0
  141. vanna/integrations/local/__init__.py +17 -0
  142. vanna/integrations/local/agent_memory/__init__.py +7 -0
  143. vanna/integrations/local/agent_memory/in_memory.py +285 -0
  144. vanna/integrations/local/audit.py +59 -0
  145. vanna/integrations/local/file_system.py +242 -0
  146. vanna/integrations/local/file_system_conversation_store.py +255 -0
  147. vanna/integrations/local/storage.py +62 -0
  148. vanna/integrations/marqo/__init__.py +7 -0
  149. vanna/integrations/marqo/agent_memory.py +354 -0
  150. vanna/integrations/milvus/__init__.py +7 -0
  151. vanna/integrations/milvus/agent_memory.py +458 -0
  152. vanna/integrations/mock/__init__.py +9 -0
  153. vanna/integrations/mock/llm.py +65 -0
  154. vanna/integrations/mssql/__init__.py +5 -0
  155. vanna/integrations/mssql/sql_runner.py +66 -0
  156. vanna/integrations/mysql/__init__.py +5 -0
  157. vanna/integrations/mysql/sql_runner.py +92 -0
  158. vanna/integrations/ollama/__init__.py +7 -0
  159. vanna/integrations/ollama/llm.py +252 -0
  160. vanna/integrations/openai/__init__.py +10 -0
  161. vanna/integrations/openai/llm.py +267 -0
  162. vanna/integrations/openai/responses.py +163 -0
  163. vanna/integrations/opensearch/__init__.py +7 -0
  164. vanna/integrations/opensearch/agent_memory.py +411 -0
  165. vanna/integrations/oracle/__init__.py +5 -0
  166. vanna/integrations/oracle/sql_runner.py +75 -0
  167. vanna/integrations/pinecone/__init__.py +7 -0
  168. vanna/integrations/pinecone/agent_memory.py +329 -0
  169. vanna/integrations/plotly/__init__.py +5 -0
  170. vanna/integrations/plotly/chart_generator.py +313 -0
  171. vanna/integrations/postgres/__init__.py +9 -0
  172. vanna/integrations/postgres/sql_runner.py +112 -0
  173. vanna/integrations/premium/agent_memory/__init__.py +7 -0
  174. vanna/integrations/premium/agent_memory/premium.py +186 -0
  175. vanna/integrations/presto/__init__.py +5 -0
  176. vanna/integrations/presto/sql_runner.py +107 -0
  177. vanna/integrations/qdrant/__init__.py +7 -0
  178. vanna/integrations/qdrant/agent_memory.py +439 -0
  179. vanna/integrations/snowflake/__init__.py +5 -0
  180. vanna/integrations/snowflake/sql_runner.py +147 -0
  181. vanna/integrations/sqlite/__init__.py +9 -0
  182. vanna/integrations/sqlite/sql_runner.py +65 -0
  183. vanna/integrations/weaviate/__init__.py +7 -0
  184. vanna/integrations/weaviate/agent_memory.py +428 -0
  185. vanna/{ZhipuAI → legacy/ZhipuAI}/ZhipuAI_embeddings.py +11 -11
  186. vanna/legacy/__init__.py +403 -0
  187. vanna/legacy/adapter.py +463 -0
  188. vanna/{advanced → legacy/advanced}/__init__.py +3 -1
  189. vanna/{anthropic → legacy/anthropic}/anthropic_chat.py +9 -7
  190. vanna/{azuresearch → legacy/azuresearch}/azuresearch_vector.py +79 -41
  191. vanna/{base → legacy/base}/base.py +224 -217
  192. vanna/legacy/bedrock/__init__.py +1 -0
  193. vanna/{bedrock → legacy/bedrock}/bedrock_converse.py +13 -12
  194. vanna/{chromadb → legacy/chromadb}/chromadb_vector.py +3 -1
  195. vanna/legacy/cohere/__init__.py +2 -0
  196. vanna/{cohere → legacy/cohere}/cohere_chat.py +19 -14
  197. vanna/{cohere → legacy/cohere}/cohere_embeddings.py +25 -19
  198. vanna/{deepseek → legacy/deepseek}/deepseek_chat.py +5 -6
  199. vanna/legacy/faiss/__init__.py +1 -0
  200. vanna/{faiss → legacy/faiss}/faiss.py +113 -59
  201. vanna/{flask → legacy/flask}/__init__.py +84 -43
  202. vanna/{flask → legacy/flask}/assets.py +5 -5
  203. vanna/{flask → legacy/flask}/auth.py +5 -4
  204. vanna/{google → legacy/google}/bigquery_vector.py +75 -42
  205. vanna/{google → legacy/google}/gemini_chat.py +7 -3
  206. vanna/{hf → legacy/hf}/hf.py +0 -1
  207. vanna/{milvus → legacy/milvus}/milvus_vector.py +58 -35
  208. vanna/{mock → legacy/mock}/llm.py +0 -1
  209. vanna/legacy/mock/vectordb.py +67 -0
  210. vanna/legacy/ollama/ollama.py +110 -0
  211. vanna/{openai → legacy/openai}/openai_chat.py +2 -6
  212. vanna/legacy/opensearch/opensearch_vector.py +369 -0
  213. vanna/legacy/opensearch/opensearch_vector_semantic.py +200 -0
  214. vanna/legacy/oracle/oracle_vector.py +584 -0
  215. vanna/{pgvector → legacy/pgvector}/pgvector.py +42 -13
  216. vanna/{qdrant → legacy/qdrant}/qdrant.py +2 -6
  217. vanna/legacy/qianfan/Qianfan_Chat.py +170 -0
  218. vanna/legacy/qianfan/Qianfan_embeddings.py +36 -0
  219. vanna/legacy/qianwen/QianwenAI_chat.py +132 -0
  220. vanna/{remote.py → legacy/remote.py} +28 -26
  221. vanna/{utils.py → legacy/utils.py} +6 -11
  222. vanna/{vannadb → legacy/vannadb}/vannadb_vector.py +115 -46
  223. vanna/{vllm → legacy/vllm}/vllm.py +5 -6
  224. vanna/{weaviate → legacy/weaviate}/weaviate_vector.py +59 -40
  225. vanna/{xinference → legacy/xinference}/xinference.py +6 -6
  226. vanna/py.typed +0 -0
  227. vanna/servers/__init__.py +16 -0
  228. vanna/servers/__main__.py +8 -0
  229. vanna/servers/base/__init__.py +18 -0
  230. vanna/servers/base/chat_handler.py +65 -0
  231. vanna/servers/base/models.py +111 -0
  232. vanna/servers/base/rich_chat_handler.py +141 -0
  233. vanna/servers/base/templates.py +331 -0
  234. vanna/servers/cli/__init__.py +7 -0
  235. vanna/servers/cli/server_runner.py +204 -0
  236. vanna/servers/fastapi/__init__.py +7 -0
  237. vanna/servers/fastapi/app.py +163 -0
  238. vanna/servers/fastapi/routes.py +183 -0
  239. vanna/servers/flask/__init__.py +7 -0
  240. vanna/servers/flask/app.py +132 -0
  241. vanna/servers/flask/routes.py +137 -0
  242. vanna/tools/__init__.py +41 -0
  243. vanna/tools/agent_memory.py +322 -0
  244. vanna/tools/file_system.py +879 -0
  245. vanna/tools/python.py +222 -0
  246. vanna/tools/run_sql.py +165 -0
  247. vanna/tools/visualize_data.py +195 -0
  248. vanna/utils/__init__.py +0 -0
  249. vanna/web_components/__init__.py +44 -0
  250. vanna-2.0.0rc1.dist-info/METADATA +868 -0
  251. vanna-2.0.0rc1.dist-info/RECORD +289 -0
  252. vanna-2.0.0rc1.dist-info/entry_points.txt +3 -0
  253. vanna/bedrock/__init__.py +0 -1
  254. vanna/cohere/__init__.py +0 -2
  255. vanna/faiss/__init__.py +0 -1
  256. vanna/mock/vectordb.py +0 -55
  257. vanna/ollama/ollama.py +0 -103
  258. vanna/opensearch/opensearch_vector.py +0 -392
  259. vanna/opensearch/opensearch_vector_semantic.py +0 -175
  260. vanna/oracle/oracle_vector.py +0 -585
  261. vanna/qianfan/Qianfan_Chat.py +0 -165
  262. vanna/qianfan/Qianfan_embeddings.py +0 -36
  263. vanna/qianwen/QianwenAI_chat.py +0 -133
  264. vanna-0.7.9.dist-info/METADATA +0 -408
  265. vanna-0.7.9.dist-info/RECORD +0 -79
  266. /vanna/{ZhipuAI → legacy/ZhipuAI}/ZhipuAI_Chat.py +0 -0
  267. /vanna/{ZhipuAI → legacy/ZhipuAI}/__init__.py +0 -0
  268. /vanna/{anthropic → legacy/anthropic}/__init__.py +0 -0
  269. /vanna/{azuresearch → legacy/azuresearch}/__init__.py +0 -0
  270. /vanna/{base → legacy/base}/__init__.py +0 -0
  271. /vanna/{chromadb → legacy/chromadb}/__init__.py +0 -0
  272. /vanna/{deepseek → legacy/deepseek}/__init__.py +0 -0
  273. /vanna/{exceptions → legacy/exceptions}/__init__.py +0 -0
  274. /vanna/{google → legacy/google}/__init__.py +0 -0
  275. /vanna/{hf → legacy/hf}/__init__.py +0 -0
  276. /vanna/{local.py → legacy/local.py} +0 -0
  277. /vanna/{marqo → legacy/marqo}/__init__.py +0 -0
  278. /vanna/{marqo → legacy/marqo}/marqo.py +0 -0
  279. /vanna/{milvus → legacy/milvus}/__init__.py +0 -0
  280. /vanna/{mistral → legacy/mistral}/__init__.py +0 -0
  281. /vanna/{mistral → legacy/mistral}/mistral.py +0 -0
  282. /vanna/{mock → legacy/mock}/__init__.py +0 -0
  283. /vanna/{mock → legacy/mock}/embedding.py +0 -0
  284. /vanna/{ollama → legacy/ollama}/__init__.py +0 -0
  285. /vanna/{openai → legacy/openai}/__init__.py +0 -0
  286. /vanna/{openai → legacy/openai}/openai_embeddings.py +0 -0
  287. /vanna/{opensearch → legacy/opensearch}/__init__.py +0 -0
  288. /vanna/{oracle → legacy/oracle}/__init__.py +0 -0
  289. /vanna/{pgvector → legacy/pgvector}/__init__.py +0 -0
  290. /vanna/{pinecone → legacy/pinecone}/__init__.py +0 -0
  291. /vanna/{pinecone → legacy/pinecone}/pinecone_vector.py +0 -0
  292. /vanna/{qdrant → legacy/qdrant}/__init__.py +0 -0
  293. /vanna/{qianfan → legacy/qianfan}/__init__.py +0 -0
  294. /vanna/{qianwen → legacy/qianwen}/QianwenAI_embeddings.py +0 -0
  295. /vanna/{qianwen → legacy/qianwen}/__init__.py +0 -0
  296. /vanna/{types → legacy/types}/__init__.py +0 -0
  297. /vanna/{vannadb → legacy/vannadb}/__init__.py +0 -0
  298. /vanna/{vllm → legacy/vllm}/__init__.py +0 -0
  299. /vanna/{weaviate → legacy/weaviate}/__init__.py +0 -0
  300. /vanna/{xinference → legacy/xinference}/__init__.py +0 -0
  301. {vanna-0.7.9.dist-info → vanna-2.0.0rc1.dist-info}/WHEEL +0 -0
  302. {vanna-0.7.9.dist-info → vanna-2.0.0rc1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,21 @@
1
+ """User feedback components."""
2
+
3
+ from .notification import NotificationComponent
4
+ from .status_card import StatusCardComponent
5
+ from .progress import ProgressBarComponent, ProgressDisplayComponent
6
+ from .status_indicator import StatusIndicatorComponent
7
+ from .log_viewer import LogViewerComponent, LogEntry
8
+ from .badge import BadgeComponent
9
+ from .icon_text import IconTextComponent
10
+
11
+ __all__ = [
12
+ "NotificationComponent",
13
+ "StatusCardComponent",
14
+ "ProgressBarComponent",
15
+ "ProgressDisplayComponent",
16
+ "StatusIndicatorComponent",
17
+ "LogViewerComponent",
18
+ "LogEntry",
19
+ "BadgeComponent",
20
+ "IconTextComponent",
21
+ ]
@@ -0,0 +1,16 @@
1
+ """Badge component for displaying status or labels."""
2
+
3
+ from typing import Optional
4
+ from ....core.rich_component import RichComponent, ComponentType
5
+
6
+
7
+ class BadgeComponent(RichComponent):
8
+ """Simple badge/pill component for displaying status or labels."""
9
+
10
+ type: ComponentType = ComponentType.BADGE
11
+ text: str
12
+ variant: str = (
13
+ "default" # "default", "primary", "success", "warning", "error", "info"
14
+ )
15
+ size: str = "medium" # "small", "medium", "large"
16
+ icon: Optional[str] = None
@@ -0,0 +1,14 @@
1
+ """Icon with text component."""
2
+
3
+ from ....core.rich_component import RichComponent, ComponentType
4
+
5
+
6
+ class IconTextComponent(RichComponent):
7
+ """Simple component for displaying an icon with text."""
8
+
9
+ type: ComponentType = ComponentType.ICON_TEXT
10
+ icon: str
11
+ text: str
12
+ variant: str = "default" # "default", "primary", "secondary", "muted"
13
+ size: str = "medium" # "small", "medium", "large"
14
+ alignment: str = "left" # "left", "center", "right"
@@ -0,0 +1,41 @@
1
+ """Log viewer component."""
2
+
3
+ import uuid
4
+ from datetime import datetime
5
+ from typing import Any, Dict, List, Optional
6
+ from pydantic import BaseModel, Field
7
+ from ....core.rich_component import RichComponent, ComponentType
8
+
9
+
10
+ class LogEntry(BaseModel):
11
+ """Log entry for tool execution."""
12
+
13
+ timestamp: str = Field(default_factory=lambda: datetime.utcnow().isoformat())
14
+ level: str = "info" # "debug", "info", "warning", "error"
15
+ message: str
16
+ data: Optional[Dict[str, Any]] = None
17
+
18
+
19
+ class LogViewerComponent(RichComponent):
20
+ """Generic log viewer for displaying timestamped entries."""
21
+
22
+ type: ComponentType = ComponentType.LOG_VIEWER
23
+ title: str = "Logs"
24
+ entries: List[LogEntry] = Field(default_factory=list)
25
+ max_entries: int = 100
26
+ searchable: bool = True
27
+ show_timestamps: bool = True
28
+ auto_scroll: bool = True
29
+
30
+ def add_entry(
31
+ self, message: str, level: str = "info", data: Optional[Dict[str, Any]] = None
32
+ ) -> "LogViewerComponent":
33
+ """Add a new log entry."""
34
+ new_entry = LogEntry(message=message, level=level, data=data)
35
+ new_entries = self.entries + [new_entry]
36
+
37
+ # Limit to max_entries
38
+ if len(new_entries) > self.max_entries:
39
+ new_entries = new_entries[-self.max_entries :]
40
+
41
+ return self.update(entries=new_entries)
@@ -0,0 +1,19 @@
1
+ """Notification component for alerts and messages."""
2
+
3
+ from typing import Any, Dict, List, Optional
4
+ from pydantic import Field
5
+ from ....core.rich_component import RichComponent, ComponentType
6
+
7
+
8
+ class NotificationComponent(RichComponent):
9
+ """Notification component for alerts and messages."""
10
+
11
+ type: ComponentType = ComponentType.NOTIFICATION
12
+ message: str
13
+ title: Optional[str] = None
14
+ level: str = "info" # "success", "info", "warning", "error"
15
+ icon: Optional[str] = None
16
+ dismissible: bool = True
17
+ auto_dismiss: bool = False
18
+ auto_dismiss_delay: int = 5000 # milliseconds
19
+ actions: List[Dict[str, Any]] = Field(default_factory=list)
@@ -0,0 +1,37 @@
1
+ """Progress components for displaying progress indicators."""
2
+
3
+ from typing import Any, Dict, Optional
4
+ from ....core.rich_component import RichComponent, ComponentType
5
+
6
+
7
+ class ProgressBarComponent(RichComponent):
8
+ """Progress bar with status and value."""
9
+
10
+ type: ComponentType = ComponentType.PROGRESS_BAR
11
+ value: float # 0.0 to 1.0
12
+ label: Optional[str] = None
13
+ show_percentage: bool = True
14
+ status: Optional[str] = None # "success", "warning", "error"
15
+ animated: bool = False
16
+
17
+
18
+ class ProgressDisplayComponent(RichComponent):
19
+ """Generic progress display for any long-running process."""
20
+
21
+ type: ComponentType = ComponentType.PROGRESS_DISPLAY
22
+ label: str
23
+ value: float = 0.0 # 0.0 to 1.0
24
+ description: Optional[str] = None
25
+ status: Optional[str] = None # "info", "success", "warning", "error"
26
+ show_percentage: bool = True
27
+ animated: bool = False
28
+ indeterminate: bool = False
29
+
30
+ def update_progress(
31
+ self, value: float, description: Optional[str] = None
32
+ ) -> "ProgressDisplayComponent":
33
+ """Update progress value and optionally description."""
34
+ updates: Dict[str, Any] = {"value": max(0.0, min(1.0, value))}
35
+ if description is not None:
36
+ updates["description"] = description
37
+ return self.update(**updates)
@@ -0,0 +1,28 @@
1
+ """Status card component for displaying process status."""
2
+
3
+ from typing import Any, Dict, List, Optional
4
+ from pydantic import Field
5
+ from ....core.rich_component import RichComponent, ComponentType
6
+
7
+
8
+ class StatusCardComponent(RichComponent):
9
+ """Generic status card that can display any process status."""
10
+
11
+ type: ComponentType = ComponentType.STATUS_CARD
12
+ title: str
13
+ status: str # "pending", "running", "completed", "failed", "success", "warning", "error"
14
+ description: Optional[str] = None
15
+ icon: Optional[str] = None
16
+ metadata: Dict[str, Any] = Field(default_factory=dict)
17
+ actions: List[Dict[str, Any]] = Field(default_factory=list)
18
+ collapsible: bool = False
19
+ collapsed: bool = False
20
+
21
+ def set_status(
22
+ self, status: str, description: Optional[str] = None
23
+ ) -> "StatusCardComponent":
24
+ """Update the status and optionally the description."""
25
+ updates = {"status": status}
26
+ if description is not None:
27
+ updates["description"] = description
28
+ return self.update(**updates)
@@ -0,0 +1,14 @@
1
+ """Status indicator component."""
2
+
3
+ from typing import Optional
4
+ from ....core.rich_component import RichComponent, ComponentType
5
+
6
+
7
+ class StatusIndicatorComponent(RichComponent):
8
+ """Status indicator with icon and message."""
9
+
10
+ type: ComponentType = ComponentType.STATUS_INDICATOR
11
+ status: str # "success", "warning", "error", "info", "loading"
12
+ message: str
13
+ icon: Optional[str] = None
14
+ pulse: bool = False
@@ -0,0 +1,21 @@
1
+ """Interactive components."""
2
+
3
+ from .task_list import TaskListComponent, Task
4
+ from .ui_state import (
5
+ StatusBarUpdateComponent,
6
+ TaskTrackerUpdateComponent,
7
+ ChatInputUpdateComponent,
8
+ TaskOperation,
9
+ )
10
+ from .button import ButtonComponent, ButtonGroupComponent
11
+
12
+ __all__ = [
13
+ "TaskListComponent",
14
+ "Task",
15
+ "StatusBarUpdateComponent",
16
+ "TaskTrackerUpdateComponent",
17
+ "ChatInputUpdateComponent",
18
+ "TaskOperation",
19
+ "ButtonComponent",
20
+ "ButtonGroupComponent",
21
+ ]
@@ -0,0 +1,95 @@
1
+ """Button component for interactive actions."""
2
+
3
+ from typing import Any, Dict, List, Literal, Optional
4
+ from ....core.rich_component import ComponentType, RichComponent
5
+
6
+
7
+ class ButtonComponent(RichComponent):
8
+ """Interactive button that sends a message when clicked.
9
+
10
+ The button renders in the UI and when clicked, sends its action
11
+ value as a message to the chat input.
12
+
13
+ Args:
14
+ label: Text displayed on the button
15
+ action: Message/command to send when clicked
16
+ variant: Visual style variant
17
+ size: Button size
18
+ icon: Optional emoji or icon
19
+ icon_position: Position of icon relative to label
20
+ disabled: Whether button is disabled
21
+
22
+ Example:
23
+ ButtonComponent(
24
+ label="Generate Report",
25
+ action="/report sales",
26
+ variant="primary",
27
+ icon="📊"
28
+ )
29
+ """
30
+
31
+ def __init__(
32
+ self,
33
+ label: str,
34
+ action: str,
35
+ variant: Literal[
36
+ "primary", "secondary", "success", "warning", "error", "ghost", "link"
37
+ ] = "primary",
38
+ size: Literal["small", "medium", "large"] = "medium",
39
+ icon: Optional[str] = None,
40
+ icon_position: Literal["left", "right"] = "left",
41
+ disabled: bool = False,
42
+ ):
43
+ super().__init__(
44
+ type=ComponentType.BUTTON,
45
+ data={
46
+ "label": label,
47
+ "action": action,
48
+ "variant": variant,
49
+ "size": size,
50
+ "icon": icon,
51
+ "icon_position": icon_position,
52
+ "disabled": disabled,
53
+ },
54
+ )
55
+
56
+
57
+ class ButtonGroupComponent(RichComponent):
58
+ """Group of buttons with consistent styling.
59
+
60
+ Args:
61
+ buttons: List of button data dictionaries
62
+ orientation: Layout direction
63
+ spacing: Gap between buttons
64
+ alignment: Button alignment within group
65
+ full_width: Whether buttons should stretch to fill width
66
+
67
+ Example:
68
+ ButtonGroupComponent(
69
+ buttons=[
70
+ {"label": "Yes", "action": "/confirm yes", "variant": "success"},
71
+ {"label": "No", "action": "/confirm no", "variant": "error"},
72
+ ],
73
+ orientation="horizontal",
74
+ spacing="medium"
75
+ )
76
+ """
77
+
78
+ def __init__(
79
+ self,
80
+ buttons: List[Dict[str, Any]],
81
+ orientation: Literal["horizontal", "vertical"] = "horizontal",
82
+ spacing: Literal["small", "medium", "large"] = "medium",
83
+ alignment: Literal["start", "center", "end", "stretch"] = "start",
84
+ full_width: bool = False,
85
+ ):
86
+ super().__init__(
87
+ type=ComponentType.BUTTON_GROUP,
88
+ data={
89
+ "buttons": buttons,
90
+ "orientation": orientation,
91
+ "spacing": spacing,
92
+ "alignment": alignment,
93
+ "full_width": full_width,
94
+ },
95
+ )
@@ -0,0 +1,58 @@
1
+ """Task list component for interactive task tracking."""
2
+
3
+ import uuid
4
+ from datetime import datetime
5
+ from typing import Any, Dict, List, Optional
6
+ from pydantic import BaseModel, Field
7
+ from ....core.rich_component import RichComponent, ComponentType
8
+
9
+
10
+ class Task(BaseModel):
11
+ """Individual task in a task list."""
12
+
13
+ id: str = Field(default_factory=lambda: str(uuid.uuid4()))
14
+ title: str
15
+ description: Optional[str] = None
16
+ status: str = "pending" # "pending", "in_progress", "completed", "error"
17
+ progress: Optional[float] = None # 0.0 to 1.0
18
+ created_at: str = Field(default_factory=lambda: datetime.utcnow().isoformat())
19
+ completed_at: Optional[str] = None
20
+ metadata: Dict[str, Any] = Field(default_factory=dict)
21
+
22
+
23
+ class TaskListComponent(RichComponent):
24
+ """Interactive task list with progress tracking."""
25
+
26
+ type: ComponentType = ComponentType.TASK_LIST
27
+ title: str = "Tasks"
28
+ tasks: List[Task] = Field(default_factory=list)
29
+ show_progress: bool = True
30
+ allow_reorder: bool = False
31
+ show_timestamps: bool = True
32
+ filter_status: Optional[str] = None # Filter by task status
33
+
34
+ def add_task(self, task: Task) -> "TaskListComponent":
35
+ """Add a task to the list."""
36
+ new_tasks = self.tasks + [task]
37
+ return self.update(tasks=new_tasks)
38
+
39
+ def update_task(self, task_id: str, **updates: Any) -> "TaskListComponent":
40
+ """Update a specific task."""
41
+ new_tasks = []
42
+ for task in self.tasks:
43
+ if task.id == task_id:
44
+ task_data = task.model_dump()
45
+ task_data.update(updates)
46
+ new_tasks.append(Task(**task_data))
47
+ else:
48
+ new_tasks.append(task)
49
+ return self.update(tasks=new_tasks)
50
+
51
+ def complete_task(self, task_id: str) -> "TaskListComponent":
52
+ """Mark a task as completed."""
53
+ return self.update_task(
54
+ task_id,
55
+ status="completed",
56
+ completed_at=datetime.utcnow().isoformat(),
57
+ progress=1.0,
58
+ )
@@ -0,0 +1,93 @@
1
+ """UI state update components for controlling interface elements."""
2
+
3
+ from enum import Enum
4
+ from typing import Any, Optional
5
+ from .task_list import Task
6
+ from ....core.rich_component import RichComponent, ComponentType
7
+
8
+
9
+ class StatusBarUpdateComponent(RichComponent):
10
+ """Component for updating the status bar above chat input."""
11
+
12
+ type: ComponentType = ComponentType.STATUS_BAR_UPDATE
13
+ status: str # "idle", "working", "success", "error"
14
+ message: str
15
+ detail: Optional[str] = None
16
+
17
+ def __init__(self, **kwargs: Any) -> None:
18
+ # Set a fixed ID for status bar updates
19
+ kwargs.setdefault("id", "vanna-status-bar")
20
+ super().__init__(**kwargs)
21
+
22
+
23
+ class TaskOperation(str, Enum):
24
+ """Operations for task tracker updates."""
25
+
26
+ ADD_TASK = "add_task"
27
+ UPDATE_TASK = "update_task"
28
+ REMOVE_TASK = "remove_task"
29
+ CLEAR_TASKS = "clear_tasks"
30
+
31
+
32
+ class TaskTrackerUpdateComponent(RichComponent):
33
+ """Component for updating the task tracker in the sidebar."""
34
+
35
+ type: ComponentType = ComponentType.TASK_TRACKER_UPDATE
36
+ operation: TaskOperation
37
+ task: Optional[Task] = None # Used for ADD_TASK
38
+ task_id: Optional[str] = None # Used for UPDATE_TASK and REMOVE_TASK
39
+ status: Optional[str] = None # Used for UPDATE_TASK
40
+ progress: Optional[float] = None # Used for UPDATE_TASK
41
+ detail: Optional[str] = None # Used for UPDATE_TASK
42
+
43
+ def __init__(self, **kwargs: Any) -> None:
44
+ # Set a fixed ID for task tracker updates
45
+ kwargs.setdefault("id", "vanna-task-tracker")
46
+ super().__init__(**kwargs)
47
+
48
+ @classmethod
49
+ def add_task(cls, task: Task) -> "TaskTrackerUpdateComponent":
50
+ """Create a component to add a new task."""
51
+ return cls(operation=TaskOperation.ADD_TASK, task=task)
52
+
53
+ @classmethod
54
+ def update_task(
55
+ cls,
56
+ task_id: str,
57
+ status: Optional[str] = None,
58
+ progress: Optional[float] = None,
59
+ detail: Optional[str] = None,
60
+ ) -> "TaskTrackerUpdateComponent":
61
+ """Create a component to update an existing task."""
62
+ return cls(
63
+ operation=TaskOperation.UPDATE_TASK,
64
+ task_id=task_id,
65
+ status=status,
66
+ progress=progress,
67
+ detail=detail,
68
+ )
69
+
70
+ @classmethod
71
+ def remove_task(cls, task_id: str) -> "TaskTrackerUpdateComponent":
72
+ """Create a component to remove a task."""
73
+ return cls(operation=TaskOperation.REMOVE_TASK, task_id=task_id)
74
+
75
+ @classmethod
76
+ def clear_tasks(cls) -> "TaskTrackerUpdateComponent":
77
+ """Create a component to clear all tasks."""
78
+ return cls(operation=TaskOperation.CLEAR_TASKS)
79
+
80
+
81
+ class ChatInputUpdateComponent(RichComponent):
82
+ """Component for updating chat input state and appearance."""
83
+
84
+ type: ComponentType = ComponentType.CHAT_INPUT_UPDATE
85
+ placeholder: Optional[str] = None
86
+ disabled: Optional[bool] = None
87
+ value: Optional[str] = None # Set input text value
88
+ focus: Optional[bool] = None # Focus/unfocus the input
89
+
90
+ def __init__(self, **kwargs: Any) -> None:
91
+ # Set a fixed ID for chat input updates
92
+ kwargs.setdefault("id", "vanna-chat-input")
93
+ super().__init__(**kwargs)
@@ -0,0 +1,7 @@
1
+ """Specialized components."""
2
+
3
+ from .artifact import ArtifactComponent
4
+
5
+ __all__ = [
6
+ "ArtifactComponent",
7
+ ]
@@ -0,0 +1,20 @@
1
+ """Artifact component for interactive content."""
2
+
3
+ import uuid
4
+ from typing import Optional
5
+ from pydantic import Field
6
+ from ....core.rich_component import RichComponent, ComponentType
7
+
8
+
9
+ class ArtifactComponent(RichComponent):
10
+ """Component for displaying interactive artifacts that can be rendered externally."""
11
+
12
+ type: ComponentType = ComponentType.ARTIFACT
13
+ artifact_id: str = Field(default_factory=lambda: f"artifact_{uuid.uuid4().hex[:8]}")
14
+ content: str # HTML/SVG/JS content
15
+ artifact_type: str # "html", "svg", "visualization", "interactive", "d3", "threejs"
16
+ title: Optional[str] = None
17
+ description: Optional[str] = None
18
+ editable: bool = True
19
+ fullscreen_capable: bool = True
20
+ external_renderable: bool = True
@@ -0,0 +1,16 @@
1
+ """Rich text component."""
2
+
3
+ from typing import Optional
4
+ from ...core.rich_component import RichComponent, ComponentType
5
+
6
+
7
+ class RichTextComponent(RichComponent):
8
+ """Rich text component with formatting options."""
9
+
10
+ type: ComponentType = ComponentType.TEXT
11
+ content: str
12
+ markdown: bool = False
13
+ code_language: Optional[str] = None # For syntax highlighting
14
+ font_size: Optional[str] = None
15
+ font_weight: Optional[str] = None
16
+ text_align: Optional[str] = None
@@ -0,0 +1,15 @@
1
+ """Simple UI components for basic rendering."""
2
+
3
+ # Import from core
4
+ from ...core.simple_component import SimpleComponent, SimpleComponentType
5
+ from .text import SimpleTextComponent
6
+ from .image import SimpleImageComponent
7
+ from .link import SimpleLinkComponent
8
+
9
+ __all__ = [
10
+ "SimpleComponent",
11
+ "SimpleComponentType",
12
+ "SimpleTextComponent",
13
+ "SimpleImageComponent",
14
+ "SimpleLinkComponent",
15
+ ]
@@ -0,0 +1,15 @@
1
+ """Simple image component."""
2
+
3
+ from typing import Optional
4
+ from pydantic import Field
5
+ from ...core.simple_component import SimpleComponent, SimpleComponentType
6
+
7
+
8
+ class SimpleImageComponent(SimpleComponent):
9
+ """A simple image component."""
10
+
11
+ type: SimpleComponentType = SimpleComponentType.IMAGE
12
+ url: str = Field(..., description="The URL of the image to display.")
13
+ alt_text: Optional[str] = Field(
14
+ default=None, description="Alternative text for the image."
15
+ )
@@ -0,0 +1,15 @@
1
+ """Simple link component."""
2
+
3
+ from typing import Optional
4
+ from pydantic import Field
5
+ from ...core.simple_component import SimpleComponent, SimpleComponentType
6
+
7
+
8
+ class SimpleLinkComponent(SimpleComponent):
9
+ """A simple link component."""
10
+
11
+ type: SimpleComponentType = SimpleComponentType.LINK
12
+ url: str = Field(..., description="The URL the link points to.")
13
+ text: Optional[str] = Field(
14
+ default=None, description="The display text for the link."
15
+ )
@@ -0,0 +1,11 @@
1
+ """Simple text component."""
2
+
3
+ from pydantic import Field
4
+ from ...core.simple_component import SimpleComponent, SimpleComponentType
5
+
6
+
7
+ class SimpleTextComponent(SimpleComponent):
8
+ """A simple text component."""
9
+
10
+ type: SimpleComponentType = SimpleComponentType.TEXT
11
+ text: str = Field(..., description="The text content to display.")