Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/JasonHonKL/spy-search/llms.txt

Use this file to discover all available pages before exploring further.

All runtime behaviour in Spy Search is controlled by a single file: config.json in the project root. The file is read at startup by src/api/core/config.py, and it is also hot-reloaded in Docker — meaning you can update the file and restart the container without rebuilding the image.
Never commit config.json or your .env file to version control. Both files may contain API keys and secrets. Add them to .gitignore immediately.

Field Reference

provider
string
required
The LLM provider to use. Must be one of:
ValueProvider
openai or gptOpenAI (or any OpenAI-compatible API, e.g. OpenRouter)
ollamaOllama (local)
deepseekDeepSeek
google or geminiGoogle Gemini
xAI or gorkxAI / Grok
The value is matched inside Factory.get_model() in src/factory/factory.py.
model
string
required
The model identifier string passed directly to the provider’s API. The accepted values depend on the provider you have selected.Examples: gpt-4o, deepseek-chat, gemini-2.0-flash, grok-beta, qwen3:8b, meta-llama/llama-3.3-70b-instruct
agents
string[]
required
Array of agent IDs to activate for each query. The Planner agent is always instantiated internally and does not need to be listed here.Available values:
ValueDescription
reporterSynthesizes a long-form report from gathered data
searcherPerforms live web search via DuckDuckGo
local-retrievalQueries a local ChromaDB vector store for RAG
At minimum, include "reporter" — the UI will auto-add it if missing.
db
string
default:"./local_files/test"
Path to the local file directory used by the local-retrieval agent for ChromaDB-backed RAG. Only required when local-retrieval is in agents.The path is relative to the project root.
base_url
string
Override the API base URL. Leave empty (or omit the key) to use each provider’s default endpoint.Useful for:
  • OpenRouterhttps://openrouter.ai/api/v1
  • Ollamahttp://localhost:11434 (or http://host.docker.internal:11434 in Docker)
  • Azure OpenAI — your deployment endpoint
  • Custom proxies — any OpenAI-compatible proxy
language
string
default:"en"
BCP-47 language code that instructs the reporter agent to produce output in the specified language. Examples: en, zh, fr, de, ja.

Example Configurations

Use OpenAI’s API directly with gpt-4o:
config.json
{
    "provider": "openai",
    "model": "gpt-4o",
    "agents": ["searcher", "reporter"],
    "language": "en"
}
Set your key in .env:
.env
OPENAI_API_KEY=sk-...

How the File is Read

src/api/core/config.py exposes two helpers used throughout the application:
src/api/core/config.py
def read_config() -> Dict[str, Any]:
    config_file = "./config.json"
    if not os.path.exists(config_file):
        # Safe default when the file is missing
        return {
            "agents": [],
            "provider": "openai",
            "model": "deepseek-r1:1.5b"
        }
    try:
        with open(config_file, "r") as f:
            return json.load(f)
    except (json.JSONDecodeError, FileNotFoundError):
        return {
            "agents": [],
            "provider": "ollama",
            "model": "deepseek-r1:1.5b"
        }

def write_config(config: Dict[str, Any]) -> None:
    with open("./config.json", "w") as f:
        json.dump(config, f, indent=4)
Default fallbackread_config() has two fallback paths:
  • File missing: returns provider: "openai", model: "deepseek-r1:1.5b", empty agents.
  • File present but invalid JSON: returns provider: "ollama", model: "deepseek-r1:1.5b", empty agents.
In both cases no agents will be active until you create a valid config.json. The frontend Settings page reads the live config via GET /get_config and writes updates via the /agents_selection endpoint, so the file stays in sync with the UI at all times.

Build docs developers (and LLMs) love