Environment Variables That Control Research Behavior and LLM Configuration in local-deep-research
The local-deep-research application reads all configuration from environment variables prefixed with LDR_, converting dot-notation settings to uppercase underscore format (e.g., app.host becomes LDR_APP_HOST) to control API binding, search parameters, rate limiting, and LLM provider selection without code changes.
All runtime behavior in the learningcircuit/local-deep-research repository is externally configurable through a unified environment variable system. These variables control the Flask web API bootstrap process, research workflow features like search timeouts and result limits, and detailed LLM client parameters including provider credentials, model selection, and inference tuning. Understanding the LDR_ prefix convention and the type coercion system allows operators to deploy the application across development, CI, and production environments with zero configuration file edits.
The LDR_ Prefix and Dot-Notation Conversion
Every environment variable recognized by the system must begin with the LDR_ prefix. The application automatically transforms dot-notation configuration keys into standard environment variable names by replacing periods with underscores and converting to uppercase.
In src/local_deep_research/settings/manager.py, the conversion logic is implemented as:
env_variable_name = f"LDR_{'_'.join(key.split('.')).upper()}"
This means a setting key like llm.temperature maps to LDR_LLM_TEMPERATURE, and app.port becomes LDR_APP_PORT. The SettingsManager class handles this resolution automatically, ensuring environment variables override database defaults and JSON configuration files.
Bootstrap and General Research Variables
Before the application establishes any database connection, it resolves bootstrap variables via SettingsManager.get_bootstrap_env_vars(). These control server binding, security policies, and feature toggles.
Server and Application Control
LDR_APP_HOST– Hostname the Flask API binds to (default:0.0.0.0)LDR_APP_PORT– TCP port for the API listener (default:8000)LDR_APP_DEBUG– Enables Flask debug mode (trueorfalse)LDR_APP_ALLOW_REGISTRATIONS– Controls whether new users may registerLDR_DATA_DIR– Filesystem path for cache storage and embeddings (e.g.,/var/ldr/data)LDR_BOOTSTRAP_ALLOW_UNENCRYPTED– Allows startup with an unencrypted database, primarily used in test suites
Provider and Feature Toggles
LDR_DISABLE_OLLAMA– Prevents loading the Ollama provider even if installedLDR_DISABLE_OPENAI– Prevents loading the OpenAI providerLDR_DISABLE_ANTHROPIC– Prevents loading the Anthropic providerLDR_USE_FALLBACK_LLM– Forces the fallback local LLM when remote providers failLDR_RATE_LIMITING_ENABLED– Activates the global request-rate limiterLDR_CI– Marks CI environment context, disabling interactive prompts (automatically set by CI pipelines)
Search Behavior Tuning
LDR_SEARCH_TIMEOUT– Maximum seconds allowed for a search request (e.g.,30)LDR_SEARCH_TOOL_MAX_RESULTS– Hard upper bound on search results returned (e.g.,10)
LLM Configuration Variables
All LLM-related variables use the LDR_LLM_ prefix and map directly to the LLMProvider class initialization parameters. These are processed by the type conversion system defined in UI_ELEMENT_TO_SETTING_TYPE (lines 54-61 of manager.py), which coerces string values to booleans, integers, floats, or JSON objects as appropriate.
Provider Selection and Model Parameters
LDR_LLM_PROVIDER– Provider identifier (openai,anthropic,ollama,gemini,localhost)LDR_LLM_MODEL– Model name for the selected provider (e.g.,gpt-4o,llama3.1)LDR_LLM_TEMPERATURE– Sampling temperature as float (e.g.,0.7)LDR_LLM_MAX_TOKENS– Token limit for completions (e.g.,2048)LDR_LLM_TOP_P– Nucleus sampling probability (e.g.,0.9)LDR_LLM_N– Number of completions to generateLDR_LLM_LOGPROBS– Number of log-probabilities to returnLDR_LLM_TIMEOUT– Request timeout in seconds for LLM calls (e.g.,60)
Provider-Specific Credentials and Endpoints
LDR_LLM_OPENAI_API_KEY– OpenAI API secretLDR_LLM_ANTHROPIC_API_KEY– Anthropic API secretLDR_LLM_OLLAMA_URL– Base URL for Ollama server (e.g.,http://localhost:11434)LDR_LLM_OLLAMA_MODEL– Specific Ollama model identifierLDR_LLM_OPENAI_ENDPOINT_URL– Custom OpenAI-compatible endpoint (e.g., Azure)LDR_LLM_OPENAI_ENDPOINT_API_KEY– API key for custom endpointsLDR_LLM_GEMINI_API_KEY– Google Gemini API keyLDR_LLM_GEMINI_MODEL– Gemini model name (e.g.,gemini-1.5-pro)LDR_LLM_GEMINI_ENDPOINT_URL– Optional custom Gemini API endpoint
How Variables Are Resolved
The resolution process occurs in three distinct phases:
-
Bootstrap Stage –
SettingsManager.get_bootstrap_env_vars()extracts critical variables likeLDR_APP_HOSTandLDR_DATA_DIRbefore any database connection is attempted. -
General Look-up – The
check_env_setting(key)helper constructs the environment variable name using theLDR_prefix pattern and callsos.getenv(). If present, the environment value overrides database and JSON defaults. -
Type Coercion – The system references the
UI_ELEMENT_TO_SETTING_TYPEmapping to convert raw strings into appropriate Python types, ensuringLDR_APP_DEBUG=truebecomes a booleanTrueandLDR_LLM_TEMPERATURE=0.7becomes a float.
Practical Configuration Examples
Running with OpenAI GPT-4o-mini
Configure the server to use OpenAI with specific model parameters:
export LDR_APP_HOST=0.0.0.0
export LDR_APP_PORT=8080
export LDR_LLM_PROVIDER=openai
export LDR_LLM_MODEL=gpt-4o-mini
export LDR_LLM_TEMPERATURE=0.5
export LDR_LLM_OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx
docker run -e LDR_APP_HOST -e LDR_APP_PORT -e LDR_LLM_PROVIDER \
-e LDR_LLM_MODEL -e LDR_LLM_TEMPERATURE -e LDR_LLM_OPENAI_API_KEY \
learningcircuit/local-deep-research
CI Environment Optimization
Disable external providers and force fallback for faster unit tests:
export LDR_DISABLE_OPENAI=true
export LDR_DISABLE_OLLAMA=true
export LDR_DISABLE_ANTHROPIC=true
export LDR_USE_FALLBACK_LLM=true
export LDR_CI=true
Custom Search Constraints
Limit search duration and result volume for resource-constrained environments:
export LDR_SEARCH_TIMEOUT=15
export LDR_SEARCH_TOOL_MAX_RESULTS=5
Local Ollama Integration
Point to a local Ollama instance instead of cloud providers:
export LDR_LLM_PROVIDER=ollama
export LDR_LLM_OLLAMA_URL=http://localhost:11434
export LDR_LLM_OLLAMA_MODEL=llama3.1
Key Source Files
The environment variable system is implemented across several critical modules:
-
src/local_deep_research/settings/manager.py– ContainsSettingsManagerclass, the prefix building logic (env_variable_name = f"LDR_{'_'.join(key.split('.')).upper()}"on lines 41-44), and theUI_ELEMENT_TO_SETTING_TYPEmapping (lines 54-61) for type conversion. -
src/local_deep_research/settings/env_registry.py– Central registry listing bootstrap variables and credentials that must remain environment-only. -
src/local_deep_research/web/app_factory.py– Consumes bootstrap variables to configure Flask debug mode, rate limiting, and server binding. -
src/local_deep_research/web/services/research_service.py– Reads LLM configuration variables to initialize provider clients and pass parameters to the inference layer. -
examples/optimization/run_optimization.py– Demonstrates production deployment patterns setting multipleLDR_LLM_*variables programmatically.
Summary
- All configuration uses the
LDR_prefix with dot-notation keys converted to uppercase underscores (e.g.,llm.model→LDR_LLM_MODEL). - Bootstrap variables like
LDR_APP_HOST,LDR_DATA_DIR, andLDR_CIare resolved before database initialization viaSettingsManager.get_bootstrap_env_vars(). - Research behavior is controlled by
LDR_SEARCH_TIMEOUT,LDR_SEARCH_TOOL_MAX_RESULTS,LDR_RATE_LIMITING_ENABLED, and provider disable flags (LDR_DISABLE_OPENAI, etc.). - LLM configuration requires
LDR_LLM_PROVIDERselection plus provider-specific credentials (LDR_LLM_OPENAI_API_KEY,LDR_LLM_OLLAMA_URL) and inference parameters (LDR_LLM_TEMPERATURE,LDR_LLM_MAX_TOKENS). - Type coercion is handled automatically by the
UI_ELEMENT_TO_SETTING_TYPEmapping inmanager.py, converting environment strings to proper Python types.
Frequently Asked Questions
How do I change the LLM model without modifying code?
Set the LDR_LLM_PROVIDER and LDR_LLM_MODEL environment variables. For example, to use OpenAI's GPT-4o, export LDR_LLM_PROVIDER=openai and LDR_LLM_MODEL=gpt-4o before starting the application. The research_service.py module reads these variables to instantiate the correct provider class.
Why are my boolean environment variables not working?
The system uses the UI_ELEMENT_TO_SETTING_TYPE mapping in manager.py to coerce types. Ensure you use lowercase true or false for boolean flags like LDR_APP_DEBUG or LDR_RATE_LIMITING_ENABLED. The conversion logic handles the string-to-boolean transformation automatically.
Can I use a custom OpenAI-compatible endpoint like Azure?
Yes. Instead of setting LDR_LLM_OPENAI_API_KEY, use LDR_LLM_OPENAI_ENDPOINT_URL for the base URL (e.g., https://my-endpoint.openai.azure.com/v1) and LDR_LLM_OPENAI_ENDPOINT_API_KEY for the authentication key. This bypasses the standard OpenAI API configuration and points the client to your custom endpoint.
What happens if I set LDR_CI=true?
Setting LDR_CI=true signals to the application that it is running in a continuous integration environment. This disables interactive prompts that would otherwise block execution, allows the LDR_BOOTSTRAP_ALLOW_UNENCRYPTED flag to function for test databases, and ensures the application exits cleanly without waiting for user input during initialization.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →