An AI-powered platform for reading and analyzing financial reports using RAG/CAG/KAG architecture with Rust.
Functional Core - Imperative Shell + Railway Oriented Programming
βββ core/ # Business logic (Functional Core)
β βββ domain/ # Domain models
β βββ ports/ # Trait interfaces
β βββ adapters/ # I/O implementations (Imperative Shell)
β βββ services/ # RAG/CAG/KAG services
β βββ agent/ # Agent orchestration
βββ api/ # Axum REST API
βββ cli/ # Ratatui terminal UI
βββ financial_service/ # Python yfinance microservice
βββ prompts.json # Externalized System Prompts
βββ llm_config.json # LLM provider configuration
βββ docker-compose.yml # Infrastructure orchestration
- Language: Rust
- File Storage: MinIO (S3-compatible)
- Database: SurrealDB (Vector + Graph + Memory Store)
- LLM: Multi-provider support (Ollama, Gemini, OpenAI, Anthropic)
- Embeddings: Ollama mxbai-embed-large
- PDF Extraction: Extractous
- Backend: Axum with streaming support
- CLI: Ratatui
- Financial Data: Python/yfinance microservice
- Web Search: Brave Search API
- Container: Docker Compose
- Docker & Docker Compose
- Rust toolchain (1.75+)
- (Optional) Local Ollama models cached at
~/.ollama
Run everything in Docker, including the API server:
./start.sh --dockerThis will:
- Start all infrastructure (SurrealDB, Ollama, MinIO, Financial Service)
- Build and run the API server in Docker
- Copy local Ollama models if available (faster startup)
- Wait for all services to be healthy
Once ready, run the CLI:
cargo run --bin cliRun the API locally with Docker infrastructure:
# Start infrastructure only
./start.sh
# In terminal 1: Run API server
cargo run --bin api
# In terminal 2: Run CLI
cargo run --bin cliRebuild only the API container without restarting infrastructure:
./start.sh --rebuild| Service | Port | Description |
|---|---|---|
| SurrealDB | 8000 | Vector, Graph, and Memory Database |
| Ollama | 11434 | LLM & embedding service |
| MinIO | 9000 | S3-compatible file storage |
| MinIO Console | 9001 | Web UI for file management |
| API Server | 3000 | REST API endpoints |
| Financial Service | 8001 | Python/yfinance for stock data |
Copy from example and customize:
cp .env.example .envKey variables:
GEMINI_API_KEY- Google Gemini API keyOPENAI_API_KEY- OpenAI API keyANTHROPIC_API_KEY- Anthropic API keyBRAVE_SEARCH_API_KEY- Brave Search API keyOLLAMA_BASE_URL- Ollama endpoint (default: http://localhost:11434)
Configure which LLM provider and model to use for each task:
- Main LLM for generation
- Intent detection
- Entity extraction
- Embeddings
System prompts for the AI agents:
- general_system_prompt: Used for standard RAG/CAG queries
- financial_analysis_prompt: Used for financial analysis with Chain of Thought (CoT)
curl -X POST http://localhost:3000/api/documents \
-F "file=@NAB_2024_Annual_Report.pdf"curl -X POST http://localhost:3000/api/query/stream \
-H "Content-Type: application/json" \
-d '{"text": "What was the total revenue?", "max_results": 50}'curl -X POST http://localhost:3000/api/query \
-H "Content-Type: application/json" \
-d '{"text": "What are the key financial highlights?", "max_results": 50}'cargo run --bin cliFeatures:
- Interactive document upload
- Real-time streaming responses
- Conversation history with CAG
- Multi-document support
-
RAG (Retrieval Augmented Generation)
- Vector similarity search on embeddings
- Retrieve top-k relevant chunks
- LLM generates answer with context
-
CAG (Context Augmented Generation)
- Memory Manager: Short-term (Sliding Window) and Long-term (Vector Search)
- SurrealDB Memory Store: Persists conversation history
- Context-aware follow-up questions
-
KAG (Knowledge Augmented Generation)
- Graph traversal to find related documents
- Cross-document knowledge synthesis
- Relationship-aware answers
-
Agent Orchestrator
- Intent Detection: Routes queries to RAG, Financial Analysis, or Web Search
- Web Search: Integrates real-time data via Brave Search API
- Financial Service: Fetches live stock data via yfinance
- Multi-entity Support: Handles queries about multiple companies
PDF Upload β MinIO Storage
β PDF Extraction (Extractous)
β Text Chunking (Semantic)
β Embedding Generation (Ollama)
β Vector Storage (SurrealDB)
β Graph Relationships (SurrealDB)
Query β Intent Detection (Orchestrator)
β [Web Search Strategy] β Brave Search β Answer
β [Financial Data Strategy] β yfinance Service β Answer
β [RAG/CAG Strategy]
β Memory Retrieval (Short-term + Long-term)
β Vector Similarity Search (Documents)
β LLM Generation (Streaming)
β Answer with Citations
AI_Financial_Report_Reader_v5/
βββ api/ # REST API Server (Axum)
β βββ src/
β βββ main.rs # Server setup, routes, AppState
β βββ dto.rs # Request/Response DTOs
β βββ handlers/ # Route handlers
β βββ documents.rs # Upload, list, delete documents
β βββ query.rs # Query & streaming endpoints
β βββ health.rs # Health check
β
βββ cli/ # Terminal UI Client (Ratatui)
β βββ src/
β βββ main.rs # TUI application
β βββ ui.rs # UI components & layout
β βββ client.rs # API client with streaming
β βββ markdown.rs # Markdown rendering
β βββ utils.rs # Helper utilities
β
βββ core/ # Business Logic (Functional Core)
β βββ src/
β βββ config.rs # Configuration management
β βββ domain/ # Pure domain models
β β βββ mod.rs # Document, Chunk, Query, Answer
β β βββ entity.rs # Named entities (Company, Ticker)
β β βββ agent.rs # Agent types & tools
β β βββ memory.rs # MemoryEntry, conversation history
β β βββ error.rs # Domain errors (Railway pattern)
β β
β βββ ports/ # Trait interfaces (Dependency Inversion)
β β βββ llm.rs # LLM trait (generate, stream)
β β βββ embedding.rs # Embedding trait
β β βββ vector_db.rs # VectorDatabase trait
β β βββ graph_db.rs # GraphDatabase trait
β β βββ memory_store.rs # MemoryStore trait
β β βββ file_storage.rs # FileStorage trait
β β βββ pdf_extractor.rs # PdfExtractor trait
β β βββ web_search.rs # WebSearch trait
β β βββ financial.rs # FinancialData trait
β β βββ entity_extraction.rs # NER trait
β β
β βββ adapters/ # Concrete Implementations
β β βββ ollama.rs # Ollama LLM & embeddings
β β βββ gemini_llm.rs # Google Gemini LLM
β β βββ gemini_custom.rs # Custom Gemini client
β β βββ llm_factory.rs # Multi-provider factory
β β βββ surrealdb_vector.rs # Vector storage
β β βββ surrealdb_graph.rs # Graph relationships
β β βββ surrealdb_memory.rs # Conversation memory
β β βββ rustfs.rs # MinIO S3 storage
β β βββ pdf_extractous.rs # PDF extraction (Extractous)
β β βββ brave_search.rs # Brave Search API
β β βββ financial_service.rs # yfinance client
β β βββ ollama_ner.rs # Named Entity Recognition
β β
β βββ services/ # Business Logic Services
β β βββ document_ingestion.rs # Upload & indexing
β β βββ embedding.rs # Embedding generation
β β βββ memory_manager.rs # Short/long-term memory
β β βββ query_processing.rs # Query preprocessing
β β βββ re_ranker.rs # Result re-ranking
β β βββ router_agent.rs # Intent detection & routing
β β βββ agent_orchestrator.rs # Main orchestrator
β β βββ cag.rs # Context Augmented Generation
β β βββ kag.rs # Knowledge Augmented Generation
β β
β βββ agent/ # Agent Framework
β βββ agent.rs # Agent execution loop
β βββ builder.rs # Agent builder pattern
β βββ tool.rs # Tool definitions
β βββ prompts.rs # Agent system prompts
β
βββ financial_service/ # Python Microservice (yfinance)
β βββ main.py # FastAPI server
β βββ Dockerfile
β βββ requirements.txt
β
βββ scripts/ # Utility Scripts
β βββ download_models.sh # Ollama model setup
β βββ run_benchmark.sh # Performance benchmarks
β βββ test_*.sh # Test scripts
β
βββ docker-compose.yml # Infrastructure orchestration
βββ Dockerfile # API container build
βββ start.sh # One-command startup
βββ llm_config.json # LLM provider configuration
βββ prompts.json # System prompts
βββ .env.example # Environment template
cargo test --workspace./scripts/run_benchmark.shcargo check
cargo clippycargo fmtlsof -ti:3000 | xargs kill -9# Models are auto-copied from ~/.ollama if available
# Otherwise, pull manually:
docker exec -it ollama ollama pull qwen3:8b
docker exec -it ollama ollama pull mxbai-embed-large# Check container health
docker exec surrealdb /surreal isready --conn http://localhost:8000
# Restart if needed
docker-compose restart surrealdbDefault credentials: minioadmin / minioadmin
Console: http://localhost:9001
If using both Podman Desktop and OrbStack, ensure only one is running:
# Check current Docker context
docker context ls
# Switch to OrbStack
docker context use orbstackMIT License
Mike Graham