borderless / README.md
spagestic's picture
switched to qwen
71a7158
|
Raw
History Blame Contribute Delete
9.05 kB
---
title: Borderless
emoji: 🌍
colorFrom: yellow
colorTo: purple
sdk: gradio
sdk_version: 6.16.0
app_file: app.py
pinned: false
license: apache-2.0
hardware: cpu
short_description: Agentic immigration research for global movers
tags:
- agents
- gradio
- immigration
- travel
- research
- tool-use
- qwen
- langgraph
- maplibre
- geospatial
models:
- Qwen/Qwen3.6-27B
datasets: []
hf_oauth: true
hf_oauth_scopes:
- inference-api
hf_oauth_expiration_minutes: 480 # 8 hours
disable_embedding: false
startup_duration_timeout: 10m
---
# Borderless
**An agentic immigration research tool β€” describe your background in plain English, explore where you could go.**
Live demo: **[build-small-hackathon/borderless](https://huggingface.co/spaces/build-small-hackathon/borderless)**
Built for the [Build Small Hackathon](https://huggingface.co/build-small-hackathon) β€” small models (≀32B), big adventure.
## What it does
Immigration research is fragmented across government sites, forums, and spreadsheets. Borderless puts it in one conversational flow:
1. **Describe yourself** β€” citizenship, education, work history, budget, timeline, and goals via a guided intake form or free-form chat.
2. **Get a research plan** β€” the agent parses your profile, picks realistic destination countries, and breaks the work into focused to-dos.
3. **Watch parallel research** β€” subagents investigate each to-do at the same time, searching official sources and scraping government pages.
4. **Explore on a 3D globe** β€” recommended countries appear on an interactive MapLibre globe with pathway labels.
5. **Read a consolidated answer** β€” visa pathways, documents, timelines, costs, risks, and cited official sources in one structured report.
No forms to decode. No keyword guessing. Just a research session that meets you where you are.
## How it works
Borderless uses a **[LangGraph](https://docs.langchain.com/oss/python/langgraph/overview)** workflow powered by **[Qwen/Qwen3.6-27B](https://huggingface.co/Qwen/Qwen3.6-27B)** via the Hugging Face Inference API:
```
User profile β†’ Planner β†’ parallel Researchers (one per to-do) β†’ Consolidator β†’ final answer
```
| Stage | What happens |
|-------|----------------|
| **Planner** | Reads the profile, selects 3–4 destination countries, emits a research plan, and marks countries on the globe. |
| **Researchers** | Run in parallel via LangGraph `Send`. Each subagent searches official immigration sources, scrapes government pages, and writes a findings report for its to-do. |
| **Consolidator** | Merges all findings into a single structured answer with pathways, documents, risks, timelines, and official source links. |
Progress streams live in the chat: thinking steps, the research plan, tool calls (with expandable arguments and results), per-to-do findings, globe updates, and the final answer.
### Research tools
| Tool | What it fetches |
|------|-----------------|
| `get_country_profile` | Country metadata and official immigration domain hints |
| `search_immigration_info` | Web search with source-quality labels for official immigration pages (Exa) |
| `scrape_web_page` | Markdown content from a specific official government or embassy URL (Firecrawl) |
| `crawl_web_site` | Multiple pages from an official immigration website section (Firecrawl) |
| `update_globe` | Marks, highlights, and flies to countries on the MapLibre globe |
Sign in with your Hugging Face account for inference, or set `HF_TOKEN` as a Space secret for server-side API access.
## Features
- **Guided intake** β€” form fields and demo personas turn a profile into a complete research prompt
- **LangGraph parallel research** β€” planner plus parallel subagents, not a single monolithic agent loop
- **Live streaming UI** β€” thinking, tool calls, findings, and the final answer appear as the workflow runs
- **Tool-driven 3D globe** β€” MapLibre GL globe with markers, pathway labels, and fly-to camera moves
- **Source quality** β€” search results flag likely official government and embassy sources
- **Structured recommendations** β€” shortlist, pathways, documents, risks, timelines, next steps, and official sources
- **Chat history** β€” sessions persist in the browser
## Example prompts
- *"I'm a software engineer from India with 8 years of experience and a master's degree. Where could I realistically relocate for skilled work within 12–18 months?"*
- *"I hold a Hong Kong passport and want to study in Europe on a modest budget. What are my visa options?"*
- *"Compare skilled worker pathways to Canada, Germany, and Ireland for a solo applicant with USD 20k savings."*
## Tech stack
- **[Gradio Server](https://gradio.app)** β€” custom HTML/JS UI, OAuth, and streaming API endpoints
- **[LangGraph](https://docs.langchain.com/oss/python/langgraph/overview)** β€” planner / parallel researcher / consolidator workflow
- **[Qwen3.6-27B](https://huggingface.co/Qwen/Qwen3.6-27B)** β€” planning and synthesis via Hugging Face Inference API (`huggingface_hub.InferenceClient`)
- **[MapLibre GL JS](https://maplibre.org/)** β€” interactive 3D globe
- **[Exa](https://exa.ai)** β€” neural web search for discovering immigration sources
- **[Firecrawl](https://firecrawl.dev)** β€” scrape and crawl official web pages
## Project structure
```
app.py # Gradio Server entry point and API routes
assets/
index.html # Custom UI shell
app.js # Intake form, chat, history, streaming client
gradio_api.js # Gradio SSE streaming helper
globe.js / globe.css # MapLibre globe rendering
server.css # App styling
ui/
server_api.py # Chat API adapter and intake helpers
globe_commands.py # Globe marker/highlight/fly-to state
country_coords.py # Country coordinate lookup
intake/ # Profile form, personas, prompt builders
agent/
graph/ # LangGraph workflow (planner, researchers, consolidator)
respond.py # Legacy single-agent loop (fallback mode)
tools.py # Tool dispatch
completion.py # Hugging Face Inference API client
streaming.py # Chunked answer streaming
tool_schemas/ # Function-calling schemas
apis/
exa.py # Exa web search
firecrawl.py # Firecrawl scrape/crawl
rest_countries.py # Country metadata (with static fallback)
country_profile.py # Country profile tool
data/
countries_fallback.yaml # Static country coordinates when REST Countries is unavailable
intake/ # Form choices and demo personas
```
## Hackathon fit
| Constraint | Borderless |
|------------|------------|
| Model ≀ 32B | Qwen3.6-27B (27B) |
| Gradio on HF Spaces | Yes β€” [live Space](https://huggingface.co/spaces/build-small-hackathon/borderless) |
| Agentic | LangGraph multi-agent research with visible tool traces |
| Sharing is Caring | JSONL tool traces can be sanitized and published β€” see `TRACE_SHARING.md` |
| Field Notes | See `FIELD_NOTES.md` |
**Track:** Backyard AI β€” immigration research is a real, specific problem faced by millions of people weighing where they can live, work, and study.
## Run locally
```bash
pip install -r requirements.txt
cp .env.example .env # then fill in API keys
python app.py
```
Set `HF_TOKEN` in `.env` (or sign in through OAuth on the Space). The default model is `Qwen/Qwen3.6-27B:featherless-ai` on the Hugging Face Inference API.
For web research tools, set API keys from [dashboard.exa.ai](https://dashboard.exa.ai/api-keys) and [firecrawl.dev](https://firecrawl.dev):
| Variable | Purpose |
|----------|---------|
| `HF_TOKEN` | Hugging Face Inference API access (Space secret and/or user OAuth) |
| `EXA_API_KEY` | `search_immigration_info` |
| `FIRECRAWL_API_KEY` | `scrape_web_page`, `crawl_web_site` |
| `BORDERLESS_MODEL_ID` | Model override (default `Qwen/Qwen3.6-27B:featherless-ai`) |
| `BORDERLESS_INFERENCE_MODE` | `hub` (default, InferenceClient) or `router` (OpenAI-compatible router) or `local` (MiniCPM on ZeroGPU) |
| `BORDERLESS_AGENT_MODE` | `graph` (default) or `legacy` for the single-agent loop |
| `BORDERLESS_TRACE_DIR` | JSONL trace output directory |
| `BORDERLESS_DISABLE_TRACE_LOGS` | Set to `1` to disable local trace logs |
On Hugging Face Spaces, add API keys as **Space secrets** (Settings β†’ Secrets). Without keys, web tools return a clear error and the agent continues with partial results.
### Startup logs (normal on Spaces)
| Log | Meaning |
|-----|---------|
| `GRADIO_HOT_RELOAD: ... Using 'demo'` | Harmless β€” Gradio found the app entrypoint. |
| `Invalid file descriptor: -1` in `BaseEventLoop.__del__` | Harmless asyncio cleanup noise during Gradio SSR hot reload. |
| `HF_TOKEN is set ... independently from the token you've just configured` | Informational β€” Space secret and OAuth login both provide tokens. |
## License
Apache-2.0 (model: [Qwen/Qwen3.6-27B](https://huggingface.co/Qwen/Qwen3.6-27B))