How to Switch Between LLM Providers Programmatically in VulnClaw
Use the apply_provider_preset helper function to update the global VulnClawConfig object, which resolves the provider name to an enum, auto-fills default base_url and model values when appropriate, and leaves user-customized settings untouched.
VulnClaw is an open-source security analysis framework that relies on Large Language Models (LLMs) for vulnerability detection. When you need to switch between LLM providers programmatically in VulnClaw, the library provides a dedicated configuration management system that handles provider resolution, default value injection, and persistence through a clean Python API.
Understanding the Provider Configuration Architecture
The provider state is stored in the global configuration object VulnClawConfig.llm.provider, which is managed through the configuration module in vulnclaw/config/settings.py. The core mechanism relies on the apply_provider_preset function (source lines 311-348), which orchestrates the switching logic by interacting with preset definitions stored in vulnclaw/config/schema.py under the PROVIDER_PRESETS mapping.
When invoked, apply_provider_preset performs four critical operations: it resolves the provider string to the internal LLMProvider enum, updates config.llm.provider to its canonical value, auto-fills base_url and the default model only when the provider changes or when current fields still contain the old provider's defaults, and preserves any user-customized values that deviate from the presets.
Switching to a Built-in Provider
To switch to a supported provider like DeepSeek, load the configuration, apply the preset, and optionally persist the changes to disk.
from vulnclaw.config.settings import load_config, save_config, apply_provider_preset
# Load the current configuration
cfg = load_config()
# Switch to the DeepSeek provider (auto-fills its base_url & default model)
cfg = apply_provider_preset(cfg, "deepseek")
# Persist the change (writes ~/.vulnclaw/config.yaml)
save_config(cfg)
print(f"Now using {cfg.llm.provider} @ {cfg.llm.base_url} – model {cfg.llm.model}")
This call resolves the string "deepseek" to the enum LLMProvider.deepseek and injects the corresponding defaults from PROVIDER_PRESETS as defined in lines 311-348 of vulnclaw/config/settings.py.
Configuring Custom Providers
For providers not included in the built-in presets, apply_provider_preset accepts arbitrary provider names and stores them unchanged, allowing you to manually configure the connection parameters.
cfg = load_config()
cfg = apply_provider_preset(cfg, "my-custom-provider") # not in PROVIDER_PRESETS
cfg.llm.base_url = "https://api.myprovider.com/v1"
cfg.llm.model = "my-model"
save_config(cfg)
If the provider name is unknown, the function simply updates the provider field without overwriting existing base_url or model values (source lines 319-324), enabling seamless integration of private or experimental endpoints.
Runtime Provider Switching Without Persistence
For temporary provider changes that should not affect the global configuration file, apply the preset and use the configuration object directly without calling save_config.
cfg = load_config()
cfg = apply_provider_preset(cfg, "zhipu")
# Use cfg directly with the LLM client; do NOT call save_config()
client = make_openai_client(api_key=cfg.llm.api_key,
base_url=cfg.llm.base_url)
# …run queries…
This approach keeps the switch in-memory only, ensuring that subsequent executions revert to the persisted defaults.
Discovering Available Providers
Before switching, enumerate the built-in presets using the list_providers function (source lines 352-363) to inspect default models and endpoint configurations.
from vulnclaw.config.settings import list_providers
for p in list_providers():
print(f"{p['provider']}: {p['label']} – default model {p['default_model']}")
This utility walks the PROVIDER_PRESETS dictionary in vulnclaw/config/schema.py, returning metadata for each supported provider including labels and default model identifiers.
Summary
- The
apply_provider_presetfunction invulnclaw/config/settings.py(lines 311-348) is the canonical method to switch between LLM providers programmatically in VulnClaw. - Provider presets are defined in
vulnclaw/config/schema.pyunderPROVIDER_PRESETS, mapping provider names to their defaultbase_urlandmodelvalues. - The function auto-fills defaults only when switching providers or when existing values match the previous provider's defaults, preserving user customizations.
- Use
load_configto read the current state andsave_configto persist changes to~/.vulnclaw/config.yaml. - Use
list_providers(lines 352-363) to discover available built-in providers before switching.
Frequently Asked Questions
How does VulnClaw handle provider defaults when switching?
VulnClaw only auto-fills the base_url and model fields when the provider actually changes or when these fields still contain the previous provider's default values. If you have manually customized these settings, apply_provider_preset leaves them untouched to prevent overwriting user preferences.
Can I switch to a custom LLM provider not in the preset list?
Yes. When you pass a provider name that is not found in PROVIDER_PRESETS, apply_provider_preset stores the name as-is without modifying other configuration fields (source lines 319-324). You can then manually set cfg.llm.base_url and cfg.llm.model to point to your custom endpoint.
Where are the provider presets defined in the source code?
The preset definitions reside in vulnclaw/config/schema.py within the PROVIDER_PRESETS dictionary. These presets map provider strings to their corresponding LLMProvider enum values and default connection parameters, which are then consumed by the apply_provider_preset function in vulnclaw/config/settings.py.
Is it possible to switch providers temporarily without saving to disk?
Yes. Simply omit the save_config(cfg) call after applying the preset. The configuration object remains modified in-memory for the duration of your Python session, but the underlying ~/.vulnclaw/config.yaml file retains its original provider settings, making this ideal for one-off analysis tasks or testing different models.
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 →