Airsc is free for everyone. If it helps you, support it with $2–$20.

Support
SkillSafeUI & designSome setup

UIX

Deepractice · Deepractice/UIX

UIX provides an AI-to-UI protocol and conversion engine to normalize AI output into a consistent format for any UI framework.

AI-to-UI IR Protocol Layer — The Last Mile from AI to Human. Includes Lucid UI Skill for professional AI-generated interfaces.

10 stars0License: MITUpdated 7 months ago0 opens

Preview

▍

What you can do with it

  • Build a chat interface that can display AI outputs from different LLM providers consistently.
  • Develop UI components that automatically adapt to various AI-generated content formats.
  • Ensure UI designs generated by AI agents adhere to a unified design system.

Safety check

Safe

No risky patterns found in the files we scanned.

Automated scan of the repo files. Always review code you run.

From the README

UIX

<strong>The Last Mile from AI to Human</strong>


AI-to-UI Intermediate Representation (IR) Protocol & Conversion Engine










<strong>English</strong> |
简体中文

What UIX Is (and What It Is Not)

UIX is a protocol layer and conversion engine, not a Chat UI framework.

If you need a full-featured React chat interface, use assistant-ui — it's excellent and battle-tested. UIX solves a different problem: normalizing AI output from any source into a single, stable format.

                      ┌─────────────────────────┐
Vercel AI SDK ──────→ │                         │
AgentX ─────────────→ │   UIX IR                │ ──→ assistant-ui
AG-UI (CopilotKit) ─→ │   (unified format)      │ ──→ your own renderer
A2UI (Google) ──────→ │                         │ ──→ any UI framework
                      └─────────────────────────┘

Think of UIX as Babel for AI output — Babel normalizes JavaScript across engines; UIX normalizes AI output across providers.


The Problem

AI backends all speak different formats:

SourceMessage FormatTool Call FormatStreaming Protocol
Vercel AI SDKUIMessage.parts[]ToolInvocationPartData Stream
AgentXConversation.blocks[]ToolBlockWebSocket events
AG-UI (CopilotKit)AG-UI eventsToolCallStart/EndSSE events
A2UI (Google)Declarative UI payloadComponent-basedgRPC stream

If you build a chat UI, you're locked into one format. Switch backends? Rewrite your UI layer.

UIX IR eliminates this coupling. Your UI only knows LucidConversation and LucidBlock — adapters handle the rest.


Architecture

┌─────────────────────────────────────────────────────────────────┐
│  AI Backends (upstream)                                         │
│  Vercel AI SDK · AgentX · AG-UI · A2UI · LangChain · ...        │
└──────────────────────────┬──────────────────────────────────────┘
                           │
                    UIX Adapters (ACL)
                    Pure functions, zero side effects
                           │
                           ▼
┌─────────────────────────────────────────────────────────────────┐
│  UIX IR  (@uix-ai/core)                                         │
│  LucidConversation → LucidBlock[]                               │
│  7 block types: text · tool · thinking · image · file · error · │
│  source                                                         │
│  JSON Schema + TypeScript types + type guards                   │
└──────────────────────────┬──────────────────────────────────────┘
                           │
               ┌───────────┴───────────┐
               ▼                       ▼
┌──────────────────────┐  ┌──────────────────────────────────────┐
│  assistant-ui        │  │  UIX Reference Renderer              │
│  (recommended)       │  │  @uix-ai/stream (StreamMarkdown)     │
│  Full chat UI runtime│  │  @uix-ai/agent (ChatBubble, etc.)    │
│  via ExternalStore   │  │  Lightweight, zero-runtime           │
└──────────────────────┘  └──────────────────────────────────────┘

Why Adapters Instead of Direct Integration?

In DDD terms, each AI backend is a separate Bounded Context. UIX adapters are the Anti-Corruption Layer (ACL) — the downstream consumer (UI) protects itself from upstream format changes.

  • Upstream (AgentX, Vercel, etc.) owns its own types — no pressure to change
  • Downstream (UI) only depends on UIX IR — immune to backend switches
  • Adapters are pure functions: fromX(input) → LucidConversation[]

UIX IR Specification

Core Types

interface LucidConversation {
  id: string
  role: 'user' | 'assistant' | 'system'
  status: 'streaming' | 'completed' | 'error'
  blocks: LucidBlock[]
  timestamp: number
}

interface LucidBlock<T extends BlockType> {
  id: string
  type: T  // 'text' | 'tool' | 'thinking' | 'image' | 'file' | 'error' | 'source'
  status: 'streaming' | 'completed' | 'error'
  content: ContentByType<T>  // conditional type, inferred from T
}

Block Types

TypeDescriptionContent
textText content (supports streaming){ text: string }
toolTool/function call{ name, input, output, status } — 9-state lifecycle
thinkingAI reasoning process{ reasoning: string }
imageImage content{ url, alt, width, height }
fileFile attachment{ name, type, url, size }
errorError message{ code, message, details }
sourceSource citation{ sourceId, title, url, excerpt }

Tool Lifecycle (9 states)

pending → streaming → ready → running → success
                                ↓
                        approval-required → approved → success
                                         → denied
                                ↓
                               error

Packages

Core (the value)

PackageDescriptionStatus
@uix-ai/coreUIX IR types, JSON Schema, type guards✅ v0.0.2

Adapters (the bridge)

PackageConverts FromStatus
@uix-ai/adapter-vercelVercel AI SDK 4.x / 6.x✅ v0.0.2
@uix-ai/adapter-aguiAG-UI protocol (CopilotKit)🚧 Alpha
@uix-ai/adapter-a2uiA2UI protocol (Google)🧪 Experimental
@uix-ai/adapter-agentxAgentX Presentation🔜 Planned

Reference Renderers (optional)

These are not the core value of UIX. They are lightweight reference implementations. For production chat UI, we recommend assistant-ui.

PackageDescriptionStatus
@uix-ai/streamStreaming Markdown renderer (Streamdown + Shiki
View source on GitHub