vanna 0.7.9__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +461 -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.0.dist-info/METADATA +485 -0
- vanna-2.0.0.dist-info/RECORD +289 -0
- vanna-2.0.0.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.0.dist-info}/WHEEL +0 -0
- {vanna-0.7.9.dist-info → vanna-2.0.0.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,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.")
|