Migration Guide: Vanna 0.x to Vanna 2.0+
This guide will help you migrate from Vanna 0.x (legacy) to Vanna 2.0+, the new user-aware agent framework.
Overview of Changes
Vanna 2.0+ represents a fundamental architectural shift from a simple LLM wrapper to a full-fledged user-aware agent framework. Here are the major changes:
Whatβs New in 2.0+
- β User awareness - Identity and permissions flow through every layer
- β Web component - Pre-built UI with streaming responses
- β Tool registry - Modular, extensible tool system
- β Rich UI components - Tables, charts, status cards (not just text)
- β Streaming by default - Progressive responses via SSE
- β Enterprise features - Audit logs, rate limiting, observability
- β FastAPI/Flask servers - Production-ready backends included
What Changed from 0.x
- β Direct method calls (
vn.ask()) β Agent-based workflow - β Monolithic
VannaBaseclass β Modular tool system - β No user context β User-aware at every layer
- β Simple text responses β Rich streaming UI components
Quick Migration Path
Canβt migrate immediately? Use the Legacy Adapter to get started quickly:
# Assume you already have a working vn object from your Vanna 0.x code:
# vn = MyVanna(config={"model": "gpt-4"})
# vn.connect_to_postgres(...)
# vn.train(ddl="...")
# NEW: Just add these imports and wrap your existing vn object
from vanna import Agent, AgentConfig
from vanna.servers.fastapi import VannaFastAPIServer
from vanna.core.user import UserResolver, User, RequestContext
from vanna.legacy.adapter import LegacyVannaAdapter
from vanna.integrations.anthropic import AnthropicLlmService
# Define simple user resolver
class SimpleUserResolver(UserResolver):
async def resolve_user(self, request_context: RequestContext) -> User:
user_email = request_context.get_cookie('vanna_email')
return User(id=user_email, email=user_email, group_memberships=['user'])
# Wrap your existing vn with the adapter
legacy_adapter = LegacyVannaAdapter(vn)
# Create agent with new LLM service
llm = AnthropicLlmService(model="claude-haiku-4-5")
agent = Agent(
llm_service=llm,
tool_registry=legacy_adapter, # LegacyVannaAdapter is a ToolRegistry
agent_memory=legacy_adapter, # LegacyVannaAdapter implements AgentMemory
user_resolver=SimpleUserResolver()
)
# Run server
server = VannaFastAPIServer(agent)
server.run(host='0.0.0.0', port=8000)
# Now it works with the new Agent framework! What the LegacyVannaAdapter does:
- Implements both
ToolRegistryandAgentMemoryinterfaces - Automatically wraps
vn.run_sql()as therun_sqltool (available to βuserβ and βadminβ groups) - Exposes training data as searchable memory via
AgentMemoryinterface - Provides memory tools:
save_question_tool_args(admin) andsearch_saved_correct_tool_uses(user, admin) - Maintains your existing database connection and training data
Key Architectural Differences
| Feature | Vanna 0.x | Vanna 2.0+ |
|---|---|---|
| User Context | None | User object with permissions flows through entire system |
| Interaction Model | Direct method calls (vn.ask()) | Agent-based with streaming components |
| Tools | Monolithic methods | Modular Tool classes with schemas |
| Responses | Plain text/DataFrames | Rich UI components (tables, charts, code) |
| Training | vn.train() with vector DB | System prompts, context enrichers, RAG tools |
| Database Connection | vn.connect_to_postgres() | SqlRunner implementations as dependencies |
| Web UI | Old Vanna Flask | Built-in web component + backend |
| Streaming | None | Server-Sent Events by default |
| Permissions | None | Group-based access control on tools |
| Audit Logs | None | Built-in audit logging system |