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 VannaBase class β†’ 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
tools = LegacyVannaAdapter(vn)

# Create agent with new LLM service
llm = AnthropicLlmService(model="claude-haiku-4-5")
agent = Agent(llm_service=llm, tool_registry=tools, 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:

  • Automatically wraps vn.run_sql() as the run_sql tool (available to β€˜user’ and β€˜admin’ groups)
  • Exposes training data from vn.get_training_data() as searchable memory (via search_saved_correct_tool_uses tool)
  • Optionally allows saving new training data (via save_question_tool_args tool - admin only)
  • Maintains your existing database connection and training data

Key Architectural Differences

FeatureVanna 0.xVanna 2.0+
User ContextNoneUser object with permissions flows through entire system
Interaction ModelDirect method calls (vn.ask())Agent-based with streaming components
ToolsMonolithic methodsModular Tool classes with schemas
ResponsesPlain text/DataFramesRich UI components (tables, charts, code)
Trainingvn.train() with vector DBSystem prompts, context enrichers, RAG tools
Database Connectionvn.connect_to_postgres()SqlRunner implementations as dependencies
Web UIOld Vanna FlaskBuilt-in web component + backend
StreamingNoneServer-Sent Events by default
PermissionsNoneGroup-based access control on tools
Audit LogsNoneBuilt-in audit logging system