Lesson 15: The Generated Web Chat UI

A complete browser chat client - sidebar, streaming, approvals, SQLite store.

On this page

The Generated Web Chat UI

A gateways/*.bx entry with exposes: "webui" ships a complete browser chat client for your agent - a conversation sidebar, streaming with reasoning and tool calls, human-in-the-loop approvals, per-visitor theming, and a real SQLite store behind it.

// gateways/chat.bx
class {
	function configure() {
		return {
			exposes     : "webui",
			path        : "/chat",
			apiKeyEnvVar: "CHAT_UI_API_KEY"   // optional - see "Securing it" below
		};
	}
}

This generates a static <path>/index.html (served directly, no route needed) plus a dedicated API under <path>/api. The page is dependency-free vanilla HTML/CSS/JS, pre-built and vendored inside BxAgents itself - bxAgents build never runs npm install, and a generated project never needs Node installed at all.

The generated web chat UI, branded and populated with an example conversation

That's the real, unmodified generated page - this one branded with examples/webui-agent's theme/title/icon config from Lesson 13's exposure concept, taken further. bxAgents build && bxAgents serve in that example gets you the same page for real.

What the page can do

  • Conversation sidebar - switch, rename, delete, or start a new conversation.
  • Steer while streaming - the composer stays live during a turn; Send becomes Steer, splicing your message into the run already in flight.
  • Stop - posts /cancel before aborting, so the server actually stops spending tokens rather than just abandoning the browser connection.
  • Reasoning + tool calls - collapsed disclosures fed straight off the streamed response.
  • Approvals - a human-in-the-loop pause renders an Approve/Reject card.

Without accounts: one shared workspace

By default the UI has no accounts and no gate - every visitor is anonymous, and every visitor reads and writes the same conversations, preferences and agent memory. This is the zero-ceremony local-dev experience, not a deployment posture.

Warning

An open UI has no privacy between visitors. Declare users if the page is reachable by more than the people who should see the transcripts.

users : [
    { username: "ada", passwordEnvVar: "ACME_ADA_PASSWORD", displayName: "Ada Lovelace" }
]

An account names the environment variable holding its password, or carries an already-hashed value - a literal password key is a build error, not a warning. Generate a hash with:

bxAgents hash-password --password="<your-password>"

Branding it

Every key is optional:

theme: {
	accent : "0f766e",
	radius : "10px",
	font   : "Inter, system-ui, sans-serif",
	dark   : { accent : "rgb(45, 212, 191)" }
}
Info

Write hex colors bare, with no leading # - BoxLang begins string interpolation at # in both quote styles, so the generator adds it back for you.

title, subtitle, icon, welcome, placeholder and footer are also available, plus a themeFile for anything the tokens don't cover.

Securing it

apiKeyEnvVar is a simple, toggleable gate - not a full login system. Left unset, <path>/api/* is wide open (fine for local dev). Set it, and every request under <path>/api/* must carry a matching X-API-Key header. The static shell itself is deliberately not gated, since a browser's plain page navigation can't send a custom header.

Try it

bxAgents build
bxAgents serve --port=8080

Open http://localhost:8080/chat in a browser and talk to your agent - the same one you've been building tools, skills and subagents onto since Lesson 9.

Full reference: The web chat UI.

Next: Lesson 16 - Scheduling Background Work

Edit this page Download Markdown Last updated Sep 17, 2026, 5:15:06 PM
Lesson 15 of 20 - Introduction to BxAgents