{"id":50783339,"url":"https://github.com/60milesperhour/horizon-search","last_synced_at":"2026-06-12T05:03:51.085Z","repository":{"id":360157957,"uuid":"1248892140","full_name":"60MilesPerHour/Horizon-Search","owner":"60MilesPerHour","description":"Self-hosted privacy-first search engine — custom SearXNG theme + opt-in AI side panel with BYO Ollama and agentic search loop.","archived":false,"fork":false,"pushed_at":"2026-05-25T07:59:49.000Z","size":678,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-25T09:28:19.736Z","etag":null,"topics":["ai-search","ollama","privacy","search-engine","searxng","self-hosted"],"latest_commit_sha":null,"homepage":"https://horizonsearch.tech","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/60MilesPerHour.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-25T06:37:10.000Z","updated_at":"2026-05-25T07:59:52.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/60MilesPerHour/Horizon-Search","commit_stats":null,"previous_names":["60milesperhour/horizon-search"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/60MilesPerHour/Horizon-Search","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/60MilesPerHour%2FHorizon-Search","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/60MilesPerHour%2FHorizon-Search/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/60MilesPerHour%2FHorizon-Search/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/60MilesPerHour%2FHorizon-Search/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/60MilesPerHour","download_url":"https://codeload.github.com/60MilesPerHour/Horizon-Search/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/60MilesPerHour%2FHorizon-Search/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34229661,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-search","ollama","privacy","search-engine","searxng","self-hosted"],"created_at":"2026-06-12T05:03:50.266Z","updated_at":"2026-06-12T05:03:51.077Z","avatar_url":"https://github.com/60MilesPerHour.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Horizon Search\n\nA self-hosted, privacy-first search engine — a custom theme + AI side panel built on top of [SearXNG](https://github.com/searxng/searxng).\n\nSibling project to [**Horizon**](https://github.com/60MilesPerHour/Horizon), the multi-provider AI chat client. Shared brand DNA (OLED true-black, Pacifico wordmark, sunset-orange accent). Horizon is where you talk to your models (Ollama + Claude + OpenAI + Gemini); Horizon Search is the **Ollama-only** sibling that helps you find things — see [AI side panel](#ai-side-panel-optional) for why cloud providers stay on the chat side.\n\n- OLED true-black UI, Pacifico wordmark, sunset-orange accent\n- Card mosaic for results, news, and videos\n- Maps tab powered by Foursquare + OpenStreetMap (Leaflet)\n- Optional AI side panel that connects directly to your own Ollama server — no inference data ever touches the Horizon backend\n- Primary + backup Ollama URL with automatic failover (mirrors main Horizon)\n- Agentic loop: the AI can drive the search bar on your behalf (`goto_search`) or pull in extra context invisibly (`search`)\n\n## Quick start\n\nPrerequisites: Docker + Docker Compose.\n\n```bash\ngit clone https://github.com/60MilesPerHour/horizon-search.git\ncd horizon-search\n\n# 1. Copy the example configs\ncp searxng/settings.example.yml searxng/settings.yml\ncp .env.example .env\n\n# 2. Generate a fresh SearXNG secret_key\nopenssl rand -hex 32\n# paste the output into searxng/settings.yml at server.secret_key\n\n# 3. (Optional) Fill in Foursquare creds in .env for the Maps tab\n#    Get them at https://foursquare.com/developers/\n\n# 4. Bring it up\ndocker compose up -d\n```\n\nDefault port: `:8888`. Open `http://localhost:8888`.\n\n## AI side panel (optional)\n\nBring-your-own Ollama. Click `horizon` in the bottom bar → enable AI panel → enter your Ollama URL (optionally a backup URL) + pick a tool-capable model → save. The pill in the search row turns orange when the panel is open.\n\n**Backup URL / failover:** if you run an Ollama box at home and another at the office, set the second as the backup. When the primary is unreachable (DNS, network, host down) the panel transparently retries the next chat request against the backup and surfaces a one-line `primary unreachable — using backup` indicator. The model dropdown is still populated from the primary, so install the same model on both hosts.\n\n\u003e **Ollama-only by design.** No Claude / OpenAI / Gemini adapters here, and that's deliberate. Cloud providers from a browser would either require proxying inference through the SearXNG container (which would break the \"no inference data ever touches the Horizon backend\" promise) or stashing raw API keys in `localStorage` (strictly worse than the OS keystore the main [Horizon](https://github.com/60MilesPerHour/Horizon) app uses). Ollama dodges both because the call is loopback / LAN, never third-party. If you want a chat app on top of Claude / OpenAI / Gemini, that's what main Horizon is for.\n\n**Model requirements:** only tool-capable models are listed (capability filtered via Ollama's `/api/show`). Tested on:\n- `llama3.1` / `llama3.2` / `llama3.3`\n- `qwen2.5` / `qwen3`\n- `mistral-nemo`\n- `command-r`\n\n**CORS gotcha:** Ollama refuses cross-origin browser requests by default. On the Ollama host, set:\n\n```bash\nOLLAMA_ORIGINS=*    # or your Horizon domain\n```\n\n…then restart Ollama. The settings modal also reminds you of this inline.\n\n**What the panel can do:**\n- Read every visible result card on the page as context (title, source, snippet, date)\n- Cite with clickable `[N]` chips that scroll to + flash the matching card\n- Stream answers with markdown (bold, lists, headers, links)\n- Call `goto_search(query, category)` — types the query into the main search bar and navigates, restoring the conversation on the new page via `sessionStorage`\n- Call `search(query, category)` — fetches results invisibly via `/search?format=json`, appends them to the citation map with continuation numbering\n- Bounded at 3 tool hops per turn to prevent runaway loops\n\n## What's in here\n\n```\ntemplates/         Jinja templates that override SearXNG's simple theme\n  base.html        Globals: fonts, palette, settings modal\n  index.html       Landing page\n  results.html     All result tabs + AI side panel\nsearxng/           Files mounted into /etc/searxng inside the container\n  settings.example.yml   Engine selection + features (copy to settings.yml)\n  horizon-logo.png       Sunset logo\n  favicon.svg\n  sxng-ltr.min.css       Theme CSS overrides\n  limiter.toml           Rate-limit rules\ninfopage/en/       About + search-syntax pages\ndocker-compose.yml SearXNG + Valkey\n```\n\n## Customising\n\n- **Accent color:** change `--accent` (and friends) in `templates/base.html` at the top of the `\u003cstyle\u003e` block. Currently `#ff7200`.\n- **Logo:** replace `searxng/horizon-logo.png` (1024×1024 recommended) and re-deploy.\n- **Engines:** edit `searxng/settings.yml` — see [SearXNG docs](https://docs.searxng.org/admin/settings/index.html).\n- **AI tools:** the agentic loop lives at the bottom of `templates/results.html` (inside the last `\u003cscript\u003e` block). The tool definitions are in the `TOOLS` array; the system prompt is `SYSTEM_PROMPT`.\n\n## Re-deploying after template edits\n\nTemplates are bind-mounted read-only, so a restart is enough:\n\n```bash\ndocker restart searxng\n```\n\nFor volume / compose changes:\n\n```bash\ndocker compose up -d --force-recreate searxng\n```\n\n## Notes\n\n- The AI panel is entirely opt-in; the rest of the search engine works without it.\n- Image thumbnails for Bing News bypass SearXNG's `image_proxy` (the server IP is blocked) — the browser fetches them directly with `referrerpolicy=\"no-referrer\"`.\n- The Maps tab uses Foursquare Places for venue data and OpenStreetMap/Nominatim for geocoding. Both calls go through small backend proxies (Foursquare key never reaches the browser).\n\n## Companion project\n\nIf you want to *talk to* the same Ollama server (or to Claude / OpenAI / Gemini) outside the browser, check out [**Horizon**](https://github.com/60MilesPerHour/Horizon) — the multi-provider Flutter chat client this project is branded after. Same author, same OLED + Pacifico look, same Ollama-first ethos.\n\n## License\n\nMIT — see `LICENSE`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F60milesperhour%2Fhorizon-search","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F60milesperhour%2Fhorizon-search","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F60milesperhour%2Fhorizon-search/lists"}