This repository contains our project developed for the Mistral Datathon (February 2026).
The goal of the project is to explore and prototype a multi-agent geopolitical simulation powered by Large Language Models (LLMs), using Mistral models as the reasoning backbone.
The system models countries as autonomous agents capable of making strategic decisions (e.g., war declarations, alliances, trade, sanctions) within a structured world state. Actions have quantitative effects on inter-country relationships and internal metrics, enabling controlled simulation dynamics.
The main objectives of this project are:
-
Design a multi-agent architecture driven by LLM-based decision-making.
-
Define a structured world state representation with measurable metrics.
-
Implement a rule-based simulation engine with quantitative effects.
-
Build an interactive React frontend with map visualization to explore the simulation state in real time.
-
Experiment with hybrid control:
- LLM-driven strategic reasoning
- Deterministic, auditable simulation rules
-
Explore negotiation dynamics such as alliance proposals and responses.
The project emphasizes architectural clarity and modularity rather than production-ready deployment.
The system is organized into three layers:
-
Frontend (React + Maps)
Visualizes the world state (countries, relations, events) and provides a UI to run turns / trigger actions.
-
API Layer (FastAPI)
Bridges the frontend with the backend logic, exposing endpoints to:
- fetch world state
- step the simulation (turn-based loop)
- return updated state for visualization
-
Multi-LLM + Simulation Core
- Multi-LLM layer: country agents select structured actions using Mistral models
- Simulation engine: applies deterministic rules and quantitative effects to update the world
To provide a seamless and responsive user experience, the communication between the React frontend and the FastAPI backend leverages WebSockets.
While the simulation itself operates on a turn-based logic, resolving a full turn requires multiple LLM queries that can take time to process. WebSockets enhance the architecture by providing:
-
Instant UI synchronization: The map, event logs and country statistics update immediately as soon as the backend resolves an action, without the need for manual page refreshes.
-
Efficient communication: By pushing state changes directly to the client, we completely eliminate the need for heavy HTTP polling. This reduces latency and keeps the server load low, even during complex, multi-agent simulation steps.
The cognitive core of our country agents is powered by Mistral Small 3.2 (specifically the mistral-small-2506 endpoint) via the Mistral API.
In a multi-agent environment where every turn requires multiple complex evaluations, we selected this specific model for three main reasons:
-
Low latency and scalability: Running a world simulation requires computing decisions for multiple countries per turn.
mistral-small-2506provides the necessary speed to keep the simulation loop fluid without bottlenecks. -
Reliable structured outputs: Our simulation engine relies on strict deterministic rules. The model excels at strictly following our system prompts and reliably returning well-formatted JSON payloads (mapping perfectly to our
ActionandToolCallPydantic schemas) without hallucinating unsupported tools. -
Nuanced strategic reasoning: Despite being a small tier model, it proves highly capable of analyzing complex, multi-variable contexts (e.g., weighing military advantages against economic deficits or pending alliances) and generating coherent, context-aware justifications for its diplomatic actions.
To start the project, you will need Docker installed. You must run both the backend and frontend containers in separate terminal windows.
Navigate to the backend directory, clean up any previous conflicting volumes and build the container:
cd Hackathon-Demo/back-end
docker compose down -v
docker compose up --buildNavigate to the frontend directory, clean up any previous conflicting volumes and build the container:
cd Hackathon-Demo/front-end
docker compose down -v
docker compose up --buildThe frontend reads the backend base URL from .venv file:
VITE_PUBLIC_API_URL=http://localhost:8000Why this differs between environments
-
WSL2 / Docker Desktop (Windows): Containers run inside a VM. The browser cannot access Docker’s internal
172.x.x.xnetwork, so you must use the host-published port vialocalhost. -
Native Linux Docker: Docker runs natively and the bridge network is directly accessible. You can retrieve the backend container IP with:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' fastapi_backendThen set:
VITE_PUBLIC_API_URL=http://<BACKEND_IP>:<backend_port>Using localhost is generally more portable, but on native Linux accessing the container IP may also work.
Once the frontend container finishes building and starts, you will see an output similar to this in your terminal:
react_frontend | VITE v7.3.1 ready in 307 ms
react_frontend |
react_frontend | ➜ Local: http://localhost:5173/
react_frontend | ➜ Network: http://172.23.0.2:5173/To load the web application in your browser, choose the appropriate link based on your operating system (keeping in mind the Backend URL configuration explained in the previous section):
-
Windows (WSL2 / Docker Desktop): Use the
LocalURL (http://localhost:5173/). -
Native Linux: You can use the
NetworkURL (http://172.23.0.2:5173/) to access the container directly via the Docker bridge network.
Upon starting the frontend, you are greeted by the Home page, which serves as the main entry point for the application:
-
How it works: Clicking this button navigates you to a detailed overview of the project, including its purpose, the architecture, simulation mechanics and the underlying game rules, among other information.
-
Start simulation: This button takes you directly to the interactive map interface, where you can select your countries and begin the match.
-
Top Navbar: You can also jump straight into the action at any time by clicking the MAP link in the top navigation bar.
Once you navigate to the map and begin a session, the app operates as a turn-based, controlled environment. While the Mistral LLM drives the strategic reasoning, the simulation engine enforces strict deterministic rules to calculate the outcomes.
-
Selection: The match begins by selecting five countries from the interactive map interface.
-
Initialization: The simulation loads the initial
WorldState, assigning starting internal metrics (e.g., economy, military power) and baseline bilateral relations to the selected countries.
-
Progression: The simulation advances manually when the user clicks the "Next Turn" button in the side panel.
-
Action selection: During each turn, the active country agent evaluates the global context and selects a single structured action (or decides to pass).
-
Deterministic outcomes: Once an action is chosen (e.g.,
PROPOSE_ALLIANCE,SANCTION,DECLARE_WAR,TRADE), the simulation engine applies predefined, quantitative effects. -
Impact: These actions dynamically alter both the internal statistics of the involved countries and their diplomatic relationships. These changes are visually updated in real-time on the interactive map, reflecting new diplomatic stances through relation lines and updating the values displayed inside each country's popup.
- To maintain system stability and prevent numbers from scaling infinitely, all relationship scores are strictly bounded (e.g., from
-100representing absolute hostility to+100for perfect alliances), and internal stats are clamped between0and100.
Once the backend container finishes building and starts successfully, you will see output similar to this:
postgres_db | 2026-03-01 23:47:25.476 UTC [1] LOG: database system is ready to accept connections
Container postgres_db Healthy
fastapi_backend | INFO: Started server process [1]
fastapi_backend | INFO: Waiting for application startup.
fastapi_backend | Database already initialized. Skipping seed.
fastapi_backend | INFO: Application startup complete.
fastapi_backend | INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)With the backend running, you can view and test all the available routes of the app by visiting http://localhost:8000/docs in your browser.
-
WorldState: global representation of the simulation.
-
CountryState: per-country metrics (economy, military power, technology, etc.).
-
RelationState: bilateral relationship scores between countries.
-
ActionType: structured action space (e.g., propose alliance, respond to alliance, war, sanction, trade, pass).
-
Quantitative Effects: diplomatic actions translate into bounded numerical changes.
The interactive world map in the front-end is built using Leaflet and renders country polygons from a GeoJSON file.
Please note the following technical decisions and limitations regarding the visualization:
-
Simplified geometry: To ensure fast rendering and optimal performance in the browser, the chosen GeoJSON uses a reduced number of vertices. As a result, country borders are approximated and not perfectly exact.
-
Missing countries (ISO 3166-1 alpha-3): You might notice that some countries or territories are not interactive on the map. This occurs due to data inconsistencies or missing mappings of the ISO 3166-1 alpha-3 codes between the GeoJSON file properties and our simulation's database.




