Omni UI

Hex.pmLicenseBuild Status

Agent chat UI for Elixir — a ready-made LiveView interface for exploring, prototyping, and experimenting with Omni Agent powered agents.

Omni UI

Features

Installation

Add Omni UI to your dependencies:

def deps do
[
{:omni_ui, "~> 0.1"}
]
end

Omni UI depends on omni, which provides the LLM API layer. Configure your provider API keys as described in the Omni README.

Requirements

Omni UI uses colocated CSS and JavaScript (extracted at compile time by the :phoenix_live_view compiler). This requires:

New Phoenix applications generated from 1.8.8 onwards are ready out of the box.

Assets

Omni UI ships its CSS and JavaScript as colocated assets — no static files to copy. Your application imports them from the phoenix-colocated build output.

In your CSS entry point, import the colocated stylesheet and add a @source directive so Tailwind can scan the component templates:

/* assets/css/app.css */
@import "phoenix-colocated/omni_ui/colocated.css";
@source "../../deps/omni_ui/lib";

In your JavaScript entry point, import the colocated hooks and spread them into your LiveSocket:

// assets/js/app.js
import {hooks as omniHooks} from "phoenix-colocated/omni_ui"
const liveSocket = new LiveSocket("/live", Socket, {
hooks: {...omniHooks},
// ...
})

Both require your bundler's module resolution to include Mix.Project.build_path(). For esbuild and Tailwind, this is configured via the NODE_PATH environment variable, which is the default for Phoenix 1.8+ applications.

The CSS defines OKLCH semantic colour tokens (--color-omni-bg, --color-omni-text, --color-omni-accent-1, etc.) with light and dark variants. Override any token in your own CSS to match your application's palette.

Syntax highlighting

Omni UI uses mdex for Markdown rendering with syntax highlighting powered by lumis. Enable it in your application config:

# config/config.exs
config :mdex_native, syntax_highlighter: :lumis

Quick start

The fastest way to see Omni running in your app. Mount the built-in AgentLive, add the session manager to your supervision tree, and you're done.

1. Configure

# config/config.exs
config :mdex_native, syntax_highlighter: :lumis
config :omni_ui, Omni.UI.Sessions,
store: {Omni.Session.Stores.FileSystem, base_dir: "priv/sessions"},
title_generator: {:anthropic, "claude-haiku-4-5"}
config :omni_ui, Omni.UI.AgentLive,
providers: [:anthropic],
default_model: {:anthropic, "claude-sonnet-4-6"}

2. Add it to your supervision tree

# application.ex
children = [
# ... your other children
Omni.UI.Sessions,
]

3. Mount in your router

# router.ex
scope "/" do
pipe_through :browser
live "/", Omni.UI.AgentLive
end
forward "/omni_files", Omni.UI.Files.Plug

Start your server and open the browser — you have a working agent chat with sessions, files, REPL, and web tools.

Build your own

When you want full control over the layout, tools, or event handling, skip AgentLive and use Omni.UI in your own LiveView. The macro injects session streaming, state management, and event routing — you bring the template and any custom behaviour.

defmodule MyAppWeb.ChatLive do
use Phoenix.LiveView
use Omni.UI
def render(assigns) do
~H"""
<.chat_interface>
<.turn_list stream={@streams.turns} tool_components={@tool_components} />
<.turn :if={@current_turn} turn={@current_turn} tool_components={@tool_components} />
<:editor>
<.editor model={@model} />
</:editor>
</.chat_interface>
"""
end
def mount(_params, _session, socket) do
{:ok, init_session(socket, model: {:anthropic, "claude-sonnet-4-6"})}
end
def handle_params(params, _uri, socket) do
{:noreply, attach_session(socket, id: params["session_id"])}
end
end

See the Omni.UI module documentation for the full API — session lifecycle, custom agents, tool components, configuration, and the session_event callback.

Documentation

Full API reference is available on HexDocs.

License

This package is open source and released under the Apache-2 License.

© Copyright 2026 Push Code Ltd.