Skip to main content
An air-gapped install calls the LLM endpoint you choose: a local OpenAI-compatible runtime, Amazon Bedrock over PrivateLink, or a hosted provider if your egress allows. Declare the defaults at install, then register any local endpoint under Platform > AI governance > Models.

Local LLM inference

xpander speaks the OpenAI-compatible API, so any local runtime that exposes it plugs in: Size the inference pool separately: it is your infrastructure, not part of the chart. Hosted providers also work if your egress allows, with the same LLM provider keys. Two models are declared at install: the agents’ default and the gateway model that filters requests first (global.llm.gateway.{provider,model,apiBase}). Each install or upgrade converges the organization’s defaults to the chart’s declaration only when that declaration changed, so defaults an admin edited in the UI survive upgrades. Summaries around agent work (thread titles, context compaction, evaluation judges) use the org default model, backed by the install’s other providers. None dials a public endpoint on a sealed install.

Amazon Bedrock without a key

In images built after 27 August 2026, chat, tasks and their summaries use the pods’ own AWS identity (EKS Pod Identity or IRSA): leave global.llm.bedrock.bearerTokenSecret empty and set global.llm.bedrock.region.
  • The pod role needs bedrock:InvokeModel, bedrock:InvokeModelWithResponseStream, bedrock:Converse and bedrock:ConverseStream on * (the global.* profiles route across regions), bound to both default and agent-controller ServiceAccounts. No second role is assumed.
  • The account must be opted in to Bedrock data retention for those models in every region a global. profile spans. A sealed network needs VPC endpoints for bedrock-runtime, sts and eks-auth.
  • A Bedrock API key in bearerTokenSecret is the alternative.
  • The “IAM role” method under Platform > AI governance > Models applies to the Claude Code leg only. If such an entry exists and chat fails, remove it and restart agent-controller, agent-worker, agents, actions and functions.
Leave bearerTokenSecret and assumeRoleArn unset, put the Bedrock permissions on the role the pods run as (xpander-sa-role there), bind it to default and agent-controller, and upgrade. No separate Bedrock role is needed.
Claude Code on Bedrock: the CLI calls the in-cluster LLM Gateway directly, and the gateway gets the Bedrock credential from the Agent Controller, the only place assume-role applies: global.llm.bedrock.assumeRoleArn (plus assumeRoleExternalId), or with no token and no role, the pod’s own credentials. global.llm.bedrock.baseUrl points it at your VPC endpoint. Fable- and Mythos-class models also need the per-region data-retention opt-in. See AI vendors.

A worked vLLM setup on EKS Auto Mode

Checked end to end on an Air-Gapped install: vLLM serving a small instruct model on a T4, registered as a custom provider. The cluster side is yours. xpander needs only the address. GPU capacity. A NodePool limited to g4dn with a nvidia.com/gpu taint gets a T4 node in about two minutes, exposing nvidia.com/gpu: 1 with no device plugin. It needs nodeClassRef group: eks.amazonaws.com, kind: NodeClass, name: default. Keep weights on a PersistentVolumeClaim mounted as HF_HOME (pre-loaded on a sealed network). Five things that stop vLLM:
  1. A Service named vllm injects VLLM_PORT=tcp://... and vLLM refuses to start (VLLM_PORT ... appears to be a URI). Set enableServiceLinks: false or rename the Service.
  2. A T4 needs --dtype=half. vLLM 0.11 crash-loops on a T4. vllm/vllm-openai:v0.9.2 works.
  3. Pass the key as VLLM_API_KEY, not --api-key (which logs it). It guards only /v1. /health, /metrics and /tokenize answer without it, so keep port 8000 on a ClusterIP Service, never an ingress or load balancer.
  4. Start with --enable-auto-tool-choice --tool-call-parser=hermes, or Add provider marks the model as unable to run agents.
  5. Leave room above the composed prompt. --max-model-len=8192 failed with 400 This model's maximum context length is 8192 tokens. However, you requested 8298 tokens, shown as Unknown model error (controller log: Non-retryable model provider error: Unknown model error next to [prompt-budget] system_message_tok=...). --max-model-len=32768 ran. Custom models also log unknown model.id ... defaulting to 128,000 window.
The manifests, with account-specific values replaced by placeholders:

Register the endpoint in xpander

  1. Platform > AI governance > Models, Add provider.
  2. Name is free text, and ID (used in API calls) derives from it and is fixed. Protocol: OpenAI-compatible. Base URL: the address the pods reach, for example http://vllm.<namespace>.svc.cluster.local:8000/v1. In-cluster addresses work on Hybrid and Air-Gapped. xpander cloud accepts only a public https address.
  3. API key: No key (local or unauthenticated server), Use an existing key, or Create a new key with a Key name and the API key (the VLLM_API_KEY value).
  4. Test connection shows Reachable and the served models. A tools badge marks models that accept function calls. Add the model, with an optional Display name.
  5. Click Add provider.
  6. In the provider’s Keys and models…, tick the models the organization may use. Prices (USD per 1M tokens, via Edit model) track spend and are never charged. Who may use it… sets access. New models wait under New models unless Approve new models automatically is on. Agent readiness shows, from the last Test model, which harnesses work with each model.
Models page with the xpander.ai vllm provider panel open, showing Keys, LLM gateway, New models with Approve new models automatically, a Models list with muse-glimmer ticked and its prices

Keys and models on a custom provider: the key in use, New models waiting for approval, the models the organization may use with their prices. Shown with sample data and a different model than the one deployed above.

POST /v1/agents accepts only built-in providers in model_provider (a custom ID gets 422). Pick a custom provider per conversation in Harness and model. The header then reads, for example, OpenCode · Qwen2.5 1.5B (lab T4), the controller logs gateway turn start with model=<host>:<port>/<model id>, and vLLM logs POST /v1/chat/completions 200.