Skip to content

Models

A model is whatever turns a prompt into text. GalapagosModel.from_card loads one from a model name + a host; the host selects an OpenAI-compatible endpoint and resolves its base_url. The model is the LLM the Proposer calls each step.

import galapagos as gx

model = gx.GalapagosModel.from_card(name="openai/gpt-5.5", host="openrouter")
# functional alias:
model = gx.load_model("openai/gpt-5.5", host="openrouter")

One client (APIModel) covers every hosting platform — only the base_url (and which env vars it reads) changes. The client is built lazily, so importing Galapagos never requires credentials.

A model is loaded from a Model Cardname, model_path, host, temperature, max_tokens — exactly like every other Galapagos artifact.


The host table

host selects the endpoint. The platform's host vocabulary spans managed routers, self-hosted servers, and direct provider APIs. The hosts below are wired into the shipped loader; each resolves a base_url, and an explicit base_url= argument always overrides it.

host Resolved base_url Notes
openrouter https://openrouter.ai/api/v1 Default when host is omitted.
openai None → falls back to OPENAI_BASE_URL (or the OpenAI default) The vanilla OpenAI API.
litellm LITELLM_BASE_URL env, else http://localhost:4000 A LiteLLM proxy (any provider behind it).
vllm VLLM_BASE_URL env, else http://localhost:8000/v1 A local vLLM OpenAI server.
azure AZURE_OPENAI_BASE_URL env Azure OpenAI.
anthropic ANTHROPIC_BASE_URL env, else https://api.anthropic.com/v1/ Anthropic's OpenAI-compatible endpoint.
gemini GEMINI_BASE_URL env, else https://generativelanguage.googleapis.com/v1beta/openai/ The Gemini OpenAI-compatible endpoint.

host may also be a full URL — any value containing :// is used verbatim as the base_url (no env-var key lookup; pass api_key= or set OPENAI_API_KEY). This is how you reach any OpenAI-compatible endpoint without a named host — Together AI, an HF TGI / Inference Endpoint, a Bedrock proxy, and so on.

Anthropic & Gemini

anthropic and gemini are first-class hosts wired into the shipped loader, reached via each provider's OpenAI-compatible endpoint (override with ANTHROPIC_BASE_URL / GEMINI_BASE_URL). They are also reachable through a router — host="openrouter" (which fronts both) or host="litellm" — since every Galapagos model speaks the OpenAI chat-completions API through the single APIModel client.

Every host routes through the same APIModel. Authentication comes from per-host env vars, checked in order:

Env var Used for
OPENROUTER_API_KEY the key for openrouter; an OpenAI credential is never forwarded to OpenRouter.
ANTHROPIC_API_KEY the key for anthropic.
GEMINI_API_KEY / GOOGLE_API_KEY the key for gemini (checked in that order).
AZURE_OPENAI_API_KEY / AZURE_API_KEY the key for azure (falls back to OPENAI_API_KEY).
OPENAI_API_KEY the key for openai and generic OpenAI-compatible endpoints (defaults to "EMPTY" for keyless local servers like vLLM / LiteLLM).
TAVILY_API_KEY Tavily search credential, read only when an enabled model actually calls tavily_search.
OPENAI_BASE_URL the fallback base_url when the host resolves to None (i.e. host="openai").
LITELLM_BASE_URL / VLLM_BASE_URL / AZURE_OPENAI_BASE_URL (or AZURE_OPENAI_ENDPOINT) / ANTHROPIC_BASE_URL / GEMINI_BASE_URL per-host base_url overrides (see the table).
gx.GalapagosModel.from_card(name="meta-llama/Llama-3-70B",
                            host="https://api.together.xyz/v1")   # any OpenAI-compatible URL
gx.load_model("gpt-5.5", host="azure")              # base_url from AZURE_OPENAI_BASE_URL

from_card / load_model also accept temperature, top_p, max_tokens, reasoning_effort, timeout, retries, retry_delay, tool_call_on, max_tool_rounds, max_tool_output_chars, tavily_tool, and api_key. retries is the maximum number of total Galapagos attempts; SDK retries are disabled so retry budgets cannot multiply.

An LLMProposer can set proposer.children_per_model_call: N to request N Chat Completions choices in one provider call. The proposer translates that config value to the provider's n argument. The primary choice remains the ordinary Generation; additional choices are available via generation.responses() and the scaffold emits all of them as same-parent sibling candidates in one iteration. All evaluable siblings are scored first; the best one is admitted by default, or the best K when proposer.children_to_keep: K is set. Non-selected candidates remain traceable but do not enter the Population. A provider-default Responses mode automatically uses Chat Completions for this call, because the Responses request schema has no multi-choice n field; an explicit responses_api=True remains an error rather than being silently overridden.

API-backed proposers can make source-backed web searches during generation. The feature is gated: when tool_call_on is absent or false, Galapagos sends exactly the ordinary model request and does not import Tavily. Enable it in the run config:

proposer:
  model_name: Qwen/Qwen3.6-35B-A3B
  api_base: vllm
  tool_call_on: true
  max_tool_rounds: 3
  max_tool_output_chars: null  # default: keep the complete tool response
  tavily_tool:
    base_url: https://api.tavily.com
    timeout: 60.0
    search_depth: advanced     # basic | advanced | fast | ultra-fast
    topic: general             # general | news | finance
    max_results: 5
    chunks_per_source: 3
    auto_parameters: false
    exact_match: false
    time_range: null
    start_date: null
    end_date: null
    days: null
    include_domains: []
    exclude_domains: []
    country: null
    include_answer: true
    include_raw_content: false
    include_images: false
    include_image_descriptions: false
    include_favicon: false
    include_usage: true
    safe_search: false

Install the optional client and provide its credential to the Galapagos process:

uv sync --extra web-search              # source checkout
# or: pip install 'open-galapagos[web-search]'
export TAVILY_API_KEY='tvly-...'

With the gate on, Galapagos exposes tavily_search with required query and optional max_results (020). Extra model-generated arguments are accepted for forward compatibility but ignored; every other search option remains caller-controlled under proposer.tavily_tool. Galapagos requests parallel tool calls and executes all calls returned in the same round concurrently with asyncio.gather, while preserving the provider's call order in the trajectory and matching role: tool messages. proposer.max_tool_rounds limits executed tool rounds (default 3; must be at least 1), not the answer that consumes them. If the model uses the entire budget, Galapagos makes one additional tool-disabled synthesis call over the final result. Search queries, complete configured response fields, the round limit, tool latency, and combined multi-round token/cost accounting are preserved. Empty result sets are valid. The raw candidate row uses proposal.tool_calls[] plus proposal.tool_summary; ETIF records one logical model_call and one provider-neutral tool/execute event per attempted call. Failed calls retain their arguments, duration, and structured error.

Tool responses are unlimited by default (max_tool_output_chars: null). Set a positive character limit only when a deployment needs to bound context growth. Tavily credentials are deliberately environment-only: TAVILY_API_KEY is never stored in the serializable run config.

At INFO level, each completed tool execution prints one compact tool line (round, tool name, result count, and duration); rejected or failed executions print a warning. The following model line summarizes the whole logical call, including its LLM-round count and tools succeeded/attempted count. Arguments and result bodies stay out of normal console logs and remain available in the trajectory.

Tool mode uses Chat Completions even when that provider normally defaults to the Responses API. For vLLM, start the server with automatic tool choice and the model-appropriate tool-call parser; the repository's scripts/vllm/serve_qwen3.6-35b-a3b.sh is a working example. Tool calling is incompatible with proposer.children_per_model_call > 1.


The three mandated load forms

Every model comes from one of three places — a Hugging Face endpoint, a hosting platform, or your own local vLLM server:

A model served behind an OpenAI-compatible HF endpoint (TGI / Inference Endpoint):

model = gx.GalapagosModel.from_card(
    name="Qwen/Qwen3-8B",
    host="https://<your-endpoint>.endpoints.huggingface.cloud/v1",  # any OpenAI-compatible URL
)
Supply the key via api_key= or OPENAI_API_KEY.

A managed router / aggregator or direct provider API (OpenRouter, OpenAI, Anthropic, Gemini, Azure, LiteLLM):

model = gx.GalapagosModel.from_card(name="openai/gpt-5.5", host="openrouter")

Your own vLLM server (or any OpenAI-compatible endpoint), addressed by base_url:

model = gx.GalapagosModel.from_card(
    name="Qwen/Qwen3-8B", host="vllm",
    base_url="http://localhost:8000/v1",       # explicit > VLLM_BASE_URL > default
)


Loading from a model card

A ModelCard YAML can carry the name/host/defaults so a run is fully reproducible from disk:

model = gx.GalapagosModel.from_card(path="my_model_card.yaml")

model_path (or name), host, and the generation params (temperature, top_p, max_tokens, reasoning_effort, timeout, retries, retry_delay, tool_call_on, max_tool_rounds, max_tool_output_chars, tavily_tool) are read from the card; explicit arguments override the card.


The scaffold default model

A ScaffoldCard declares a default model:

model:
  default: openai/gpt-5.5
  host: openrouter

When you call a scaffold's from_card() without passing model= and without a model named in the run config's proposer section, the scaffold builds this default itself (precedence: explicit model= > config.proposer > the card's model.default).

Coding agents are not load_model models

An agent-as-operator method drives a CLI coding agent. That agent is the Proposer's variation operator, exposed through env, not something you pass to from_card. See Core components — Proposer.


See also