fugee / README.md
helmo's picture
List HF username @helmo (solo team)
c668df0 verified
|
Raw
History Blame Contribute Delete
9.93 kB

A newer version of the Gradio SDK is available: 6.20.0

Upgrade
metadata
title: Fugee
emoji: 🏠
colorFrom: green
colorTo: yellow
sdk: gradio
sdk_version: 6.15.2
app_file: app/app.py
pinned: false
license: mit
short_description: Agentic AI guidance for displaced people, on a small LLM
tags:
  - track:backyard
  - sponsor:openai
  - sponsor:modal
  - achievement:offbrand
  - achievement:llama

🏠 Fugee

Safe guidance for people on the move.

An agentic AI assistant for displaced people, asylum seekers, and refugees β€” powered by a small LLM, the LFM2.5 8B-parameter model.

πŸŽ₯ Watch the demo Β· πŸ“£ Launch post Β· πŸ’» GitHub

πŸ‘€ Team (solo): @helmo


What it is

Fugee conducts a calm, structured, multilingual interview, reasons about the person's situation against international refugee law (the 1951 Refugee Convention and the 1969 AU Convention), recommends realistic destination countries, and generates a personalised documentation package they can download and edit.

It is a single-process Gradio web app backed by a pure-Python agent loop (agent/loop.py, ported from pi-agent-core's patterns) and the lfm2.5:8b model served by Ollama. No Node.js, no microservices, no external database.

This Space runs the Gradio UI on free CPU and calls the LLM (lfm2.5:8b) and embeddings (nomic-embed-text) on a GPU Ollama endpoint hosted on Modal β€” so the same code and the same small model run unchanged, just on rented GPU. See deploy/DEPLOY.md.

The design point: a genuinely useful agentic product running on a small model. The interview is fully deterministic (fixed questions and controls, hand-translated into 10 languages) and the LLM is used only where it adds real intelligence β€” the legal assessment, the document drafting, and the spoken-back review summary.

The five phases

  1. Intake β€” language selection + a calm welcome.
  2. Interview β€” a fixed, deterministic question flow (current/origin country, what happened, persecution grounds, danger, documents, languages, goals).
  3. Assessment β€” the agent reasons openly about the case: classifies it (refugee / broader protection / statelessness / economic), names the Convention ground, gauges risk, and ranks destinations. Grounded in curated country data and the UNHCR Handbook & Guidelines (RAG) β€” not the open web.
  4. Recommendations β€” 2–3 country cards with real UNHCR/processing data and a step-by-step roadmap. Economic (non-protection) cases get honest work-route guidance instead of a doomed asylum claim.
  5. Documents β€” an LLM-drafted, editable Word (.docx) + PDF package, branded and laid out with bundled fonts (fully offline).

Requirements

  • Python β‰₯ 3.10
  • Ollama running somewhere you can reach (local or LAN), with:
    • lfm2.5:8b β€” the tool-calling instruct model the app uses, and
    • nomic-embed-text (used to build the UNHCR-guidelines search index).
  • A few hundred MB of disk for the Python deps and the (regenerable) RAG index.

No Node.js / npm anywhere β€” Fugee is pure Python.


Quick start

# 1. Clone and enter the repo
cd fugee

# 2. Create a virtualenv and install deps  (uv recommended; plain venv also fine)
uv venv && source .venv/bin/activate          # or: python -m venv .venv && source .venv/bin/activate
uv pip install -r requirements.txt            # or: pip install -r requirements.txt

# 3. Configure the model + host
cp .env.example .env
#   then edit .env:  set OLLAMA_HOST and MODEL_ID to what your Ollama actually has

# 4. Pull the models on your Ollama host (skip any you already have)
ollama pull lfm2.5:8b          # or your chosen ≀32B instruct model
ollama pull nomic-embed-text   # embeddings for the guidelines RAG index

# 5. Build the UNHCR-guidelines search index (one-time; regenerable, gitignored)
python data/scripts/build_guidelines_index.py

# 6. Run the app
python app/app.py

Open http://localhost:7860 in a browser. (The server binds 0.0.0.0:7860, so it's reachable from other machines on your network too.)

Configuration (.env)

Read at startup by app/config.py (no python-dotenv dependency):

Variable Meaning Example
OLLAMA_HOST Base URL of the Ollama server (local, LAN, or Modal endpoint) http://127.0.0.1:11434
MODEL_ID The single ≀32B tool-calling instruct model for the whole app lfm2.5:8b
MODEL_PROVIDER ollama (default) or a litellm provider name ollama
NUM_CTX Ollama context window β€” keep large; the small default truncates the assessment prompt 16384
MODAL_KEY / MODAL_SECRET Proxy-auth headers when OLLAMA_HOST is a protected Modal endpoint (hosted demo only) β€”

One model, no fallback. The hackathon build deliberately uses a single small model end to end. web_search is disabled β€” the assessment is grounded only in sources we control (curated country data + UNHCR guidelines), so no Tavily key is required.


Live demo: Hugging Face Space + Modal

The deployed demo splits into two pieces so it runs free and fast without changing the app or the model:

HF Space (free CPU, Gradio)            Modal (GPU, Ollama)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  HTTPS   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ app/app.py + curated data β”‚ ───────▢ β”‚ ollama serve                 β”‚
β”‚ + guidelines RAG (cosine) β”‚  proxy   β”‚   β€’ lfm2.5:8b   (assessment) β”‚
β”‚ OLLAMA_HOST β†’ Modal URL   β”‚  auth    β”‚   β€’ nomic-embed-text  (RAG)  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The Space sets OLLAMA_HOST to the Modal endpoint and sends the proxy-auth headers (agent/ollama_auth.py); everything else is identical to local. Full, copy-pasteable steps β€” create the Space, deploy Modal, set secrets, upload the RAG index β€” are in deploy/DEPLOY.md.


Project layout

fugee/
β”œβ”€β”€ agent/                  # Pure-Python agent loop + tools
β”‚   β”œβ”€β”€ loop.py             #   while-loop, typed events, hooks, steering (ported from pi)
β”‚   β”œβ”€β”€ drafting.py         #   LLM document drafting
β”‚   └── tools/              #   country_lookup, asylum_stats, guideline_search, doc_generator
β”œβ”€β”€ app/                    # Gradio application
β”‚   β”œβ”€β”€ app.py              #   entrypoint β€” `python app/app.py`
β”‚   β”œβ”€β”€ phases/             #   intake / interview / assessment / recommendations / documents
β”‚   β”œβ”€β”€ interview_script.py #   fixed questions + 10-language translations
β”‚   β”œβ”€β”€ state/session.py    #   forward-only interview state machine
β”‚   └── prompts/            #   system / assessment prompts (Markdown)
β”œβ”€β”€ data/scripts/           # UNHCR data pipeline + guidelines RAG index builder
β”œβ”€β”€ specs/                  # PLAN.md, ARCHITECTURE.md, ISSUES.md, curated country data
β”‚   └── data/countries.json #   authoritative country reference (signatories + non-signatories)
β”œβ”€β”€ tests/                  # unit / integration (no model) + e2e (real model)
β”œβ”€β”€ DESIGN.md               # design tokens (authoritative)
β”œβ”€β”€ mockup.html             # visual reference for every phase
β”œβ”€β”€ CLAUDE.md               # agent working rules for this repo
└── requirements.txt

Running the tests

# Fast: pure logic + phase integration (no model needed)
pytest tests/unit tests/integration -v

# End-to-end with a real model (needs Ollama + your MODEL_ID)
pytest tests/e2e -v

Testing philosophy: unit tests stub only at the network boundary; E2E uses real model calls. Tools never fabricate data β€” a failed lookup surfaces an error rather than inventing one.


Languages

English Β· FranΓ§ais Β· EspaΓ±ol Β· PortuguΓͺs Β· Ψ§Ω„ΨΉΨ±Ψ¨ΩŠΨ© Β· ΰ€Ήΰ€Ώΰ€¨ΰ₯ΰ€¦ΰ₯€ Β· δΈ­ζ–‡ Β· ζ—₯本θͺž Β· ν•œκ΅­μ–΄ Β· Русский

The interview questions, options, and chrome are hand-translated for all ten.


For contributors / agents

  • CLAUDE.md β€” the single source of truth for how to work in this repo (critical rules, design authority, sign-off gates). Read it first.
  • DESIGN.md + mockup.html β€” authoritative for every visual decision.
  • specs/ISSUES.md β€” hard-won gotchas and their real fixes (e.g. the Gradio CheckboxGroup reveal bug). Read before touching the interview UI or the assessment/recommendation logic β€” it will save you a long debugging loop.
  • specs/ARCHITECTURE.md / specs/PLAN.md β€” system design and phased plan.

Status & disclaimer

Built for the Hugging Face Build Small Hackathon (June 2026). Quality bar: demo-ready, real-user-usable.

Fugee provides guidance, not legal advice. It helps a person understand and prepare; it is not a substitute for a qualified immigration lawyer or an accredited adviser. It is deliberately honest about what does and does not qualify for protection β€” wrong output is worse than no output.