--- title: OpenResearcher emoji: 🏃 colorFrom: purple colorTo: green sdk: docker app_port: 7860 pinned: false --- OpenResearcher DeepSearch agent. Inference runs locally in this Space via ZeroGPU by default; a cloud OpenAI-compatible endpoint is used only as a backup if local inference fails. An "Inference Mode" switch in the sidebar (Auto / Local only / Cloud only) lets you override this per request. The agent also plans an explicit research goal (with a 1-5 vagueness rating) up front and stops as soon as that goal is met, instead of always running to the round limit. ## Configuration (Space secrets, all optional) | Secret | Description | |---|---| | `MODEL_NAME` | Local model to run via ZeroGPU. Defaults to `OpenResearcher/Nemotron-3-Nano-30B-A3B`. | | `OPENAI_BASE_URL` | Cloud backup, used only if local inference errors out. Base URL of an OpenAI-compatible API; `/chat/completions` is appended automatically. | | `OPENAI_MODEL` | Model name for the cloud backup. Defaults to `MODEL_NAME`. | | `OPENAI_API_KEY` | Bearer token for the cloud backup. | | `JINA_MCP_BASE_URL` | Self-hosted Jina MCP server. Used exclusively for web search (`search_web` tool) and as the primary scraping backend (`read_url` tool). Defaults to `https://leon4gr45-jina.hf.space`. Its own API key is configured on that server, so none is needed here. | | `MAX_CONTEXT_TOKENS` | Fallback input budget (approx. tokens), only used if the context length can't be auto-detected. Defaults to `100000`. | The ReAct loop's conversation history is kept under a per-model token budget automatically. That budget is auto-detected once per run: for the local model, straight from its loaded config (`max_position_embeddings` etc.); for the cloud backup, by querying `{OPENAI_BASE_URL}/models` and reading off whichever context-length field the server reports (e.g. vLLM's `max_model_len`, OpenRouter's `context_length` - the plain OpenAI API itself doesn't expose this, so falls back to `MAX_CONTEXT_TOKENS` there). In Auto mode, the tighter of the two detected limits is used, since either backend might end up serving the request. Older rounds get truncated (recent rounds stay verbatim) before each generation call, and again as an emergency retry if a "context length exceeded" error still slips through. Web search uses only Jina's `search_web` tool. (A self-hosted SearXNG instance was tried, but Hugging Face's abuse-detector auto-paused that Space over a process-name/cmdline match on "searxng" — not viable here.) Page fetching tries Jina's `read_url` first, then falls back to a direct HTTP fetch, then to Serper's scrape API if a key is provided in the UI. This Space requires ZeroGPU (or another GPU) hardware to run local model inference. Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference