Architecture Overview
LouieAI is built around a thread-based conversation system with specialized agents. The library provides both a notebook-friendly interface and a traditional client API for different use cases.
Core Components
1. Thread System
LouieAI maintains conversation threads that preserve context across multiple queries:
# Traditional client API
client = LouieClient()
response = client.add_cell(thread_id, "Analyze customer data") # Adds to existing thread
response = client.add_cell("", "Follow-up question") # Creates new thread
# Notebook API
from louieai.notebook import lui
lui("Analyze customer data") # Auto-manages thread
lui("Follow-up question") # Continues same thread
2. Agent System
40+ specialized agents handle different data sources and tasks:
- Database Agents: PostgresAgent, MySQLAgent, SnowflakeAgent, etc.
- Visualization Agents: GraphAgent, PerspectiveAgent, KeplerAgent
- Development Agents: CodeAgent, NotebookAgent, TableAIAgent
- Passthrough Agents: Direct query execution without AI interpretation
3. Response Elements
Responses contain structured elements rather than raw text:
response.elements = [
{"type": "TextElement", "content": "Analysis results..."},
{"type": "DfElement", "table": pandas_dataframe},
{"type": "DebugLine", "text": "Debug info"},
{"type": "ExceptionElement", "error": "Error details"}
]
API Architecture
Thread Management
When you call client.add_cell(thread_id, prompt, agent="SomeAgent"):
- Authentication: Retrieves JWT from PyGraphistry via
graphistry.api_token() - Thread Resolution: Creates new thread if
thread_id="", otherwise uses existing - Agent Selection: Routes to specified agent (defaults to LouieAgent)
- API Request: POST to
/api/dthread/{thread_id}/cellwith prompt and agent - Response Processing: Parses structured response elements
- Error Handling: Raises
RuntimeErrorwith detailed error messages
Notebook Interface
The notebook API (lui) provides a streamlined interface:
lui("Query") # Returns cursor object, auto-displays in Jupyter
lui.text # Access last response text
lui.df # Access last response dataframe
lui[-1].df # Access previous response dataframe
lui.has_errors # Check for errors
lui.errors # List of error elements
Streaming Support
Real-time response streaming in Jupyter notebooks:
- Progressive display updates as responses arrive
- Throttled updates (max 10/second) for performance
- Element-by-element rendering with appropriate styling
- Dataframe fetching via
/api/dthread/{thread_id}/df/block/{block_id}/arrow
Data Flow
User Query → Agent Selection → LouieAI API → Agent Processing → Structured Response → Element Rendering
- Input: Natural language query with optional agent specification
- Routing: Agent system routes to appropriate handler (database, visualization, etc.)
- Processing: Agent processes query (SQL generation, code execution, etc.)
- Response: Structured elements returned (text, dataframes, visualizations)
- Display: Elements rendered appropriately (HTML, tables, graphs)
Design Principles
Multi-tenancy Support
- Isolated clients: Separate
LouieClientinstances with distinct authentication - Thread isolation: Each client maintains independent conversation threads
- No shared state: Thread-safe for concurrent multi-user applications
Error Handling
- Structured errors: Error elements included in response rather than exceptions
- Graceful degradation: Partial responses displayed even with some errors
- Debug information: DebugLine and InfoLine elements for troubleshooting
Agent Flexibility
- AI-assisted agents: Natural language to query language with semantic understanding
- Passthrough agents: Direct execution for precise control
- Agent composition: Chain different agents for complex workflows
Current API Endpoints
POST /api/dthread/{thread_id}/cell: Add cell to thread (main query endpoint)GET /api/dthread/{thread_id}/df/block/{block_id}/arrow: Fetch dataframe as Arrow formatPOST /api/dthread/create: Create new thread- Authentication via JWT tokens from PyGraphistry
Integration Points
PyGraphistry Integration
- Shares authentication tokens seamlessly
- Leverages existing PyGraphistry server configurations
- Supports multi-server deployments (hub.graphistry.com ↔ den.louie.ai)
Jupyter Notebook Integration
- IPython.display integration for rich output
- Real-time streaming with progressive updates
- Automatic dataframe and visualization rendering
- History management with indexed access (
lui[-1],lui[-2], etc.)
Distributed Tracing (OpenTelemetry)
LouieAI automatically propagates W3C traceparent headers for distributed tracing:
With OpenTelemetry configured:
# Your existing OTel span context is automatically propagated
with tracer.start_as_current_span("my_analysis"):
lui("analyze data") # Request includes your trace context
Without OpenTelemetry:
# Session-level trace ID generated automatically for correlation
lui = louieai.Cursor()
lui("query 1") # All requests share a session trace_id
lui("query 2") # Same trace_id, different span_id
child = lui.new()
child("query 3") # Same session trace_id (inherited)
This enables: - Linking client requests to server-side traces in Tempo, Jaeger, etc. - Correlating all prompts within a Cursor session - No configuration required - works automatically