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.

Spy Search supports 5 LLM providers through the Factory.get_model() abstraction in src/factory/factory.py. Every agent in the pipeline shares the same model instance, so you configure your provider once in config.json and all agents use it automatically.
src/factory/factory.py
def get_model(provider: str, model: str) -> Model:
    if provider == "deepseek":
        return Deepseek(model)
    if provider == "google" or provider == "gemini":
        return Gemini(model)
    if provider == "ollama":
        return Ollama(model)
    if provider == "xAI" or provider == "gork":
        return Gork(model)
    if provider == "openai" or provider == "gpt":
        return OpenAI(model)
An Anthropic module (src/model/anthropic.py) exists in the codebase but is not yet wired into Factory.get_model(). It is not currently usable as a provider.

Provider Setup

Provider string: openai or gptEnvironment variable: OPENAI_API_KEYThe OpenAI model class uses the official openai Python SDK. Providing a base_url in config.json redirects all requests to that endpoint instead of the default api.openai.com — making this the entry-point for OpenRouter, Azure OpenAI, and other OpenAI-compatible proxies.
config.json
{
    "provider": "openai",
    "model": "gpt-4o",
    "agents": ["searcher", "reporter"],
    "language": "en"
}
.env
OPENAI_API_KEY=sk-...
Popular model values for OpenAI: gpt-4o, gpt-4o-mini, gpt-4-turbo, o1-mini.

Environment Variables

All API keys are loaded from a .env file in the project root via python-dotenv. Create the file before starting the server:
.env
# OpenAI / OpenRouter
OPENAI_API_KEY=sk-...

# DeepSeek
DEEPSEEK_API=sk-...

# Google Gemini
GEMINI_API=AIza...

# xAI / Grok
XAI_API_KEY=xai-...
Add .env to your .gitignore. Never commit API keys to version control.
Each model class calls load_dotenv(override=True) in its constructor, so the key is always sourced from the .env file at the time the model is instantiated, not at import time.

Using OpenRouter

OpenRouter provides a unified API that proxies dozens of hosted models — including Llama, Mistral, Claude, and many others — behind a single OpenAI-compatible endpoint. To use it, set provider to openai and point base_url at OpenRouter:
config.json
{
    "provider": "openai",
    "model": "meta-llama/llama-3.3-70b-instruct",
    "base_url": "https://openrouter.ai/api/v1",
    "agents": ["searcher", "reporter"],
    "language": "en"
}
.env
OPENAI_API_KEY=sk-or-...
The model string follows OpenRouter’s author/model-name convention. Browse available models at openrouter.ai/models.
This is the default configuration shipped in config.example.json, making OpenRouter the recommended starting point for new users who want access to many models without managing multiple API accounts.

Build docs developers (and LLMs) love