← Back to Work

// 00 / CUSTOM UI  ·  23 Mar 2026

A Custom AI
Chat Interface

StackHTML · CSS · JS
BackendOllama REST API
AccessLocal network · any device
File sizeSingle HTML file

// the idea

Beyond Open WebUI — owning the interface

Open WebUI is a capable front-end for Ollama and it served well for setting up the RAG knowledge base. But it's someone else's product — generic branding, generic layout, and no way to make it feel like something you built. The next step was to replace it entirely with a custom interface built to match the cyber-wyse aesthetic.

The goal was straightforward: a single HTML file that talks directly to the Ollama REST API, branded to match this site, and accessible from any device on the local network — no Docker, no npm, no build step. Just a file you open in a browser.

The result is exactly that. One file. Drop it anywhere. Open it. It works. And because it calls Ollama's API directly, it's as capable as any other interface — streaming responses, model switching, session history, suggested prompts — all of it custom built.

// the design

Built to match the site

The interface uses the same design language as cyber-wyse.com — the same colour palette, the same typefaces (Share Tech Mono, Syne, DM Sans), the same noise overlay and grid background, the same dark base with #00e5b4 as the primary accent. It feels like a product that belongs to this project rather than a generic tool dropped in.

cyberwyse-chat.html — welcome screen 1400 × 860
cyber-wyse custom chat UI — welcome screen
Branded header

cyber-wyse logo, model selector, live Ollama connection indicator, and new chat button — all in the site's monospace style.

Streaming responses

Text streams in as the model generates it — the same behaviour as any cloud AI product, running entirely locally.

Session history sidebar

Conversations are stored in session memory and listed in a sidebar with titles and message counts. Click any to reload it.

Suggested prompts

The welcome screen shows context-specific chips — WyseDSP RAG queries alongside general questions — to demonstrate both capabilities.

Model selector

Switch between all installed Ollama models from the header. WyseDSP Coder (DeepSeek) is the default, with Mistral, Qwen2.5, and TinyLlama available.

Zero dependencies

No frameworks, no build tools, no npm. Pure HTML, CSS, and vanilla JS. The whole thing is one file you can open directly from disk.

// how it works

Talking directly to Ollama

Ollama exposes a simple HTTP API on port 11434. The chat interface calls two endpoints — one to check which models are available, and one to stream a conversation. That's it. No middleware, no proxy, no backend code to maintain.

The streaming chat call

Each message sends the full conversation history to Ollama's /api/chat endpoint with stream: true. The response is a newline-delimited stream of JSON chunks, read with the browser's Fetch API:

streaming fetchjavascript
// Send message + full history, stream the response
const response = await fetch(`http://localhost:11434/api/chat`, {
  method: 'POST',
  body: JSON.stringify({
    model: 'deepseek-coder',
    messages: conversationHistory,
    stream: true
  })
});

const reader = response.body.getReader();
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  // Parse each JSON chunk and append to the UI
  const data = JSON.parse(decoder.decode(value));
  fullText += data.message?.content || '';
}

The model selector in the header maps display names to actual Ollama model identifiers, so "WyseDSP Coder" routes to deepseek-coder without the user needing to know the internal name.

One config line

The entire connection target lives in a single variable at the top of the file: const OLLAMA_BASE = 'http://localhost:11434'. Change this to your machine's IP and every device on the network can use it.

// network access

One file, every device on your network

This is where it gets genuinely useful. Because Ollama is bound to 0.0.0.0 (set up in the Local AI project), and because the HTML file just makes HTTP requests, any device on the same network can access the full AI setup — without installing anything.

STEP 01

Find the Ubuntu machine's IP

terminalbash
$ ip addr show | grep "inet " | grep -v 127.0.0.1
inet 192.168.1.45/24 brd 192.168.1.255 scope global
STEP 02

Update the config line in the HTML file

cyberwyse-chat.htmljavascript
// Change this one line:
const OLLAMA_BASE = 'http://192.168.1.45:11434';
STEP 03

Serve the file from the Ubuntu machine

Python's built-in HTTP server is the simplest option — no install needed:

terminalbash
$ mkdir ~/cyber-wyse-ui
# Copy cyberwyse-chat.html into that folder, then:
$ cd ~/cyber-wyse-ui && python3 -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 ...
STEP 04

Make it permanent — serve on boot

To have the server start automatically whenever the Ubuntu machine boots:

terminalbash
$ sudo nano /etc/systemd/system/cyberwyse-ui.service
cyberwyse-ui.serviceini
[Unit]
Description=cyber-wyse UI
After=network.target

[Service]
ExecStart=/usr/bin/python3 -m http.server 8080
WorkingDirectory=/home/eamon/cyber-wyse-ui
Restart=always

[Install]
WantedBy=multi-user.target
terminalbash
$ sudo systemctl enable cyberwyse-ui
$ sudo systemctl start cyberwyse-ui
Any device, any browser

MacBook, Windows PC, iPhone, iPad — anything on the same network can now open http://192.168.1.45:8080/cyberwyse-chat.html and get the full interface, backed by local AI running on the Ubuntu machine. No apps, no accounts, no internet required.

// what this demonstrates

A product, not a tool

The difference between a tool and a product is ownership. Open WebUI is a tool — useful, functional, but entirely someone else's. The custom interface is a product: it looks like it belongs to this project, it reflects deliberate design decisions, and it can be changed, extended, or handed to someone else without explanation.

It also demonstrates something more practical: you don't need a server, a deployment pipeline, or a cloud account to ship a working AI interface. A single HTML file and a repurposed laptop is enough infrastructure to give every device in a building access to a capable, private, offline AI assistant.

The Ollama REST API is simple enough that you could build this in an afternoon. The design work — getting it to feel polished, on-brand, and genuinely usable — is where the real effort went. And that's exactly the kind of work AI accelerates most effectively: moving quickly from a functional prototype to something that looks like it was made on purpose.