@fleetx_io/ai-ui-dsl
v1.0.3
Published
A Domain Specific Language for describing rich, streaming AI chat interfaces via composable Blocks.
Maintainers
Readme
@fleetx_io/ai-ui-dsl
FleetX AI UI DSL — a domain-specific language for block-based, streaming AI chat UIs. Assistant replies are a Message made of an ordered list of Blocks (text, charts, tables, maps, forms, actions, tools, etc.), updated through a small streaming protocol.
This npm package ships TypeScript types and pure reducers (messageReducer, applyDelta, …). It is framework-agnostic (no React/Vue).
Install
npm install @fleetx_io/ai-ui-dslCore ideas
- Block composition — One message = a flat list of blocks; blocks are not nested.
- Incremental streaming — Each block follows
block_start → block_delta (0..N) → block_end(orblock_error). - Immutable reducers — Feed
StreamEvents intomessageReducer; render the resultingMessage. - IDs and logical streams —
idis assigned by the streaming engine for each block (and used in deltas / end / error events). OptionalstreamKeyis set by the UI Composer Agent so the engine can treat a laterblock_startwith the same key as continuing one logical stream instead of a new list entry. The bundledmessageReducerignoresstreamKeyand always appends onblock_start.
Server → client flow
message_start → create / bind Message
block_start → append Block (status streaming); or engine coalesces by streamKey
block_delta → applyDelta → re-render
block_end → mark Block completed
…
message_end → mark Message completedBlock types (summary)
| Block | type | Typical streaming |
| --------------- | ------------- | ------------------------------------------ |
| Text | text | text_delta (append to content) |
| Chart | chart | json_patch on Highcharts config |
| Table | table | json_patch (e.g. rows) |
| Form | form | Often static at start; optional json_patch |
| Action | action | Static |
| Widget | widget | html_delta (sandboxed HTML) |
| Tool use/result | tool_use / tool_result | input_json_delta / json_patch |
| Step | step | json_patch on steps |
| Loading | loading | loading_message |
| Error | error | Static |
| Map | map | json_patch markers, polylines, polygons |
| Download file | download_file | Static |
Streaming protocol (summary)
Events: message_start, block_start, block_delta, block_end, block_error, message_end (includes messageId).
Deltas: text_delta, input_json_delta, json_patch, html_delta, status_delta, loading_message. Which block uses which delta is summarized in the table above.
Usage
import {
createEmptyMessage,
messageReducer,
type StreamEvent,
} from '@fleetx_io/ai-ui-dsl';
let message = createEmptyMessage();
for await (const event of streamEvents) {
message = messageReducer(message, event);
// renderMessage(message);
}Synchronous replay:
const events: StreamEvent[] = [
{ type: 'message_start', message: { id: 'm1', role: 'assistant' } },
{ type: 'block_start', block: { id: 'b1', type: 'text', content: '' } },
{ type: 'block_delta', blockId: 'b1', delta: { type: 'text_delta', text: 'Hi' } },
{ type: 'block_end', blockId: 'b1' },
{ type: 'message_end', messageId: 'm1' },
];
for (const event of events) {
message = messageReducer(message, event);
}Package exports
The package is ESM-only ("type": "module"): use import in Node 20+ or bundlers (e.g. Vite). Plain CommonJS require() is not supported.
Types: Block, block variants, Message, Conversation, Delta, StreamEvent, streaming callbacks, etc.
Functions: messageReducer, applyDelta, createEmptyMessage, setByPath, and isBlockType.
UI Composer Agent (concept)
A UI Composer Agent is an LLM layer that does not call tools: it takes tool results plus context and returns { blocks: Block[] } in this DSL. An orchestrator then turns those blocks into an SSE stream (block_start, deltas, block_end) for the client. Composition heuristics (e.g. open with a short text block, use charts or maps instead of raw JSON in prose, end with suggested actions) are up to your server-side prompt and validation schema.
License
ISC.
