Cameleer

Model providers and call optimizations

Cameleer talks to 23 model providers out of the box: seven native components and 19 OpenAI-compatible services through provider= presets, plus any other OpenAI-compatible server through baseUrl. Around each model call it adds what usually needs a separate gateway: retries, fallback models, prompt caching, an exact response cache and coalescing of identical requests. These run in the same process as the routes, so they add no network hop.

Cargo feature: saas (openai, llm, anthropic, gemini) and cloud (azure-openai, aws-bedrock, google-vertexai) ยท Apache Camel: the openai/llm options mirror Camel 4.23; presets, caching and the reliability options are Cameleer extensions

Native components

componentAPItool callingnotes
openai, llmOpenAI Chat Completions, Responses API, embeddingsyesstreaming in the tool loop
openai with apiFormat=ollamaOllama's /api/chatyes
anthropicAnthropic Messages APIyesautomatic prompt caching
geminiGemini API (AI Studio keys)yesthought signatures kept
azure-openaiAzure OpenAI deploymentsyesEntra ID or keys
aws-bedrockBedrock Converse (Claude, Llama, Mistral, Nova, ...)yesguardrails, opt-in prompt caching
google-vertexaiGemini on Vertex AIyesservice accounts

All of them are models for the agent step and take the same tool options.

Provider presets

provider=NAME on openai: / llm: sets the base URL and the environment variable the key is read from. baseUrl and apiKey still override both.

yaml example: model-providers-groq
- route:
    from:
      uri: direct:ask
      steps:
        - to: "llm:chat-completion?provider=groq&model=llama-3.3-70b-versatile&tags=support"
providerbase URLkey from
openai (default)https://api.openai.com/v1OPENAI_API_KEY
geminihttps://generativelanguage.googleapis.com/v1beta/openaiGEMINI_API_KEY
mistralhttps://api.mistral.ai/v1MISTRAL_API_KEY
deepseekhttps://api.deepseek.com/v1DEEPSEEK_API_KEY
xaihttps://api.x.ai/v1XAI_API_KEY
groqhttps://api.groq.com/openai/v1GROQ_API_KEY
cerebrashttps://api.cerebras.ai/v1CEREBRAS_API_KEY
togetherhttps://api.together.xyz/v1TOGETHER_API_KEY
fireworkshttps://api.fireworks.ai/inference/v1FIREWORKS_API_KEY
openrouterhttps://openrouter.ai/api/v1OPENROUTER_API_KEY
perplexityhttps://api.perplexity.aiPERPLEXITY_API_KEY
huggingfacehttps://router.huggingface.co/v1HF_TOKEN
dashscope (Qwen)https://dashscope-intl.aliyuncs.com/compatible-mode/v1DASHSCOPE_API_KEY
moonshot (Kimi)https://api.moonshot.ai/v1MOONSHOT_API_KEY
coherehttps://api.cohere.ai/compatibility/v1COHERE_API_KEY
nvidia (NIM)https://integrate.api.nvidia.com/v1NVIDIA_API_KEY
ollamahttp://localhost:11434/v1OLLAMA_API_KEY (usually none)
vllmhttp://localhost:8000/v1VLLM_API_KEY
lmstudiohttp://localhost:1234/v1LMSTUDIO_API_KEY
llamacpphttp://localhost:8080/v1LLAMACPP_API_KEY

Any other OpenAI-compatible server works with baseUrl. Azure OpenAI's v1 API and Bedrock's OpenAI-compatible endpoint work the same way; the native components add Entra ID, SigV4 and guardrails.

What the component adjusts per provider:

  • OpenAI's o-series and GPT-5 models get max_completion_tokens instead of max_tokens.
  • DeepSeek, Qwen and Kimi return reasoning_content with tool calls and want it back on the next turn; Cameleer sends it back.
  • Missing tool call ids (some Ollama versions) are generated.

The presets were checked against each provider's documentation, not against the live services; the tests run against mocks.

Reliability and cost

Every model component takes these options. They apply to the tool loop and the agent step.

optiondefaultdescription
maxRetries2Retries of 408, 409, 425, 429, 5xx and 529 answers, timeouts and resets, with exponential backoff
retryDelay500msThe first backoff; it doubles each retry, up to 10 s
fallbackModelsModel endpoint URIs, comma separated, tried in order when the model still fails. Inside a URI option, write the fallback's own & as %26
responseCacheoffexact: an identical request (same model, messages, tools and system prompt) is answered from memory
responseCacheTtl5mHow long a cached answer is used
responseCacheSize1000Answers kept; the oldest goes first
coalescefalseIdentical requests in flight at the same time share one model call
yaml example: model-providers-fallback
- route:
    from:
      uri: direct:ask
      steps:
        - to: "openai:chat-completion?model=gpt-5.4-mini&tags=support&responseCache=exact&fallbackModels=anthropic:messages?model=claude-sonnet-4-5"

What these guarantee:

  • A retried, cached or coalesced model turn never repeats a tool call: tools run in the ai-tool envelope after the model answers, with their own idempotency.
  • A cached or coalesced answer reports zero tokens, so the usage headers show what was paid.
  • A streamed call is not retried once text has been sent to the chunk processor.
  • responseCache and coalesce are off by default: two users who send the same prompt get the same answer. Turn them on for classification, extraction and other deterministic calls.

Prompt caching

Providers bill cached input at a fraction of the normal price, but only for a prefix that is byte-for-byte the same as last time. Cameleer assembles the prompt itself (tools in a fixed order, then the system prompt, then the history), so the prefix is stable from turn to turn.

componenthowdefault
anthropiccache_control breakpoints on the last tool, the system prompt and the last messageon (promptCaching=auto)
aws-bedrockConverse cachePoint after the tools, the system prompt and the last messageoff (promptCaching=true), because models without caching reject it
openai and presetsthe provider's automatic prefix cachingalways (provider side)
gemini, google-vertexaiGemini's implicit cachingalways (provider side)

CamelAiCacheReadTokens and CamelAiCacheWriteTokens report the cached input tokens of a call when there were any. A prompt shorter than the provider's minimum (about 1024 tokens for most models) is not cached and costs nothing extra.

Why in-process

A hosted gateway adds a network hop to every model call; a sidecar gateway adds a local hop and another process. Cameleer's model calls go straight from the route to the provider over pooled keep-alive connections (no TCP and TLS handshake after the first call), and the cache and coalescing live in the same memory as the routes. The tool loop, approvals and the audit log are in the same process too, so a retried model turn can't run a tool twice.

Found a problem?

If something on this page doesn't match what Cameleer does, please open an issue, or fork the repository, fix it, add a test, run cargo test --workspace and open a pull request.

Edit this page on GitHub