GeoGuess_Arena / README.md
Joffrey Thomas
Mistral Large 4: reasoning effort high, and parse its thinking chunks
246fa4e
|
Raw History Blame Contribute Delete
4.74 kB
metadata
title: GeoGuessr Arena
emoji: 🌍
colorFrom: indigo
colorTo: yellow
sdk: docker
app_port: 7860
hf_oauth: true
hf_oauth_scopes:
  - inference-api
pinned: true
models:
  - mistralai/Mistral-Large-4.0-1T05-A52B

GeoGuessr Arena: you vs the machines

Everyone is dropped at the same random Street View location with the same clock. You explore with a draggable Street View. The AI agents explore with tools:

tool what it does
look / pan / zoom change heading, pitch or field of view and get a new 640×640 view
move walk forward or backward along the current heading, snapping to the nearest Google panorama
view_map a roadmap of any coordinates the agent picks, so it can check a hypothesis. It never shows where the agent actually is.
place_pin / reverse_geocode drop a candidate pin, or look up which place a coordinate falls in
submit_guess lock in a final answer

While the round is live you only see a blind feed of what each rival is doing ("walked 23 m", "zoomed in"), never what they see or think. At the reveal you get the guesses map, every agent's walked path, and a full step-by-step replay of its views, reasoning and tool calls.

Space secrets

secret needed for
GOOGLE_MAPS_API_KEY server side: Street View Static + metadata, Static Maps, Geocoding
GOOGLE_MAPS_BROWSER_KEY Maps JavaScript API in the browser. Restrict it by HTTP referrer. Falls back to the server key.
HF_TOKEN trace uploads (needs write access to the traces dataset)
MISTRAL_API_KEY Mistral models
HF_TRACES_REPO optional. Private dataset for traces (default Jofthomas/geoguessr-arena-traces)

Open-weight models (every key="hf_login" entry in MODELS) run through the HF router on the player's own Hugging Face account: they click "Sign in with Hugging Face" and the Space's OAuth token (scope inference-api) is used for their games, so usage is billed to them.

Proprietary models (key="byok") run on the player's own key. Those keys are held in memory for the duration of the game only. They are never logged and never written to traces.

Optional tuning variables: ROUNDS_PER_GAME, ROUND_SECONDS, AGENT_MAX_STEPS, AGENT_MAX_GEOCODES, AGENT_WRAPUP_SECONDS, GAMES_PER_IP_PER_HOUR.

Changing the model list

Every opponent is one entry in the MODELS dict in arena/config.py. The lobby, the live feed, the reveal and the traces all read from it, so adding, removing or editing an entry is the only change needed.

field meaning
label, color name and colour shown in the UI
provider "openai_compat" (any OpenAI-style /chat/completions with tools), "openai_responses" (OpenAI's Responses API, required for their reasoning models with tools) or "anthropic"
base_url endpoint for openai_compat, e.g. HF_ROUTER_BASE_URL
model_id model name sent to the provider (HF router: the Hub repo id)
key "hf_login" (player's HF account), "byok" (player pastes a key, set key_hint), or the name of an env var holding a server key
avatar profile picture, e.g. /static/avatars/qwen.webp
default_on pre-selected in the lobby
catalog BYOK only: "openai", "anthropic" or "gemini". Once a key is pasted, the lobby lists that provider's models in a dropdown; model_id is the default
reasoning_effort openai_responses (e.g. "medium") or openai_compat providers that accept it, e.g. Mistral Large 4 ("high" / "none")
max_images optional cap on images per request for providers that limit it (also learned automatically from a 413)
token_param, extra_body optional provider quirks for openai_compat

Model keys (the dict keys) end up in DOM ids: use letters, digits, - and _ only.

Models must accept images and support tool calling. For the HF router, check https://router.huggingface.co/v1/models: input_modalities must include image and at least one live provider must have supports_tools: true.

Traces

Each revealed round is written to data/{date}/{game_id}/round_NN.jsonl in the private dataset, with one row per participant: the guess, distance, score, rank, token usage, walked path, pins and the full provider-neutral message trace. Street View pixels are not uploaded (Google Maps ToS). Each image is stored as its request parameters instead (pano, heading, pitch, fov / map center + zoom), so you can re-fetch it with your own key.

Local dev

uv venv -p 3.12 .venv && uv pip install -r requirements.txt
cp .env.example .env   # fill in keys
.venv/bin/uvicorn arena.main:app --reload --port 7860