Skip to content

AI-powered decision intelligence system for Formula 1 strategy analysis, transforming race documents and OpenF1 telemetry into evidence-backed timelines and strategic insights using local LLMs.

Notifications You must be signed in to change notification settings

mateluky/f1-race-intelligence

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

18 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

F1 Race Intelligence System

An intelligent Formula 1 race analysis application that combines PDF document parsing with real-time OpenF1 API data to reconstruct comprehensive race timelines with interactive visualizations.

What is it?

F1 Race Intelligence is a Retrieval-Augmented Generation (RAG) system that analyzes F1 race documents (Wikipedia articles, race reports, etc.) and enriches them with live telemetry data from the OpenF1 API. It automatically extracts race events, pit stops, safety car periods, weather changes, overtakes, and moreβ€”then presents everything in an interactive timeline visualization.

Key Features

  • πŸ“„ PDF Upload & Parsing – Upload race documents and extract key events using LLM-powered analysis
  • πŸ”Œ OpenF1 API Integration – Automatically fetches real telemetry: pit stops, stints, race control messages, position changes, overtakes
  • 🏎️ Timeline Reconstruction – Merges PDF-extracted events with API data into a unified, chronological timeline
  • πŸ“Š Interactive Visualization – Plotly-powered chart showing all events by lap and driver with color-coded event types
  • πŸ” Advanced Filtering – Filter by event type, driver, or evidence source
  • 🎨 14 Event Type Categories – Safety Car, VSC, Red Flag, Yellow Flag, Pit Stop, Strategy, Weather, Incident, Overtake, Pace, Position, Result, Grid, Info

Architecture

                                 EXTERNAL SERVICES
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚   OLLAMA SERVER    β”‚    β”‚   OPENF1 API       β”‚
                    β”‚  localhost:11434   β”‚    β”‚ api.openf1.org     β”‚
                    β”‚  β€’ llama3 model    β”‚    β”‚  β€’ Live telemetry  β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚                         β”‚
══════════════════════════════β•ͺ═════════════════════════β•ͺ══════════════════════
                              β”‚       APPLICATION       β”‚
                              β”‚                         β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                             β”‚    USER INTERFACES      β”‚                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚                      GRADIO UI (ui_gradio.py)                         β”‚  β”‚
β”‚  β”‚  β€’ πŸ“„ PDF Upload Tab        β€’ πŸ“ˆ Visualization Tab (Plotly)           β”‚  β”‚
β”‚  β”‚  β€’ πŸ”Ž Timeline Explorer     β€’ πŸ“‹ Raw Data Tab                         β”‚  β”‚
β”‚  β”‚  β€’ πŸ“ Event Details Tab     β€’ 14 Event Type Filters                   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                      β”‚                                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚              MCP SERVER (server.py) + CLIENT (client.py)              β”‚  β”‚
β”‚  β”‚  β€’ FastAPI-based Model Context Protocol server                        β”‚  β”‚
β”‚  β”‚  β€’ Exposes tools: ingest_pdf, build_timeline, query_timeline          β”‚  β”‚
β”‚  β”‚  β€’ Enables AI assistant integration                                   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                      β”‚                                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                       β”‚
                                       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                       APP SERVICE (rag/app_service.py)                       β”‚
β”‚  β€’ Orchestrates all components      β€’ Metadata extraction (year, GP, session)β”‚
β”‚  β€’ Coordinates PDF ingestion        β€’ JSON serialization                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚                                       β”‚
                   β–Ό                                       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚       RAG PIPELINE               β”‚    β”‚       OPENF1 CLIENT (openf1/api.py)  β”‚
β”‚                                  β”‚    β”‚                                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚    β”‚  β€’ Sessions lookup & resolution      β”‚
β”‚  β”‚   Ingest (ingest.py)       β”‚  β”‚    β”‚  β€’ Race control messages (SC, VSC)   β”‚
β”‚  β”‚   β€’ PDF text extraction    β”‚  β”‚    β”‚  β€’ Pit stops & stint data            β”‚
β”‚  β”‚   β€’ Text chunking          β”‚  β”‚    β”‚  β€’ Position changes tracking         β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚    β”‚  β€’ Weather data                      β”‚
β”‚                β–Ό                 β”‚    β”‚  β€’ Overtakes detection               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚    β”‚  β€’ Starting grid positions           β”‚
β”‚  β”‚   Embed (embed.py)         β”‚  β”‚    β”‚  β€’ Session results                   β”‚
β”‚  β”‚   β€’ Sentence embeddings    β”‚  β”‚    β”‚  β€’ Rate limiting & caching           β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚    β”‚                                      β”‚
β”‚                β–Ό                 β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚   Store (store.py)         β”‚  β”‚
β”‚  β”‚   β€’ In-memory vector store β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                β–Ό                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚   Retrieve (retrieve.py)   β”‚  β”‚
β”‚  β”‚   β€’ Similarity search      β”‚  β”‚
β”‚  β”‚   β€’ Top-K retrieval        β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                β–Ό                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚   LLM (llm.py)             β”‚  β”‚
β”‚  β”‚   β€’ Ollama interface       β”‚  β”‚
β”‚  β”‚   β€’ Event extraction       β”‚  β”‚
β”‚  β”‚   β€’ Prompts (prompts.py)   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚   Agent (agent.py)         β”‚  β”‚
β”‚  β”‚   β€’ Query orchestration    β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     TIMELINE BUILDER (rag/timeline.py)                       β”‚
β”‚  β€’ Merges PDF events + OpenF1 events    β€’ Impact analysis scoring            β”‚
β”‚  β€’ Deduplication & conflict resolution  β€’ Event categorization (14 types)    β”‚
β”‚  β€’ Schemas (rag/schemas.py): TimelineEvent, TimelineEventType, etc.          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Project Structure

f1_race_intelligence/
β”œβ”€β”€ ui_gradio.py          # Main Gradio web interface
β”œβ”€β”€ server.py             # FastAPI MCP server
β”œβ”€β”€ client.py             # MCP client
β”œβ”€β”€ requirements.txt      # Python dependencies
β”œβ”€β”€ pytest.ini            # Test configuration
β”‚
β”œβ”€β”€ openf1/               # OpenF1 API client
β”‚   β”œβ”€β”€ __init__.py
β”‚   └── api.py            # API client with caching & rate limiting
β”‚
β”œβ”€β”€ rag/                  # RAG pipeline components
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ app_service.py    # Main orchestration service
β”‚   β”œβ”€β”€ timeline.py       # Timeline builder & merger
β”‚   β”œβ”€β”€ schemas.py        # Pydantic models (TimelineEvent, etc.)
β”‚   β”œβ”€β”€ ingest.py         # PDF parsing & chunking
β”‚   β”œβ”€β”€ embed.py          # Text embeddings
β”‚   β”œβ”€β”€ store.py          # Vector storage
β”‚   β”œβ”€β”€ retrieve.py       # Similarity search
β”‚   β”œβ”€β”€ llm.py            # Ollama LLM interface
β”‚   β”œβ”€β”€ prompts.py        # LLM prompt templates
β”‚   └── agent.py          # Agent orchestration
β”‚
β”œβ”€β”€ output/               # Generated outputs
β”‚   β”œβ”€β”€ race_brief.json
β”‚   └── race_brief.md
β”‚
└── tests/                # Test files

Quick Start

Prerequisites

  1. Python 3.10+
  2. Ollama with llama3 model: In a separte Terminal
    brew install ollama
    ollama pull llama3
    ollama serve

Installation

  1. Navigate to the project folder:

    cd path\to\Text Mining and NLP
  2. Activate the virtual environment:

    .\.venv\Scripts\activate

    If activation is blocked, run once:

    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
  3. Install dependencies (first run only):

    python -m pip install -r f1_race_intelligence\requirements.txt

Running the App

cd f1_race_intelligence
python ui_gradio.py

Open http://localhost:7860 (or the port shown in the terminal).

Usage

  1. Upload PDF – Go to "πŸ“„ Ingest" tab and upload a race document
  2. Build Timeline – Click "Build Timeline" to extract events and fetch OpenF1 data
  3. Explore – Use the "πŸ”Ž Timeline" tab to browse events with filters
  4. Visualize – Go to "πŸ“ˆ Visualization" to see the interactive chart
  5. Filter – Use the category filters (Race Control, Strategy, Session Info) to focus on specific event types

Event Types

Category Events
🚨 Race Control Safety Car, VSC, Red Flag, Yellow Flag, Incident
πŸ”§ Strategy Pit Stop, Stint Change, Pace Update, Overtake, Weather
πŸ“‹ Session Info Starting Grid, Results, Position, Info

Technology Stack

Layer Technology Purpose
Frontend Gradio 6.x Web UI with tabs for upload, timeline, visualization
Visualization Plotly Interactive timeline charts
API Server FastAPI MCP (Model Context Protocol) server
Data Validation Pydantic Schemas for TimelineEvent, EventType, etc.
LLM Runtime Ollama (localhost:11434) Local LLM inference
LLM Model llama3 Event extraction & text analysis
Embeddings Sentence Transformers Text vectorization
Vector Store In-memory Similarity search & Top-K retrieval
PDF Parsing PyPDF / pdfplumber Document text extraction & chunking
External API OpenF1 API Live telemetry, pit stops, race control data
Caching In-memory Rate limiting & API response caching
Language Python 3.10+ Core application runtime

License

MIT License

About

AI-powered decision intelligence system for Formula 1 strategy analysis, transforming race documents and OpenF1 telemetry into evidence-backed timelines and strategic insights using local LLMs.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages