vanna 0.7.9__py3-none-any.whl ā 2.0.0rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vanna/__init__.py +167 -395
- vanna/agents/__init__.py +7 -0
- vanna/capabilities/__init__.py +17 -0
- vanna/capabilities/agent_memory/__init__.py +21 -0
- vanna/capabilities/agent_memory/base.py +103 -0
- vanna/capabilities/agent_memory/models.py +53 -0
- vanna/capabilities/file_system/__init__.py +14 -0
- vanna/capabilities/file_system/base.py +71 -0
- vanna/capabilities/file_system/models.py +25 -0
- vanna/capabilities/sql_runner/__init__.py +13 -0
- vanna/capabilities/sql_runner/base.py +37 -0
- vanna/capabilities/sql_runner/models.py +13 -0
- vanna/components/__init__.py +92 -0
- vanna/components/base.py +11 -0
- vanna/components/rich/__init__.py +83 -0
- vanna/components/rich/containers/__init__.py +7 -0
- vanna/components/rich/containers/card.py +20 -0
- vanna/components/rich/data/__init__.py +9 -0
- vanna/components/rich/data/chart.py +17 -0
- vanna/components/rich/data/dataframe.py +93 -0
- vanna/components/rich/feedback/__init__.py +21 -0
- vanna/components/rich/feedback/badge.py +16 -0
- vanna/components/rich/feedback/icon_text.py +14 -0
- vanna/components/rich/feedback/log_viewer.py +41 -0
- vanna/components/rich/feedback/notification.py +19 -0
- vanna/components/rich/feedback/progress.py +37 -0
- vanna/components/rich/feedback/status_card.py +28 -0
- vanna/components/rich/feedback/status_indicator.py +14 -0
- vanna/components/rich/interactive/__init__.py +21 -0
- vanna/components/rich/interactive/button.py +95 -0
- vanna/components/rich/interactive/task_list.py +58 -0
- vanna/components/rich/interactive/ui_state.py +93 -0
- vanna/components/rich/specialized/__init__.py +7 -0
- vanna/components/rich/specialized/artifact.py +20 -0
- vanna/components/rich/text.py +16 -0
- vanna/components/simple/__init__.py +15 -0
- vanna/components/simple/image.py +15 -0
- vanna/components/simple/link.py +15 -0
- vanna/components/simple/text.py +11 -0
- vanna/core/__init__.py +193 -0
- vanna/core/_compat.py +19 -0
- vanna/core/agent/__init__.py +10 -0
- vanna/core/agent/agent.py +1407 -0
- vanna/core/agent/config.py +123 -0
- vanna/core/audit/__init__.py +28 -0
- vanna/core/audit/base.py +299 -0
- vanna/core/audit/models.py +131 -0
- vanna/core/component_manager.py +329 -0
- vanna/core/components.py +53 -0
- vanna/core/enhancer/__init__.py +11 -0
- vanna/core/enhancer/base.py +94 -0
- vanna/core/enhancer/default.py +118 -0
- vanna/core/enricher/__init__.py +10 -0
- vanna/core/enricher/base.py +59 -0
- vanna/core/errors.py +47 -0
- vanna/core/evaluation/__init__.py +81 -0
- vanna/core/evaluation/base.py +186 -0
- vanna/core/evaluation/dataset.py +254 -0
- vanna/core/evaluation/evaluators.py +376 -0
- vanna/core/evaluation/report.py +289 -0
- vanna/core/evaluation/runner.py +313 -0
- vanna/core/filter/__init__.py +10 -0
- vanna/core/filter/base.py +67 -0
- vanna/core/lifecycle/__init__.py +10 -0
- vanna/core/lifecycle/base.py +83 -0
- vanna/core/llm/__init__.py +16 -0
- vanna/core/llm/base.py +40 -0
- vanna/core/llm/models.py +61 -0
- vanna/core/middleware/__init__.py +10 -0
- vanna/core/middleware/base.py +69 -0
- vanna/core/observability/__init__.py +11 -0
- vanna/core/observability/base.py +88 -0
- vanna/core/observability/models.py +47 -0
- vanna/core/recovery/__init__.py +11 -0
- vanna/core/recovery/base.py +84 -0
- vanna/core/recovery/models.py +32 -0
- vanna/core/registry.py +278 -0
- vanna/core/rich_component.py +156 -0
- vanna/core/simple_component.py +27 -0
- vanna/core/storage/__init__.py +14 -0
- vanna/core/storage/base.py +46 -0
- vanna/core/storage/models.py +46 -0
- vanna/core/system_prompt/__init__.py +13 -0
- vanna/core/system_prompt/base.py +36 -0
- vanna/core/system_prompt/default.py +157 -0
- vanna/core/tool/__init__.py +18 -0
- vanna/core/tool/base.py +70 -0
- vanna/core/tool/models.py +84 -0
- vanna/core/user/__init__.py +17 -0
- vanna/core/user/base.py +29 -0
- vanna/core/user/models.py +25 -0
- vanna/core/user/request_context.py +70 -0
- vanna/core/user/resolver.py +42 -0
- vanna/core/validation.py +164 -0
- vanna/core/workflow/__init__.py +12 -0
- vanna/core/workflow/base.py +254 -0
- vanna/core/workflow/default.py +789 -0
- vanna/examples/__init__.py +1 -0
- vanna/examples/__main__.py +44 -0
- vanna/examples/anthropic_quickstart.py +80 -0
- vanna/examples/artifact_example.py +293 -0
- vanna/examples/claude_sqlite_example.py +236 -0
- vanna/examples/coding_agent_example.py +300 -0
- vanna/examples/custom_system_prompt_example.py +174 -0
- vanna/examples/default_workflow_handler_example.py +208 -0
- vanna/examples/email_auth_example.py +340 -0
- vanna/examples/evaluation_example.py +269 -0
- vanna/examples/extensibility_example.py +262 -0
- vanna/examples/minimal_example.py +67 -0
- vanna/examples/mock_auth_example.py +227 -0
- vanna/examples/mock_custom_tool.py +311 -0
- vanna/examples/mock_quickstart.py +79 -0
- vanna/examples/mock_quota_example.py +145 -0
- vanna/examples/mock_rich_components_demo.py +396 -0
- vanna/examples/mock_sqlite_example.py +223 -0
- vanna/examples/openai_quickstart.py +83 -0
- vanna/examples/primitive_components_demo.py +305 -0
- vanna/examples/quota_lifecycle_example.py +139 -0
- vanna/examples/visualization_example.py +251 -0
- vanna/integrations/__init__.py +17 -0
- vanna/integrations/anthropic/__init__.py +9 -0
- vanna/integrations/anthropic/llm.py +270 -0
- vanna/integrations/azureopenai/__init__.py +9 -0
- vanna/integrations/azureopenai/llm.py +329 -0
- vanna/integrations/azuresearch/__init__.py +7 -0
- vanna/integrations/azuresearch/agent_memory.py +413 -0
- vanna/integrations/bigquery/__init__.py +5 -0
- vanna/integrations/bigquery/sql_runner.py +81 -0
- vanna/integrations/chromadb/__init__.py +104 -0
- vanna/integrations/chromadb/agent_memory.py +416 -0
- vanna/integrations/clickhouse/__init__.py +5 -0
- vanna/integrations/clickhouse/sql_runner.py +82 -0
- vanna/integrations/duckdb/__init__.py +5 -0
- vanna/integrations/duckdb/sql_runner.py +65 -0
- vanna/integrations/faiss/__init__.py +7 -0
- vanna/integrations/faiss/agent_memory.py +431 -0
- vanna/integrations/google/__init__.py +9 -0
- vanna/integrations/google/gemini.py +370 -0
- vanna/integrations/hive/__init__.py +5 -0
- vanna/integrations/hive/sql_runner.py +87 -0
- vanna/integrations/local/__init__.py +17 -0
- vanna/integrations/local/agent_memory/__init__.py +7 -0
- vanna/integrations/local/agent_memory/in_memory.py +285 -0
- vanna/integrations/local/audit.py +59 -0
- vanna/integrations/local/file_system.py +242 -0
- vanna/integrations/local/file_system_conversation_store.py +255 -0
- vanna/integrations/local/storage.py +62 -0
- vanna/integrations/marqo/__init__.py +7 -0
- vanna/integrations/marqo/agent_memory.py +354 -0
- vanna/integrations/milvus/__init__.py +7 -0
- vanna/integrations/milvus/agent_memory.py +458 -0
- vanna/integrations/mock/__init__.py +9 -0
- vanna/integrations/mock/llm.py +65 -0
- vanna/integrations/mssql/__init__.py +5 -0
- vanna/integrations/mssql/sql_runner.py +66 -0
- vanna/integrations/mysql/__init__.py +5 -0
- vanna/integrations/mysql/sql_runner.py +92 -0
- vanna/integrations/ollama/__init__.py +7 -0
- vanna/integrations/ollama/llm.py +252 -0
- vanna/integrations/openai/__init__.py +10 -0
- vanna/integrations/openai/llm.py +267 -0
- vanna/integrations/openai/responses.py +163 -0
- vanna/integrations/opensearch/__init__.py +7 -0
- vanna/integrations/opensearch/agent_memory.py +411 -0
- vanna/integrations/oracle/__init__.py +5 -0
- vanna/integrations/oracle/sql_runner.py +75 -0
- vanna/integrations/pinecone/__init__.py +7 -0
- vanna/integrations/pinecone/agent_memory.py +329 -0
- vanna/integrations/plotly/__init__.py +5 -0
- vanna/integrations/plotly/chart_generator.py +313 -0
- vanna/integrations/postgres/__init__.py +9 -0
- vanna/integrations/postgres/sql_runner.py +112 -0
- vanna/integrations/premium/agent_memory/__init__.py +7 -0
- vanna/integrations/premium/agent_memory/premium.py +186 -0
- vanna/integrations/presto/__init__.py +5 -0
- vanna/integrations/presto/sql_runner.py +107 -0
- vanna/integrations/qdrant/__init__.py +7 -0
- vanna/integrations/qdrant/agent_memory.py +439 -0
- vanna/integrations/snowflake/__init__.py +5 -0
- vanna/integrations/snowflake/sql_runner.py +147 -0
- vanna/integrations/sqlite/__init__.py +9 -0
- vanna/integrations/sqlite/sql_runner.py +65 -0
- vanna/integrations/weaviate/__init__.py +7 -0
- vanna/integrations/weaviate/agent_memory.py +428 -0
- vanna/{ZhipuAI ā legacy/ZhipuAI}/ZhipuAI_embeddings.py +11 -11
- vanna/legacy/__init__.py +403 -0
- vanna/legacy/adapter.py +463 -0
- vanna/{advanced ā legacy/advanced}/__init__.py +3 -1
- vanna/{anthropic ā legacy/anthropic}/anthropic_chat.py +9 -7
- vanna/{azuresearch ā legacy/azuresearch}/azuresearch_vector.py +79 -41
- vanna/{base ā legacy/base}/base.py +224 -217
- vanna/legacy/bedrock/__init__.py +1 -0
- vanna/{bedrock ā legacy/bedrock}/bedrock_converse.py +13 -12
- vanna/{chromadb ā legacy/chromadb}/chromadb_vector.py +3 -1
- vanna/legacy/cohere/__init__.py +2 -0
- vanna/{cohere ā legacy/cohere}/cohere_chat.py +19 -14
- vanna/{cohere ā legacy/cohere}/cohere_embeddings.py +25 -19
- vanna/{deepseek ā legacy/deepseek}/deepseek_chat.py +5 -6
- vanna/legacy/faiss/__init__.py +1 -0
- vanna/{faiss ā legacy/faiss}/faiss.py +113 -59
- vanna/{flask ā legacy/flask}/__init__.py +84 -43
- vanna/{flask ā legacy/flask}/assets.py +5 -5
- vanna/{flask ā legacy/flask}/auth.py +5 -4
- vanna/{google ā legacy/google}/bigquery_vector.py +75 -42
- vanna/{google ā legacy/google}/gemini_chat.py +7 -3
- vanna/{hf ā legacy/hf}/hf.py +0 -1
- vanna/{milvus ā legacy/milvus}/milvus_vector.py +58 -35
- vanna/{mock ā legacy/mock}/llm.py +0 -1
- vanna/legacy/mock/vectordb.py +67 -0
- vanna/legacy/ollama/ollama.py +110 -0
- vanna/{openai ā legacy/openai}/openai_chat.py +2 -6
- vanna/legacy/opensearch/opensearch_vector.py +369 -0
- vanna/legacy/opensearch/opensearch_vector_semantic.py +200 -0
- vanna/legacy/oracle/oracle_vector.py +584 -0
- vanna/{pgvector ā legacy/pgvector}/pgvector.py +42 -13
- vanna/{qdrant ā legacy/qdrant}/qdrant.py +2 -6
- vanna/legacy/qianfan/Qianfan_Chat.py +170 -0
- vanna/legacy/qianfan/Qianfan_embeddings.py +36 -0
- vanna/legacy/qianwen/QianwenAI_chat.py +132 -0
- vanna/{remote.py ā legacy/remote.py} +28 -26
- vanna/{utils.py ā legacy/utils.py} +6 -11
- vanna/{vannadb ā legacy/vannadb}/vannadb_vector.py +115 -46
- vanna/{vllm ā legacy/vllm}/vllm.py +5 -6
- vanna/{weaviate ā legacy/weaviate}/weaviate_vector.py +59 -40
- vanna/{xinference ā legacy/xinference}/xinference.py +6 -6
- vanna/py.typed +0 -0
- vanna/servers/__init__.py +16 -0
- vanna/servers/__main__.py +8 -0
- vanna/servers/base/__init__.py +18 -0
- vanna/servers/base/chat_handler.py +65 -0
- vanna/servers/base/models.py +111 -0
- vanna/servers/base/rich_chat_handler.py +141 -0
- vanna/servers/base/templates.py +331 -0
- vanna/servers/cli/__init__.py +7 -0
- vanna/servers/cli/server_runner.py +204 -0
- vanna/servers/fastapi/__init__.py +7 -0
- vanna/servers/fastapi/app.py +163 -0
- vanna/servers/fastapi/routes.py +183 -0
- vanna/servers/flask/__init__.py +7 -0
- vanna/servers/flask/app.py +132 -0
- vanna/servers/flask/routes.py +137 -0
- vanna/tools/__init__.py +41 -0
- vanna/tools/agent_memory.py +322 -0
- vanna/tools/file_system.py +879 -0
- vanna/tools/python.py +222 -0
- vanna/tools/run_sql.py +165 -0
- vanna/tools/visualize_data.py +195 -0
- vanna/utils/__init__.py +0 -0
- vanna/web_components/__init__.py +44 -0
- vanna-2.0.0rc1.dist-info/METADATA +868 -0
- vanna-2.0.0rc1.dist-info/RECORD +289 -0
- vanna-2.0.0rc1.dist-info/entry_points.txt +3 -0
- vanna/bedrock/__init__.py +0 -1
- vanna/cohere/__init__.py +0 -2
- vanna/faiss/__init__.py +0 -1
- vanna/mock/vectordb.py +0 -55
- vanna/ollama/ollama.py +0 -103
- vanna/opensearch/opensearch_vector.py +0 -392
- vanna/opensearch/opensearch_vector_semantic.py +0 -175
- vanna/oracle/oracle_vector.py +0 -585
- vanna/qianfan/Qianfan_Chat.py +0 -165
- vanna/qianfan/Qianfan_embeddings.py +0 -36
- vanna/qianwen/QianwenAI_chat.py +0 -133
- vanna-0.7.9.dist-info/METADATA +0 -408
- vanna-0.7.9.dist-info/RECORD +0 -79
- /vanna/{ZhipuAI ā legacy/ZhipuAI}/ZhipuAI_Chat.py +0 -0
- /vanna/{ZhipuAI ā legacy/ZhipuAI}/__init__.py +0 -0
- /vanna/{anthropic ā legacy/anthropic}/__init__.py +0 -0
- /vanna/{azuresearch ā legacy/azuresearch}/__init__.py +0 -0
- /vanna/{base ā legacy/base}/__init__.py +0 -0
- /vanna/{chromadb ā legacy/chromadb}/__init__.py +0 -0
- /vanna/{deepseek ā legacy/deepseek}/__init__.py +0 -0
- /vanna/{exceptions ā legacy/exceptions}/__init__.py +0 -0
- /vanna/{google ā legacy/google}/__init__.py +0 -0
- /vanna/{hf ā legacy/hf}/__init__.py +0 -0
- /vanna/{local.py ā legacy/local.py} +0 -0
- /vanna/{marqo ā legacy/marqo}/__init__.py +0 -0
- /vanna/{marqo ā legacy/marqo}/marqo.py +0 -0
- /vanna/{milvus ā legacy/milvus}/__init__.py +0 -0
- /vanna/{mistral ā legacy/mistral}/__init__.py +0 -0
- /vanna/{mistral ā legacy/mistral}/mistral.py +0 -0
- /vanna/{mock ā legacy/mock}/__init__.py +0 -0
- /vanna/{mock ā legacy/mock}/embedding.py +0 -0
- /vanna/{ollama ā legacy/ollama}/__init__.py +0 -0
- /vanna/{openai ā legacy/openai}/__init__.py +0 -0
- /vanna/{openai ā legacy/openai}/openai_embeddings.py +0 -0
- /vanna/{opensearch ā legacy/opensearch}/__init__.py +0 -0
- /vanna/{oracle ā legacy/oracle}/__init__.py +0 -0
- /vanna/{pgvector ā legacy/pgvector}/__init__.py +0 -0
- /vanna/{pinecone ā legacy/pinecone}/__init__.py +0 -0
- /vanna/{pinecone ā legacy/pinecone}/pinecone_vector.py +0 -0
- /vanna/{qdrant ā legacy/qdrant}/__init__.py +0 -0
- /vanna/{qianfan ā legacy/qianfan}/__init__.py +0 -0
- /vanna/{qianwen ā legacy/qianwen}/QianwenAI_embeddings.py +0 -0
- /vanna/{qianwen ā legacy/qianwen}/__init__.py +0 -0
- /vanna/{types ā legacy/types}/__init__.py +0 -0
- /vanna/{vannadb ā legacy/vannadb}/__init__.py +0 -0
- /vanna/{vllm ā legacy/vllm}/__init__.py +0 -0
- /vanna/{weaviate ā legacy/weaviate}/__init__.py +0 -0
- /vanna/{xinference ā legacy/xinference}/__init__.py +0 -0
- {vanna-0.7.9.dist-info ā vanna-2.0.0rc1.dist-info}/WHEEL +0 -0
- {vanna-0.7.9.dist-info ā vanna-2.0.0rc1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Example coding agent using the vanna-agents framework.
|
|
3
|
+
|
|
4
|
+
This example demonstrates building an agent that can edit code files,
|
|
5
|
+
following the concepts from the "How to Build an Agent" article.
|
|
6
|
+
The agent includes tools for file operations and uses an LLM service
|
|
7
|
+
that can understand and modify code.
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
PYTHONPATH=. python vanna/examples/coding_agent_example.py
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import asyncio
|
|
14
|
+
import uuid
|
|
15
|
+
from typing import AsyncGenerator, List, Optional
|
|
16
|
+
|
|
17
|
+
from vanna import (
|
|
18
|
+
AgentConfig,
|
|
19
|
+
Agent,
|
|
20
|
+
ToolRegistry,
|
|
21
|
+
User,
|
|
22
|
+
)
|
|
23
|
+
from vanna.core.interfaces import LlmService
|
|
24
|
+
from vanna.core.models import (
|
|
25
|
+
LlmRequest,
|
|
26
|
+
LlmResponse,
|
|
27
|
+
LlmStreamChunk,
|
|
28
|
+
ToolCall,
|
|
29
|
+
ToolSchema,
|
|
30
|
+
)
|
|
31
|
+
from vanna.tools.file_system import create_file_system_tools
|
|
32
|
+
from vanna.tools.python import create_python_tools
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class CodingLlmService(LlmService):
|
|
36
|
+
"""
|
|
37
|
+
LLM service that simulates a coding assistant.
|
|
38
|
+
|
|
39
|
+
This demonstrates the minimal implementation needed for an agent
|
|
40
|
+
as described in the article - just needs to understand tool calls
|
|
41
|
+
and respond appropriately.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
async def send_request(self, request: LlmRequest) -> LlmResponse:
|
|
45
|
+
"""Handle non-streaming requests."""
|
|
46
|
+
await asyncio.sleep(0.1) # Simulate thinking time
|
|
47
|
+
return self._build_response(request)
|
|
48
|
+
|
|
49
|
+
async def stream_request(
|
|
50
|
+
self, request: LlmRequest
|
|
51
|
+
) -> AsyncGenerator[LlmStreamChunk, None]:
|
|
52
|
+
"""Handle streaming requests."""
|
|
53
|
+
await asyncio.sleep(0.1)
|
|
54
|
+
response = self._build_response(request)
|
|
55
|
+
|
|
56
|
+
if response.tool_calls:
|
|
57
|
+
yield LlmStreamChunk(tool_calls=response.tool_calls)
|
|
58
|
+
if response.content:
|
|
59
|
+
# Simulate streaming by chunking the response
|
|
60
|
+
words = response.content.split()
|
|
61
|
+
for i, word in enumerate(words):
|
|
62
|
+
chunk = word if i == 0 else f" {word}"
|
|
63
|
+
await asyncio.sleep(0.05) # Simulate streaming delay
|
|
64
|
+
yield LlmStreamChunk(content=chunk)
|
|
65
|
+
|
|
66
|
+
yield LlmStreamChunk(finish_reason=response.finish_reason)
|
|
67
|
+
|
|
68
|
+
async def validate_tools(self, tools: List[ToolSchema]) -> List[str]:
|
|
69
|
+
"""Validate tools - no errors for this simple implementation."""
|
|
70
|
+
return []
|
|
71
|
+
|
|
72
|
+
def _build_response(self, request: LlmRequest) -> LlmResponse:
|
|
73
|
+
"""Build a response based on the conversation context."""
|
|
74
|
+
last_message = request.messages[-1] if request.messages else None
|
|
75
|
+
|
|
76
|
+
# If we just got a tool result, respond to it
|
|
77
|
+
if last_message and last_message.role == "tool":
|
|
78
|
+
tool_result = last_message.content or "Tool executed"
|
|
79
|
+
return LlmResponse(
|
|
80
|
+
content=f"I've completed the operation. {tool_result}",
|
|
81
|
+
finish_reason="stop",
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# If user is asking for file operations, use tools
|
|
85
|
+
if last_message and last_message.role == "user":
|
|
86
|
+
user_message = last_message.content.lower()
|
|
87
|
+
|
|
88
|
+
if "list files" in user_message or "show files" in user_message:
|
|
89
|
+
return LlmResponse(
|
|
90
|
+
content="I'll list the files for you.",
|
|
91
|
+
tool_calls=[
|
|
92
|
+
ToolCall(
|
|
93
|
+
id=f"call_{uuid.uuid4().hex[:8]}",
|
|
94
|
+
name="list_files",
|
|
95
|
+
arguments={},
|
|
96
|
+
)
|
|
97
|
+
],
|
|
98
|
+
finish_reason="tool_calls",
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
elif "read" in user_message and (
|
|
102
|
+
"file" in user_message
|
|
103
|
+
or ".py" in user_message
|
|
104
|
+
or ".txt" in user_message
|
|
105
|
+
):
|
|
106
|
+
filename = _extract_filename(user_message)
|
|
107
|
+
|
|
108
|
+
if filename:
|
|
109
|
+
return LlmResponse(
|
|
110
|
+
content=f"I'll read the file '{filename}' for you.",
|
|
111
|
+
tool_calls=[
|
|
112
|
+
ToolCall(
|
|
113
|
+
id=f"call_{uuid.uuid4().hex[:8]}",
|
|
114
|
+
name="read_file",
|
|
115
|
+
arguments={"filename": filename},
|
|
116
|
+
)
|
|
117
|
+
],
|
|
118
|
+
finish_reason="tool_calls",
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
elif "create" in user_message or "write" in user_message:
|
|
122
|
+
# Suggest creating a simple example file
|
|
123
|
+
return LlmResponse(
|
|
124
|
+
content="I'll create an example Python file for you.",
|
|
125
|
+
tool_calls=[
|
|
126
|
+
ToolCall(
|
|
127
|
+
id=f"call_{uuid.uuid4().hex[:8]}",
|
|
128
|
+
name="write_file",
|
|
129
|
+
arguments={
|
|
130
|
+
"filename": "example.py",
|
|
131
|
+
"content": "# Example Python file\nprint('Hello from the coding agent!')\n\ndef greet(name):\n return f'Hello, {name}!'\n\nif __name__ == '__main__':\n print(greet('World'))\n",
|
|
132
|
+
"overwrite": True,
|
|
133
|
+
},
|
|
134
|
+
)
|
|
135
|
+
],
|
|
136
|
+
finish_reason="tool_calls",
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
elif (
|
|
140
|
+
"run" in user_message or "execute" in user_message
|
|
141
|
+
) and ".py" in user_message:
|
|
142
|
+
filename = _extract_filename(user_message)
|
|
143
|
+
if filename:
|
|
144
|
+
return LlmResponse(
|
|
145
|
+
content=f"I'll run the Python file '{filename}'.",
|
|
146
|
+
tool_calls=[
|
|
147
|
+
ToolCall(
|
|
148
|
+
id=f"call_{uuid.uuid4().hex[:8]}",
|
|
149
|
+
name="run_python_file",
|
|
150
|
+
arguments={
|
|
151
|
+
"filename": filename,
|
|
152
|
+
"arguments": [],
|
|
153
|
+
},
|
|
154
|
+
)
|
|
155
|
+
],
|
|
156
|
+
finish_reason="tool_calls",
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
elif (
|
|
160
|
+
"edit" in user_message
|
|
161
|
+
or "update" in user_message
|
|
162
|
+
or "modify" in user_message
|
|
163
|
+
):
|
|
164
|
+
return LlmResponse(
|
|
165
|
+
content="I'll update the greet function to make it more descriptive.",
|
|
166
|
+
tool_calls=[
|
|
167
|
+
ToolCall(
|
|
168
|
+
id=f"call_{uuid.uuid4().hex[:8]}",
|
|
169
|
+
name="edit_file",
|
|
170
|
+
arguments={
|
|
171
|
+
"filename": "example.py",
|
|
172
|
+
"edits": [
|
|
173
|
+
{
|
|
174
|
+
"start_line": 4,
|
|
175
|
+
"end_line": 5,
|
|
176
|
+
"new_content": (
|
|
177
|
+
"def greet(name):\n"
|
|
178
|
+
' """Return a friendly greeting."""\n'
|
|
179
|
+
' return f"Hello, {name}! Welcome to the coding agent."\n'
|
|
180
|
+
),
|
|
181
|
+
}
|
|
182
|
+
],
|
|
183
|
+
},
|
|
184
|
+
)
|
|
185
|
+
],
|
|
186
|
+
finish_reason="tool_calls",
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
# Default response
|
|
190
|
+
return LlmResponse(
|
|
191
|
+
content=(
|
|
192
|
+
"I'm a coding assistant. I can help you list, read, write, edit, and run Python files. "
|
|
193
|
+
"Try asking me to 'list files', 'read example.py', 'create a Python file', 'run example.py', or 'update example.py'."
|
|
194
|
+
),
|
|
195
|
+
finish_reason="stop",
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def create_demo_agent() -> Agent:
|
|
200
|
+
"""
|
|
201
|
+
Create a coding agent with file operation tools.
|
|
202
|
+
|
|
203
|
+
This follows the pattern from the article - minimal code
|
|
204
|
+
to create a powerful code-editing agent. Uses dependency injection
|
|
205
|
+
for file system operations with LocalFileSystem as default.
|
|
206
|
+
"""
|
|
207
|
+
# Create tool registry and register file system tools
|
|
208
|
+
tool_registry = ToolRegistry()
|
|
209
|
+
|
|
210
|
+
# Use the convenience function to create tools with default LocalFileSystem
|
|
211
|
+
for tool in create_file_system_tools():
|
|
212
|
+
tool_registry.register(tool)
|
|
213
|
+
|
|
214
|
+
for tool in create_python_tools():
|
|
215
|
+
tool_registry.register(tool)
|
|
216
|
+
|
|
217
|
+
# Create LLM service
|
|
218
|
+
llm_service = CodingLlmService()
|
|
219
|
+
|
|
220
|
+
# Create agent with configuration
|
|
221
|
+
return Agent(
|
|
222
|
+
llm_service=llm_service,
|
|
223
|
+
tool_registry=tool_registry,
|
|
224
|
+
config=AgentConfig(
|
|
225
|
+
stream_responses=True,
|
|
226
|
+
include_thinking_indicators=True,
|
|
227
|
+
max_tool_iterations=3,
|
|
228
|
+
),
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
async def main() -> None:
|
|
233
|
+
"""
|
|
234
|
+
Demonstrate the coding agent in action.
|
|
235
|
+
|
|
236
|
+
As the article mentions: "300 lines of code and three tools and now
|
|
237
|
+
you're able to talk to an alien intelligence that edits your code."
|
|
238
|
+
"""
|
|
239
|
+
print("š¤ Starting Coding Agent Demo")
|
|
240
|
+
print("This demonstrates the concepts from 'How to Build an Agent'")
|
|
241
|
+
print("-" * 50)
|
|
242
|
+
|
|
243
|
+
# Create the agent
|
|
244
|
+
agent = create_demo_agent()
|
|
245
|
+
|
|
246
|
+
# Create a test user
|
|
247
|
+
user = User(id="coder123", username="developer", permissions=[])
|
|
248
|
+
|
|
249
|
+
# Show available tools
|
|
250
|
+
tools = await agent.get_available_tools(user)
|
|
251
|
+
print(f"Available tools: {[tool.name for tool in tools]}")
|
|
252
|
+
print()
|
|
253
|
+
|
|
254
|
+
# Demo conversation
|
|
255
|
+
conversation_id = "coding-session"
|
|
256
|
+
|
|
257
|
+
demos = [
|
|
258
|
+
"Hello! Can you list the files in this directory?",
|
|
259
|
+
"Can you create a simple Python file for me?",
|
|
260
|
+
"Now read the example.py file you just created",
|
|
261
|
+
"Please update the greet function to include a docstring and a friendlier message.",
|
|
262
|
+
"Run example.py so I can see its output.",
|
|
263
|
+
"Great, read example.py again to confirm the changes.",
|
|
264
|
+
]
|
|
265
|
+
|
|
266
|
+
for i, message in enumerate(demos, 1):
|
|
267
|
+
print(f"Demo {i}: {message}")
|
|
268
|
+
print("Agent response:")
|
|
269
|
+
|
|
270
|
+
async for component in agent.send_message(
|
|
271
|
+
user=user, message=message, conversation_id=conversation_id
|
|
272
|
+
):
|
|
273
|
+
if (
|
|
274
|
+
hasattr(component.rich_component, "content")
|
|
275
|
+
and component.rich_component.content
|
|
276
|
+
):
|
|
277
|
+
print(f" š {component.rich_component.content}")
|
|
278
|
+
elif hasattr(component.rich_component, "message"):
|
|
279
|
+
print(f" š¬ {component.rich_component.message}")
|
|
280
|
+
elif component.simple_component and hasattr(
|
|
281
|
+
component.simple_component, "text"
|
|
282
|
+
):
|
|
283
|
+
print(f" š {component.simple_component.text}")
|
|
284
|
+
|
|
285
|
+
print("-" * 30)
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def _extract_filename(message: str) -> Optional[str]:
|
|
289
|
+
"""Extract a likely filename token from a user message."""
|
|
290
|
+
|
|
291
|
+
for token in message.replace("\n", " ").split():
|
|
292
|
+
cleaned = token.strip("'\".,;!?")
|
|
293
|
+
if "." in cleaned and not cleaned.startswith("."):
|
|
294
|
+
return cleaned
|
|
295
|
+
|
|
296
|
+
return None
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
if __name__ == "__main__":
|
|
300
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Example demonstrating custom system prompt builder with dependency injection.
|
|
3
|
+
|
|
4
|
+
This example shows how to create a custom SystemPromptBuilder that dynamically
|
|
5
|
+
generates system prompts based on user context and available tools.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
python -m vanna.examples.custom_system_prompt_example
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from typing import List, Optional
|
|
12
|
+
|
|
13
|
+
from vanna.core.interfaces import SystemPromptBuilder
|
|
14
|
+
from vanna.core.models import ToolSchema, User
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class CustomSystemPromptBuilder(SystemPromptBuilder):
|
|
18
|
+
"""Custom system prompt builder that personalizes prompts based on user."""
|
|
19
|
+
|
|
20
|
+
async def build_system_prompt(
|
|
21
|
+
self, user: User, tools: List[ToolSchema]
|
|
22
|
+
) -> Optional[str]:
|
|
23
|
+
"""Build a personalized system prompt.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
user: The user making the request
|
|
27
|
+
tools: List of tools available to the user
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
Personalized system prompt
|
|
31
|
+
"""
|
|
32
|
+
# Build personalized greeting
|
|
33
|
+
username = user.username or user.id
|
|
34
|
+
greeting = f"Hello {username}! I'm your AI assistant."
|
|
35
|
+
|
|
36
|
+
# Add role-specific instructions based on user permissions
|
|
37
|
+
role_instructions = []
|
|
38
|
+
if "admin" in user.permissions:
|
|
39
|
+
role_instructions.append(
|
|
40
|
+
"As an admin user, you have access to all tools and capabilities."
|
|
41
|
+
)
|
|
42
|
+
elif "analyst" in user.permissions:
|
|
43
|
+
role_instructions.append(
|
|
44
|
+
"You're working as an analyst. I'll help you query and visualize data."
|
|
45
|
+
)
|
|
46
|
+
else:
|
|
47
|
+
role_instructions.append("I'm here to help you with your tasks.")
|
|
48
|
+
|
|
49
|
+
# List available tools
|
|
50
|
+
tool_info = []
|
|
51
|
+
if tools:
|
|
52
|
+
tool_info.append("\nAvailable tools:")
|
|
53
|
+
for tool in tools:
|
|
54
|
+
tool_info.append(f"- {tool.name}: {tool.description}")
|
|
55
|
+
|
|
56
|
+
# Combine all parts
|
|
57
|
+
parts = [greeting] + role_instructions + tool_info
|
|
58
|
+
return "\n".join(parts)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class SQLAssistantSystemPromptBuilder(SystemPromptBuilder):
|
|
62
|
+
"""System prompt builder specifically for SQL database assistants."""
|
|
63
|
+
|
|
64
|
+
def __init__(self, database_name: str = "database"):
|
|
65
|
+
"""Initialize with database context.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
database_name: Name of the database being queried
|
|
69
|
+
"""
|
|
70
|
+
self.database_name = database_name
|
|
71
|
+
|
|
72
|
+
async def build_system_prompt(
|
|
73
|
+
self, user: User, tools: List[ToolSchema]
|
|
74
|
+
) -> Optional[str]:
|
|
75
|
+
"""Build a SQL-focused system prompt.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
user: The user making the request
|
|
79
|
+
tools: List of tools available to the user
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
SQL-focused system prompt
|
|
83
|
+
"""
|
|
84
|
+
prompt = f"""You are an expert SQL database assistant for the {self.database_name} database.
|
|
85
|
+
|
|
86
|
+
Your primary responsibilities:
|
|
87
|
+
1. Write efficient, correct SQL queries
|
|
88
|
+
2. Explain query results clearly
|
|
89
|
+
3. Suggest optimizations when relevant
|
|
90
|
+
4. Visualize data when appropriate
|
|
91
|
+
|
|
92
|
+
Guidelines:
|
|
93
|
+
- Always validate SQL syntax before execution
|
|
94
|
+
- Use appropriate JOINs and avoid Cartesian products
|
|
95
|
+
- Limit result sets to reasonable sizes by default
|
|
96
|
+
- Format numbers and dates for readability
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
# Add tool-specific instructions
|
|
100
|
+
has_viz_tool = any(tool.name == "visualize_data" for tool in tools)
|
|
101
|
+
if has_viz_tool:
|
|
102
|
+
prompt += "\n- Create visualizations for numerical data when it helps understanding"
|
|
103
|
+
|
|
104
|
+
return prompt
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
async def demo() -> None:
|
|
108
|
+
"""Demonstrate custom system prompt builders."""
|
|
109
|
+
from vanna import Agent, User
|
|
110
|
+
from vanna.core.registry import ToolRegistry
|
|
111
|
+
from vanna.integrations.anthropic.mock import MockLlmService
|
|
112
|
+
|
|
113
|
+
# Example 1: Custom personalized system prompt
|
|
114
|
+
print("=" * 60)
|
|
115
|
+
print("Example 1: Custom Personalized System Prompt")
|
|
116
|
+
print("=" * 60)
|
|
117
|
+
|
|
118
|
+
custom_builder = CustomSystemPromptBuilder()
|
|
119
|
+
admin_user = User(id="user-1", username="Alice", permissions=["admin"])
|
|
120
|
+
|
|
121
|
+
# Simulate some tools
|
|
122
|
+
mock_tools = [
|
|
123
|
+
ToolSchema(
|
|
124
|
+
name="query_database", description="Query the SQL database", parameters={}
|
|
125
|
+
),
|
|
126
|
+
ToolSchema(
|
|
127
|
+
name="visualize_data",
|
|
128
|
+
description="Create data visualizations",
|
|
129
|
+
parameters={},
|
|
130
|
+
),
|
|
131
|
+
]
|
|
132
|
+
|
|
133
|
+
prompt = await custom_builder.build_system_prompt(admin_user, mock_tools)
|
|
134
|
+
print("\nGenerated system prompt for admin user:")
|
|
135
|
+
print("-" * 60)
|
|
136
|
+
print(prompt)
|
|
137
|
+
print("-" * 60)
|
|
138
|
+
|
|
139
|
+
# Example 2: SQL-specific system prompt
|
|
140
|
+
print("\n" + "=" * 60)
|
|
141
|
+
print("Example 2: SQL Assistant System Prompt")
|
|
142
|
+
print("=" * 60)
|
|
143
|
+
|
|
144
|
+
sql_builder = SQLAssistantSystemPromptBuilder(database_name="Chinook")
|
|
145
|
+
analyst_user = User(id="user-2", username="Bob", permissions=["analyst"])
|
|
146
|
+
|
|
147
|
+
prompt = await sql_builder.build_system_prompt(analyst_user, mock_tools)
|
|
148
|
+
print("\nGenerated system prompt for SQL assistant:")
|
|
149
|
+
print("-" * 60)
|
|
150
|
+
print(prompt)
|
|
151
|
+
print("-" * 60)
|
|
152
|
+
|
|
153
|
+
# Example 3: Using custom builder with Agent
|
|
154
|
+
print("\n" + "=" * 60)
|
|
155
|
+
print("Example 3: Using Custom Builder with Agent")
|
|
156
|
+
print("=" * 60)
|
|
157
|
+
|
|
158
|
+
mock_llm = MockLlmService()
|
|
159
|
+
tool_registry = ToolRegistry()
|
|
160
|
+
|
|
161
|
+
agent = Agent(
|
|
162
|
+
llm_service=mock_llm,
|
|
163
|
+
tool_registry=tool_registry,
|
|
164
|
+
system_prompt_builder=sql_builder, # Inject custom builder here
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
print("\nAgent created with custom SQL system prompt builder!")
|
|
168
|
+
print("The agent will now use the SQL-focused system prompt for all interactions.")
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
if __name__ == "__main__":
|
|
172
|
+
import asyncio
|
|
173
|
+
|
|
174
|
+
asyncio.run(demo())
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Example demonstrating the DefaultWorkflowHandler with setup health checking.
|
|
3
|
+
|
|
4
|
+
This example shows how the DefaultWorkflowHandler provides intelligent starter UI
|
|
5
|
+
that adapts based on available tools and helps users understand their setup status.
|
|
6
|
+
|
|
7
|
+
Run:
|
|
8
|
+
PYTHONPATH=. python vanna/examples/default_workflow_handler_example.py
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import asyncio
|
|
12
|
+
|
|
13
|
+
from vanna import (
|
|
14
|
+
AgentConfig,
|
|
15
|
+
Agent,
|
|
16
|
+
MemoryConversationStore,
|
|
17
|
+
MockLlmService,
|
|
18
|
+
User,
|
|
19
|
+
DefaultWorkflowHandler,
|
|
20
|
+
)
|
|
21
|
+
from vanna.core.registry import ToolRegistry
|
|
22
|
+
from vanna.core.user.resolver import SimpleUserResolver
|
|
23
|
+
from vanna.tools import ListFilesTool
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
async def demonstrate_setup_scenarios():
|
|
27
|
+
"""Demonstrate different setup scenarios with DefaultWorkflowHandler."""
|
|
28
|
+
print("š Starting DefaultWorkflowHandler Setup Health Check Demo\n")
|
|
29
|
+
|
|
30
|
+
# Create basic components
|
|
31
|
+
llm_service = MockLlmService(response_content="I'm ready to help!")
|
|
32
|
+
conversation_store = MemoryConversationStore()
|
|
33
|
+
user_resolver = SimpleUserResolver()
|
|
34
|
+
|
|
35
|
+
# Create test user
|
|
36
|
+
user = User(
|
|
37
|
+
id="user1",
|
|
38
|
+
username="alice",
|
|
39
|
+
email="alice@example.com",
|
|
40
|
+
group_memberships=["user"],
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
print("=" * 60)
|
|
44
|
+
print("SCENARIO 1: Empty Setup (No Tools)")
|
|
45
|
+
print("=" * 60)
|
|
46
|
+
|
|
47
|
+
# Empty tool registry
|
|
48
|
+
empty_registry = ToolRegistry()
|
|
49
|
+
|
|
50
|
+
agent_empty = Agent(
|
|
51
|
+
llm_service=llm_service,
|
|
52
|
+
tool_registry=empty_registry,
|
|
53
|
+
user_resolver=user_resolver,
|
|
54
|
+
conversation_store=conversation_store,
|
|
55
|
+
config=AgentConfig(stream_responses=False),
|
|
56
|
+
workflow_handler=DefaultWorkflowHandler(),
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
print("š Starter UI for empty setup:")
|
|
60
|
+
async for component in agent_empty.send_message(
|
|
61
|
+
request_context=user_resolver.create_request_context(
|
|
62
|
+
metadata={"starter_ui_request": True}
|
|
63
|
+
),
|
|
64
|
+
message="",
|
|
65
|
+
conversation_id="empty-setup",
|
|
66
|
+
):
|
|
67
|
+
if hasattr(component, "simple_component") and component.simple_component:
|
|
68
|
+
print(f" š {component.simple_component.text[:100]}...")
|
|
69
|
+
elif hasattr(component, "rich_component"):
|
|
70
|
+
comp = component.rich_component
|
|
71
|
+
if hasattr(comp, "title"):
|
|
72
|
+
print(f" š {comp.title}: {comp.status} - {comp.description}")
|
|
73
|
+
elif hasattr(comp, "content"):
|
|
74
|
+
print(f" š {comp.content[:100]}...")
|
|
75
|
+
|
|
76
|
+
print("\n" + "=" * 60)
|
|
77
|
+
print("SCENARIO 2: Functional Setup (SQL + Basic Tools)")
|
|
78
|
+
print("=" * 60)
|
|
79
|
+
|
|
80
|
+
# Tool registry with SQL tool (simulated)
|
|
81
|
+
functional_registry = ToolRegistry()
|
|
82
|
+
|
|
83
|
+
# Register a mock SQL tool (we'll simulate by tool name)
|
|
84
|
+
list_tool = ListFilesTool()
|
|
85
|
+
list_tool.name = "run_sql" # Simulate SQL tool
|
|
86
|
+
functional_registry.register(list_tool)
|
|
87
|
+
|
|
88
|
+
agent_functional = Agent(
|
|
89
|
+
llm_service=llm_service,
|
|
90
|
+
tool_registry=functional_registry,
|
|
91
|
+
user_resolver=user_resolver,
|
|
92
|
+
conversation_store=conversation_store,
|
|
93
|
+
config=AgentConfig(stream_responses=False),
|
|
94
|
+
workflow_handler=DefaultWorkflowHandler(),
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
print("š Starter UI for functional setup:")
|
|
98
|
+
async for component in agent_functional.send_message(
|
|
99
|
+
request_context=user_resolver.create_request_context(
|
|
100
|
+
metadata={"starter_ui_request": True}
|
|
101
|
+
),
|
|
102
|
+
message="",
|
|
103
|
+
conversation_id="functional-setup",
|
|
104
|
+
):
|
|
105
|
+
if hasattr(component, "simple_component") and component.simple_component:
|
|
106
|
+
print(f" š {component.simple_component.text[:100]}...")
|
|
107
|
+
elif hasattr(component, "rich_component"):
|
|
108
|
+
comp = component.rich_component
|
|
109
|
+
if hasattr(comp, "title"):
|
|
110
|
+
print(f" š {comp.title}: {comp.status} - {comp.description}")
|
|
111
|
+
elif hasattr(comp, "content"):
|
|
112
|
+
print(f" š {comp.content[:100]}...")
|
|
113
|
+
|
|
114
|
+
print("\n" + "=" * 60)
|
|
115
|
+
print("SCENARIO 3: Complete Setup (SQL + Memory + Visualization)")
|
|
116
|
+
print("=" * 60)
|
|
117
|
+
|
|
118
|
+
# Complete tool registry
|
|
119
|
+
complete_registry = ToolRegistry()
|
|
120
|
+
|
|
121
|
+
# Mock SQL tool
|
|
122
|
+
sql_tool = ListFilesTool()
|
|
123
|
+
sql_tool.name = "run_sql"
|
|
124
|
+
complete_registry.register(sql_tool)
|
|
125
|
+
|
|
126
|
+
# Mock memory tools
|
|
127
|
+
search_tool = ListFilesTool()
|
|
128
|
+
search_tool.name = "search_saved_correct_tool_uses"
|
|
129
|
+
complete_registry.register(search_tool)
|
|
130
|
+
|
|
131
|
+
save_tool = ListFilesTool()
|
|
132
|
+
save_tool.name = "save_question_tool_args"
|
|
133
|
+
complete_registry.register(save_tool)
|
|
134
|
+
|
|
135
|
+
# Mock visualization tool
|
|
136
|
+
viz_tool = ListFilesTool()
|
|
137
|
+
viz_tool.name = "visualize_data"
|
|
138
|
+
complete_registry.register(viz_tool)
|
|
139
|
+
|
|
140
|
+
agent_complete = Agent(
|
|
141
|
+
llm_service=llm_service,
|
|
142
|
+
tool_registry=complete_registry,
|
|
143
|
+
user_resolver=user_resolver,
|
|
144
|
+
conversation_store=conversation_store,
|
|
145
|
+
config=AgentConfig(stream_responses=False),
|
|
146
|
+
workflow_handler=DefaultWorkflowHandler(),
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
print("š Starter UI for complete setup:")
|
|
150
|
+
async for component in agent_complete.send_message(
|
|
151
|
+
request_context=user_resolver.create_request_context(
|
|
152
|
+
metadata={"starter_ui_request": True}
|
|
153
|
+
),
|
|
154
|
+
message="",
|
|
155
|
+
conversation_id="complete-setup",
|
|
156
|
+
):
|
|
157
|
+
if hasattr(component, "simple_component") and component.simple_component:
|
|
158
|
+
print(f" š {component.simple_component.text[:100]}...")
|
|
159
|
+
elif hasattr(component, "rich_component"):
|
|
160
|
+
comp = component.rich_component
|
|
161
|
+
if hasattr(comp, "title"):
|
|
162
|
+
print(f" š {comp.title}: {comp.status} - {comp.description}")
|
|
163
|
+
elif hasattr(comp, "content"):
|
|
164
|
+
print(f" š {comp.content[:100]}...")
|
|
165
|
+
|
|
166
|
+
print("\n" + "=" * 60)
|
|
167
|
+
print("SCENARIO 4: Testing Commands")
|
|
168
|
+
print("=" * 60)
|
|
169
|
+
|
|
170
|
+
print("š Testing /help command:")
|
|
171
|
+
async for component in agent_complete.send_message(
|
|
172
|
+
request_context=user_resolver.create_request_context(),
|
|
173
|
+
message="/help",
|
|
174
|
+
conversation_id="help-test",
|
|
175
|
+
):
|
|
176
|
+
if hasattr(component, "rich_component") and hasattr(
|
|
177
|
+
component.rich_component, "content"
|
|
178
|
+
):
|
|
179
|
+
print(f" š Help: {component.rich_component.content[:200]}...")
|
|
180
|
+
|
|
181
|
+
print("\nš Testing /status command:")
|
|
182
|
+
async for component in agent_complete.send_message(
|
|
183
|
+
request_context=user_resolver.create_request_context(),
|
|
184
|
+
message="/status",
|
|
185
|
+
conversation_id="status-test",
|
|
186
|
+
):
|
|
187
|
+
if hasattr(component, "rich_component"):
|
|
188
|
+
comp = component.rich_component
|
|
189
|
+
if hasattr(comp, "title"):
|
|
190
|
+
print(f" š {comp.title}: {comp.status}")
|
|
191
|
+
elif hasattr(comp, "content"):
|
|
192
|
+
print(f" š Status: {comp.content[:150]}...")
|
|
193
|
+
|
|
194
|
+
print("\nā
Demo complete! The DefaultWorkflowHandler provides:")
|
|
195
|
+
print(" ⢠Smart setup health checking")
|
|
196
|
+
print(" ⢠Contextual starter UI based on available tools")
|
|
197
|
+
print(" ⢠Helpful error messages and setup guidance")
|
|
198
|
+
print(" ⢠Built-in command handling (/help, /status)")
|
|
199
|
+
print(" ⢠Automatic tool analysis and recommendations")
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
async def main():
|
|
203
|
+
"""Run the DefaultWorkflowHandler demonstration."""
|
|
204
|
+
await demonstrate_setup_scenarios()
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
if __name__ == "__main__":
|
|
208
|
+
asyncio.run(main())
|