Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

244 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

CivilizationOS

CI Tests Python Node License: MIT

A multi-agent society simulation powered by autonomous AI citizens, institutional councils, and a novel RAG architecture - built as a portfolio-grade AI project on a near-zero budget.

Status: feature-complete (Phases 0-13). 61 backend tests passing, 0 TypeScript errors.

CivilizationOS - 3D city with live citizen agents


What It Is

CivilizationOS is a hybrid of two paradigms:

Layer What it is
AGORA 10 autonomous citizen-agents live in an animated 3D city. They follow daily routines, have conversations, build relationships, form factions, and accumulate episodic memories.
PANTHEON 5 societal institutions (Government, Economy, Healthcare, Media, Police) are each governed by a council of 5 AI specialists that debate before acting.

You inject crises - Pandemic, Drought, Cyberattack, Election, Crime Wave, and more - and watch society react in real time. Councils deliberate, citizens respond with occupation-specific fear, relationships shift into alliances and rivalries, and the city's causal history builds up in a queryable graph.


Key Technical Differentiators

1. Temporal-Causal Memory Fusion (TCMF) - the novel RAG

Standard RAG retrieves by semantic similarity. TCMF fuses two retrieval streams:

AGORA stream    - per-citizen episodic memories scored by:
                    relevance (embedding cosine) ร— recency (exp-decay) ร— importance (LLM-rated)

PANTHEON stream - society-wide causal graph (NetworkX DiGraph):
                    crisis โ†’ council decision โ†’ policy outcome โ†’ downstream event

Fused score = episodic_score(m, q) ร— (1 + ฮป ร— causal_boost(m))

The causal_boost rewards memories that are semantically near the causal ancestors of the current crisis. A witness at the scene of a root cause outranks someone who heard about it second-hand. No off-the-shelf RAG system does this.

Full design write-up: docs/tcmf.md - the scoring formulas with code, a worked plague-outbreak example, the honest tradeoffs (inferred causality is noisy, three tunable parameters, BFS latency at scale), and what v2 would change.

2. 3-Tier LLM Router - runs at $0 in dev

Tier Brain Used for Cost
0 Ollama + Qwen2.5 3B (local) Citizen conversations, observations, reflections, embeddings $0
1 Gemini Flash (free tier) Council Historian / Strategist / Skeptic / Predictor $0
2 Claude API (Haiku/Sonnet) Council Synthesizer (VERDICT turn) in premium mode ~$0.002 / debate

PREMIUM_MODE=false in .env โ†’ everything runs locally at $0. Flip to true for the demo. A LoRA fine-tune of Qwen2.5 3B (civos-council) can also take over the 4 non-verdict debate roles once exported from the training notebook - see Fine-Tuned Council Model.

3. Council Debate Architecture

Each institution runs a structured 5-role debate when a crisis is injected:

๐Ÿ“œ Historian   - surfaces causal precedents from TCMF context
โš”๏ธ Strategist  - proposes 2 specific actionable interventions
๐Ÿ” Skeptic     - challenges the Strategist; names hidden risks + safeguards
๐Ÿ”ฎ Predictor   - probability estimate of success + worst-case scenario
โš–๏ธ Synthesizer - VERDICT: who does what, measured by what success metric

Institution lens shapes every debate: Government debates through law + democratic legitimacy; Economy through markets + trade; Healthcare through clinical protocols; Media through information integrity; Police through proportionality + civil rights. Councils also see active citizen factions in their context, so verdicts account for real social alliances.

4. Emergent Crisis Injection

Crises don't only arrive by hand. If average citizen fear stays above a sustained threshold for long enough, the engine synthesises a new crisis via LLM and injects it automatically - with a compound-cascade path for genuine emergencies and a cooldown to prevent spam. A TENSION meter in the header shows the countdown before an emergent crisis fires.

5. Citizen Factions

Union-find over mutual relationship affinity (>0.60, both directions) detects social blocs in real time - trade guilds, press circles, justice fronts. Factions get named, colour-ringed in the relationship graph, badged in the citizen inspector, and injected into every council's debate context.

6. Council Track Record

Each institution's verdicts are scored: fear measured 60 ticks after a verdict is delivered, compared to fear before, and converted into an effectiveness percentage (50 = neutral). Over a session you can see which councils actually make things better.

7. Occupation-Specific Crisis Reactions

Each citizen reacts through the lens of their profession - 42 distinct first-person reactions across 10 occupations ร— 5 crisis types:

  • Doctor on pandemic: "As a doctor I need to prepare triage protocols immediately - we'll be overwhelmed."
  • Journalist on election: "Three sources have contacted me about voting irregularities in the same district."
  • Trader on drought: "Food futures are spiking and the exchange algorithms are amplifying the panic."

8. Causal Graph + Story Rewind

Every injected crisis, council decision, and resolution is a node in a NetworkX directed graph with temporal causal edges. The Story Rewind panel lets you scrub a slider back through the tick history and watch the causal chain unfold, or expand any event for its full text.


Architecture

civilizationos/
โ”œโ”€โ”€ api/                       Python 3.12 + FastAPI backend
โ”‚   โ”œโ”€โ”€ main.py                 FastAPI app, WebSocket hub, all REST endpoints (v0.13.0)
โ”‚   โ”œโ”€โ”€ config.py                Settings (PREMIUM_MODE, API keys, tick speed)
โ”‚   โ”œโ”€โ”€ sim/
โ”‚   โ”‚   โ”œโ”€โ”€ engine.py            Async tick loop, crisis injection, verdict effects,
โ”‚   โ”‚   โ”‚                        emergent crises, council track record, factions
โ”‚   โ”‚   โ”œโ”€โ”€ world.py             20ร—15 grid, 10 named locations, day-phase clock
โ”‚   โ”‚   โ”œโ”€โ”€ crisis.py            CrisisRegistry - debate transcripts, resolved/emergent flags
โ”‚   โ”‚   โ””โ”€โ”€ events.py            Crisis templates with occupation-specific effects
โ”‚   โ”œโ”€โ”€ agents/
โ”‚   โ”‚   โ”œโ”€โ”€ citizen.py           Autonomous citizen (movement, memory, fear, backstory)
โ”‚   โ”‚   โ”œโ”€โ”€ council.py           5-specialist PANTHEON council with institution lenses
โ”‚   โ”‚   โ””โ”€โ”€ personas.py          10 seed citizens with rich backstory + traits
โ”‚   โ”œโ”€โ”€ memory/
โ”‚   โ”‚   โ”œโ”€โ”€ stream.py            Episodic memory stream (relevance ร— recency ร— importance)
โ”‚   โ”‚   โ”œโ”€โ”€ causal_graph.py      NetworkX temporal causal graph (crisis โ†’ decision chain)
โ”‚   โ”‚   โ”œโ”€โ”€ tcmf.py               Temporal-Causal Memory Fusion retriever
โ”‚   โ”‚   โ””โ”€โ”€ vectorstore.py       In-process embedding store (no external DB)
โ”‚   โ””โ”€โ”€ llm/
โ”‚       โ””โ”€โ”€ router.py            3-tier router: Ollama โ†’ Gemini โ†’ Claude
โ”‚
โ”œโ”€โ”€ web/                        React 18 + Vite + TypeScript frontend
โ”‚   โ””โ”€โ”€ src/
โ”‚       โ”œโ”€โ”€ App.tsx              Layout, speed slider, spend counter, tension meter
โ”‚       โ”œโ”€โ”€ city/
โ”‚       โ”‚   โ”œโ”€โ”€ CityStage3D.tsx  Three.js 3D city - orbit camera, bloom, PCF shadows (primary)
โ”‚       โ”‚   โ”œโ”€โ”€ CityStage.tsx    PixiJS isometric city (kept as fallback)
โ”‚       โ”‚   โ””โ”€โ”€ iso.ts           Isometric math, palettes
โ”‚       โ”œโ”€โ”€ panels/
โ”‚       โ”‚   โ”œโ”€โ”€ Inspector.tsx         Citizen mind viewer (memory, relationships, backstory, fear sparkline)
โ”‚       โ”‚   โ”œโ”€โ”€ CouncilChamber.tsx    Live debate UI, institution-coloured debate archive
โ”‚       โ”‚   โ”œโ”€โ”€ EventFeed.tsx         City event log
โ”‚       โ”‚   โ”œโ”€โ”€ RelationshipGraph.tsx Force-directed affinity graph with faction rings
โ”‚       โ”‚   โ”œโ”€โ”€ Timeline.tsx          Story Rewind - scrubbable causal event spine
โ”‚       โ”‚   โ”œโ”€โ”€ StatsPanel.tsx        Fear histogram, council scorecards, session export
โ”‚       โ”‚   โ””โ”€โ”€ Chronicle.tsx         LLM-generated newspaper-style city dispatch
โ”‚       โ”œโ”€โ”€ components/
โ”‚       โ”‚   โ””โ”€โ”€ Onboarding.tsx        5-step dismissible first-run tour
โ”‚       โ””โ”€โ”€ ws/
โ”‚           โ””โ”€โ”€ store.ts               Zustand store + WebSocket client + health poll
โ”‚
โ””โ”€โ”€ ml/                         Fine-tuning + MLOps
    โ”œโ”€โ”€ train_lora.ipynb         Unsloth LoRA fine-tune on Qwen2.5 3B โ†’ GGUF โ†’ Ollama
    โ”œโ”€โ”€ dataset/                 Synthetic council-voice dataset generator
    โ”œโ”€โ”€ evals/                   Persona-consistency + debate-quality eval harness
    โ””โ”€โ”€ mlflow/                  Local MLflow tracking store

Quick Start

Prerequisites

  • Python 3.12+, Node 18+
  • Ollama running as a background service
  • Models pulled: ollama pull qwen2.5:3b-instruct && ollama pull nomic-embed-text

Setup

# Python environment
python -m venv .venv
.venv\Scripts\activate          # Windows PowerShell
pip install -r api/requirements.txt

# Frontend
cd web && npm install && cd ..

# Environment (optional - free mode runs without any keys)
# Create a .env file in the project root:
#   GEMINI_API_KEY=...            (optional, Tier 1)
#   ANTHROPIC_API_KEY=...         (optional, Tier 2)
#   PREMIUM_MODE=false            (set true for Claude council verdicts)
#   OLLAMA_COUNCIL_MODEL=...      (optional, fine-tuned model name once exported)

Run (two terminals, both in the project root)

Terminal 1 - Backend:

$env:PYTHONIOENCODING="utf-8"
.venv\Scripts\python -m uvicorn api.main:app --reload --port 8000

Terminal 2 - Frontend:

cd web; npm run dev

Open http://localhost:5173 in your browser.

Run tests

.venv\Scripts\python -m pytest api/tests/ -q
# 61 tests, all pass

Demo Walkthrough

Pantheon Council verdicts in the Story Rewind during a live pandemic

  1. Wait a few ticks for citizens to start moving and talking.
  2. Click any citizen โ†’ Inspector panel shows their mind, memories, backstory, and fear history.
  3. Scroll the right sidebar to โš– PANTHEON COUNCIL.
  4. Click ๐Ÿฆ  Pandemic Outbreak preset (or use the Scenario Launcher) โ†’ inject the crisis.
  5. Watch the 5-specialist debate stream live. The Synthesizer issues a VERDICT.
  6. Observe:
    • Citizens glow red with fear; buildings dim and show a crisis pulse when closed.
    • The city feed and Chronicle dispatch narrate what's happening.
    • The Story Rewind panel builds a scrubbable causal chain.
    • Factions may form or fracture as relationships shift under pressure.
  7. Click โœ“ resolve on a crisis badge to end it, or let a verdict partially reopen locations.
  8. Use the speed slider to fast-forward time; watch the TENSION meter if you leave fear to rise on its own - an emergent crisis may fire without you touching anything.

Fine-Tuned Council Model

ml/train_lora.ipynb fine-tunes Qwen2.5 3B on a synthetic council-voice dataset (Unsloth QLoRA, free Colab T4) and exports a GGUF. The routing code in api/agents/council.py is already wired to use it for the four non-verdict debate roles (Synthesizer stays on Claude/Gemini - binding verdicts benefit from the stronger model).

To activate:

ollama create civos-council -f ml/Modelfile

Then set OLLAMA_COUNCIL_MODEL=civos-council in .env and restart the API. A purple ๐Ÿง  pill appears in the header once active.


API Reference

Method Path Description
GET /health Server status, version, spend counter, tick interval, active brains
GET /agent/{id} Citizen detail: memories, relationships, backstory
WS /ws Live world snapshots + debate turn stream
GET /llm/ping?tier=0 Smoke-test a specific LLM tier
POST /crisis Inject a crisis (triggers council debate)
GET /crises All registry crises (template key, resolved, emergent flags)
GET /debates/{id} Full debate transcript
GET /events/templates All crisis presets
GET /timeline?k=60 Causal event history, newest-first
POST /speed Set tick interval (0.1โ€“5.0 seconds)
POST /crisis/{key}/resolve Resolve an active crisis by template key
POST /crisis/id/{id}/resolve Resolve any crisis (including custom ones) by registry ID
GET /graph Social graph: nodes + weighted affinity edges
GET /stats Fear histogram, memory counts, session counters
GET /track_record Per-council debates, verdicts, effectiveness score
GET /chronicle LLM-generated newspaper-style city dispatch (cached ~75s)
GET /export Full session JSON snapshot (citizens, events, crises, causal graph)

Cost Breakdown

Component Cost
All citizen AI (conversations, reflections, embeddings) $0 (Ollama local)
Council Historian / Strategist / Skeptic / Predictor $0 (Gemini free tier, or fine-tuned local model)
Council Synthesizer - PREMIUM_MODE=true only ~$0.002 / debate
Full demo (multiple crises across all 5 councils) ~$0.05โ€“0.30
LoRA fine-tuning (Colab T4) $0
Total project spend < $5

Four Required Pillars

Pillar CivilizationOS delivery
Multi-agent system + domain problem 10 citizen-agents + 5 institutional councils ร— 5 specialists = 35 agents governing a simulated society
RAG (novel retrieval) Temporal-Causal Memory Fusion - episodic memory streams fused with a society-wide causal event graph
Fine-tuned model + MLOps LoRA fine-tune on Qwen2.5 3B (Unsloth, free Colab T4), MLflow run tracking, persona-consistency + debate-quality eval harness
Full-stack + Claude API React + Three.js 3D city โ†” FastAPI/WebSocket backend; Claude powers the council Synthesizer verdict in premium mode

Project History

Full phase-by-phase build record (0 through 13), design decisions, and plan-vs-reality notes live in MASTER_BUILD_LOG.md.

Deliberately out of scope for this build:

  • Vercel deployment - the frontend is deploy-ready (cd web && vercel), but the backend depends on a local Ollama instance, so a public deploy needs either a tunnel or a self-hosted API. Deferred by explicit choice, not left unfinished.
  • Demo video recording - no recording tooling in-repo.

Contributing

See CONTRIBUTING.md. The short version: api/tests/ stays fully offline (no live Ollama/Gemini/Claude calls - router tests exercise tier-selection logic only), and PREMIUM_MODE must stay false by default so the app runs at $0.

License

MIT.

About

Multi-agent AI society simulation: 35 autonomous agents, novel TCMF causal RAG, LoRA fine-tuning, 3-tier LLM routing. Built for under $5.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages