Model Profiles and Gemma
May 13, 2026 ยท View on GitHub
OpenClaw integrates Gemma-family models, including Gemma 4, through the existing provider seams instead of creating a Gemma-specific runtime fork.
That design keeps:
- one execution stack
- one tool-calling stack
- one session/compaction/middleware stack
- one MAF integration path
Gemma is treated as a model backend that can be reached through:
- Ollama for local and development workflows
- OpenAI-compatible endpoints for production or self-hosted inference gateways
- embedded for OpenClaw-managed local packages and sidecar inference
- future provider extensions if needed, without changing the runtime architecture
Why profiles exist
Providers and models do not expose the same capabilities. A route that needs tool calling, structured outputs, and image input should not silently run against a model that only supports plain text chat.
Model profiles let OpenClaw describe a model instance independently from the provider transport:
- profile id
- provider id
- model id
- base URL
- API key or env ref
- capabilities
- context/output hints
- tags such as
local,private,cheap,tool-reliable,vision
The runtime uses those profiles to:
- select a profile explicitly
- choose a profile based on route/session capability requirements
- prefer tags such as
localorprivate - fall back to another profile when allowed
- fail clearly when no profile can safely satisfy the request
OpenAI-compatible request mapping
When a client calls OpenClaw's OpenAI-compatible HTTP routes, the request model field is interpreted as either:
- a model profile id, if it matches a configured OpenClaw profile, or
- a literal upstream model id override, if it does not.
If the request omits model, OpenClaw falls back to the configured default profile or OpenClaw:Llm:Model.
This matters for downstream integrations:
"default"is not a built-in sentinel for "use your configured default"."default"only works if you defined a profile with iddefault.- If you want the gateway default route, omit
model.
Example configuration
{
"OpenClaw": {
"Llm": {
"Provider": "openai",
"Model": "gpt-4.1"
},
"Models": {
"DefaultProfile": "gemma4-prod",
"Profiles": [
{
"Id": "gemma4-local",
"Provider": "ollama",
"Model": "gemma4",
"BaseUrl": "http://localhost:11434/v1",
"Tags": ["local", "private", "cheap"],
"Capabilities": {
"SupportsTools": false,
"SupportsVision": true,
"SupportsJsonSchema": false,
"SupportsStructuredOutputs": false,
"SupportsStreaming": true,
"SupportsParallelToolCalls": false,
"SupportsReasoningEffort": false,
"SupportsSystemMessages": true,
"SupportsImageInput": true,
"SupportsAudioInput": false,
"MaxContextTokens": 131072,
"MaxOutputTokens": 8192
}
},
{
"Id": "gemma4-prod",
"Provider": "openai-compatible",
"Model": "gemma-4",
"BaseUrl": "https://your-inference-gateway.example.com/v1",
"ApiKey": "env:MODEL_PROVIDER_KEY",
"Tags": ["private", "prod", "vision"],
"FallbackProfileIds": ["frontier-tools"],
"Capabilities": {
"SupportsTools": true,
"SupportsVision": true,
"SupportsJsonSchema": true,
"SupportsStructuredOutputs": true,
"SupportsStreaming": true,
"SupportsParallelToolCalls": true,
"SupportsReasoningEffort": false,
"SupportsSystemMessages": true,
"SupportsImageInput": true,
"SupportsAudioInput": false,
"MaxContextTokens": 262144,
"MaxOutputTokens": 16384
}
},
{
"Id": "frontier-tools",
"Provider": "openai",
"Model": "gpt-4.1",
"Tags": ["tool-reliable", "frontier"],
"Capabilities": {
"SupportsTools": true,
"SupportsVision": true,
"SupportsJsonSchema": true,
"SupportsStructuredOutputs": true,
"SupportsStreaming": true,
"SupportsParallelToolCalls": true,
"SupportsReasoningEffort": true,
"SupportsSystemMessages": true,
"SupportsImageInput": true,
"SupportsAudioInput": true,
"MaxContextTokens": 1000000,
"MaxOutputTokens": 32768
}
}
]
},
"Routing": {
"Enabled": true,
"Routes": {
"telegram:private-coder": {
"ChannelId": "telegram",
"SenderId": "private-coder",
"ModelProfileId": "gemma4-local",
"PreferredModelTags": ["local", "private"],
"FallbackModelProfileIds": ["frontier-tools"],
"ModelRequirements": {
"SupportsTools": true,
"SupportsStreaming": true
}
}
}
}
}
}
Gemma through Ollama
Use this when you want local/private inference for development or workstation deployments.
{
"Id": "gemma4-local",
"Provider": "ollama",
"Model": "gemma4",
"BaseUrl": "http://localhost:11434/v1",
"Tags": ["local", "private", "cheap"]
}
Notes:
- OpenClaw talks to Ollama through the existing OpenAI-compatible adapter path.
BaseUrldefaults tohttp://localhost:11434/v1if omitted by the legacy provider config, but setting it explicitly is clearer for named profiles.- If the profile does not advertise
SupportsTools, routes that require tools will fail clearly or fall back.
Gemma through embedded local inference
Use this when OpenClaw should manage the local model package, cache, and sidecar lifecycle.
{
"Id": "embedded-local",
"PresetId": "embedded-gemma-4-e4b",
"Provider": "embedded",
"Model": "gemma-4-e4b",
"Tags": ["local", "private", "offline"],
"FallbackProfileIds": ["frontier-tools"]
}
Notes:
openclaw models packageslists installable packages, backend, context, checksum, and experimental status.- GGUF packages run through a supervised
llama-serversidecar. - LiteRT-LM packages are experimental and require
OpenClaw:LocalInference:LiteRtRuntimePathto point to an OpenClaw-compatible adapter binary; OpenClaw does not assume a genericlitert-server. - Embedded video support is frame-based in v1: OpenClaw samples local
video/*content withffprobe/ffmpeg, writes frames to the media cache, and sends orderedimage_urlframe parts to the sidecar. - A profile only advertises video input when the embedded model supports image input and
OpenClaw:Multimodal:Video:Enabledis true.
Gemma through an OpenAI-compatible gateway
Use this when Gemma is hosted behind a production inference service that exposes an OpenAI-compatible API.
{
"Id": "gemma4-prod",
"Provider": "openai-compatible",
"Model": "gemma-4",
"BaseUrl": "https://your-inference-gateway.example.com/v1",
"ApiKey": "env:MODEL_PROVIDER_KEY",
"Tags": ["private", "prod", "vision"]
}
Notes:
- OpenClaw uses the existing OpenAI-compatible provider transport.
- No Gemma-specific runtime logic is required.
- Capability flags should reflect what your actual gateway exposes for that Gemma deployment.
Route assignment and fallback
Routes can now express:
ModelProfileIdPreferredModelTagsFallbackModelProfileIdsModelRequirements
Common patterns:
- coding/tool-heavy route: require
SupportsTools=true, prefer tagtool-reliable - privacy-sensitive route: prefer tags
localandprivate - cheap summarization route: prefer tags
cheapandlocal
If the selected profile cannot satisfy the request, OpenClaw will either:
- fall back to the first compatible profile in
FallbackModelProfileIds, or - fail with a clear message such as:
This route requires tool calling, but selected model profile 'gemma4-local' does not support it.
Capability flags
OpenClaw currently uses capability flags for:
- tool calling
- vision and image input
- JSON schema and structured outputs
- streaming
- parallel tool calls
- reasoning effort
- system messages
- audio input
- context/output token hints
These flags drive profile selection and request validation. They do not add provider-specific runtime branches.
CLI and operator surfaces
List profiles:
openclaw models list
Run profile doctor:
openclaw models doctor
Run the built-in evaluation suite:
openclaw eval run --profile gemma4-prod
Compare multiple profiles:
openclaw eval compare --profiles gemma4-prod,frontier-tools
The gateway also exposes:
GET /admin/modelsGET /admin/models/doctorPOST /admin/models/evaluations
Evaluation harness
The first version ships with OpenClaw-native scenarios:
- plain chat response
- structured JSON extraction
- tool selection correctness
- multi-turn continuity
- compaction recovery
- streaming behavior
- vision input behavior
Reports are written to:
memory/admin/model-evaluations/<run-id>.jsonmemory/admin/model-evaluations/<run-id>.md
This is intentionally lightweight and filesystem-based for the first release.