Skip to content
kitn AI/UI

Connect any model

AI/UI doesn’t care which model answers. Point it at OpenAI, Anthropic, Grok, GLM, DeepSeek, Llama — anything — and let people switch between them from a dropdown in the chat header. Open the model menu below and pick a different provider.

The switch isn’t AI/UI’s doing — it’s the gateway’s. A gateway like OpenRouter or Vercel AI Gateway puts one OpenAI-compatible endpoint in front of hundreds of models and routes by id. Change model from openai/gpt-4o to x-ai/grok-2 and the same request lands on a different model. Your server route never changes:

// app/api/chat/route.ts — forward the user's chosen model to the gateway
export async function POST(req: Request) {
const { model, messages } = await req.json();
const upstream = await fetch('https://openrouter.ai/api/v1/chat/completions', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ model, messages, stream: true }),
});
// The gateway returns OpenAI-format SSE — stream it straight back to the browser.
return new Response(upstream.body, { headers: { 'Content-Type': 'text/event-stream' } });
}

On the front end, the switcher is built into <kai-chat>: set models, listen for kai-model-change, and send the current id with each request.

<kai-chat id="chat"></kai-chat>
<script type="module">
import '@kitn.ai/ui/elements';
await customElements.whenDefined('kai-chat');
const chat = document.getElementById('chat');
let model = 'openai/gpt-4o';
chat.models = [
{ id: 'openai/gpt-4o', name: 'GPT-4o', provider: 'OpenAI' },
{ id: 'x-ai/grok-2', name: 'Grok', provider: 'xAI' },
{ id: 'z-ai/glm-4.6', name: 'GLM', provider: 'Zhipu' },
{ id: 'deepseek/deepseek-chat', name: 'DeepSeek', provider: 'DeepSeek' },
];
chat.currentModel = model;
chat.addEventListener('kai-model-change', (e) => { model = e.detail.modelId; });
chat.addEventListener('kai-submit', async (e) => {
// append the user + empty assistant message, then call your route with `model`
await fetch('/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ model, messages: chat.messages }),
});
// stream the reply into messages — see the Streaming recipe
});
</script>

There are two ways to reach a model, and both run the route above unchanged.

Gateways put hundreds of models behind one OpenAI-compatible endpoint, with routing, fallbacks, and spend tracking. Swap the base URL and key; the code is identical.

GatewayBase URLExample model ids
OpenRouterhttps://openrouter.ai/api/v1openai/gpt-4o, x-ai/grok-2, z-ai/glm-4.6
Vercel AI Gatewayhttps://ai-gateway.vercel.sh/v1openai/gpt-4o, anthropic/claude-...
Cloudflare AI Gatewayper-account URLpassthrough to the upstream provider

Direct providers skip the gateway when you only need one vendor. Most ship an OpenAI-compatible endpoint, so the same route works — only the base URL, key, and id change.

ProviderOpenAI-compatible base URL
OpenAIhttps://api.openai.com/v1
xAI (Grok)https://api.x.ai/v1
Zhipu (GLM)https://open.bigmodel.cn/api/paas/v4
DeepSeekhttps://api.deepseek.com
Groqhttps://api.groq.com/openai/v1
Ollama (local)http://localhost:11434/v1
  • Connect any backend — the messages contract this builds on.
  • Streaming — the reader loop that pulls the reply into the thread.
  • Harnesses — when the backend is a full agent, not just a model.