═══════════════════════════════════════════════════════════════════════
@bytelyst/ai-ui bump 0.1.0 → 0.4.0
═══════════════════════════════════════════════════════════════════════
Folds three more roadmap milestones into the flagship package.
0.2: <ToolCallCard> — disclosure card; status pill, JSON preview
<CitationChip> — inline citation marker + hover preview
useToolCalls() — per-turn tool-invocation state machine
(begin/update/settle/clear); preserves insertion
order across updates; auto-computes durationMs
0.3: <AgentTimeline> — vertical think→act→observe→respond trace;
embeds ToolCallCard for kind='tool_call' steps
<ModelPicker> — model dropdown with capability chips, cost,
latency, context window, disabled gating
0.4: <ToolPalette> — searchable tool list with MCP-style discovery
(source can be ToolDescriptor[] OR an
'mcp://...' URL resolved via a discover
adapter; default adapter is fetch+JSON)
Types extended:
- ToolInvocation, ToolCallStatus, Citation added
- Message gains optional toolInvocations + citations
Tests: 53/53 (27 old + 26 new) · typecheck clean · 7.65 KB / 35 KB
═══════════════════════════════════════════════════════════════════════
NEW PACKAGE: @bytelyst/command-palette@0.1.0
═══════════════════════════════════════════════════════════════════════
Wave 3 deliverable — Cmd-K dialog with three modes and pluggable command
registration. Roadmap §Wave 3 of ROADMAP_2026.md.
What's exported:
<CommandRegistryProvider> — wrap your app once
<CommandPalette> — the dialog (Cmd-K / Ctrl-K)
useRegisterCommands() — contribute commands for component lifetime
useCommands() — read snapshot
useCommandRegistry() — imperative access
useCommandPalette() — open/close state + global hotkey
fuzzyScore / scoreCommand — exposed for tests + custom UIs
Three modes:
actions — invoke a registered run()
navigate — jump to href via onNavigate or window.location
ask-ai — host-supplied askAiPanel; default renders an 'Ask AI: <q>'
suggestion that products can wire to <ChatStream>
Keyboard:
↑ ↓ navigate selection
Enter activate
Tab cycle mode tabs (Shift+Tab reverses)
Esc close
Niceties:
- Fuzzy matcher (substring + subsequence with light scoring)
- localStorage-backed recents float to top of actions mode
- requires() gate hides commands wholesale (auth / feature-flag)
- aria-haspopup, role=dialog, role=listbox, role=option, aria-selected
- Backdrop click closes; Esc handler at document level
- Hotkey suppressed by Cmd-K / Ctrl-K default; configurable
Tests: 26/26 · typecheck clean · 3.91 KB / 15 KB
═══════════════════════════════════════════════════════════════════════
CI plumbing
═══════════════════════════════════════════════════════════════════════
- .size-limit.cjs gains @bytelyst/command-palette entry
- .gitea/workflows/size-limit.yml build filter expanded
- All 8 measured packages comfortably under budget
Refs:
learning_ai_uxui_web/docs/ROADMAP_2026.md §Wave 2 (0.2/0.3/0.4)
learning_ai_uxui_web/docs/ROADMAP_2026.md §Wave 3 (Command palette)
docs/ROADMAP_2026_DECISIONS.md §10 (Vercel AI SDK shape continues)
|
||
|---|---|---|
| .. | ||
| src | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| vitest.config.ts | ||
@bytelyst/ai-ui
AI-native UI primitives for ByteLyst products. The flagship deliverable
of Wave 2 in learning_ai_uxui_web/docs/ROADMAP_2026.md.
Status:
0.1.0MVP — 3 components + 1 hook + 1 utility. Subsequent 0.x bumps add<ToolCallCard>,<CitationChip>,<AgentTimeline>,<ModelPicker>,<ToolPalette>, and theuseToolCalls/usePromptHistory/useTokenCounthooks.
Quick start
import { ChatStream } from '@bytelyst/ai-ui';
export function ChatPage() {
return (
<div style={{ height: '70vh' }}>
<ChatStream
endpoint="/api/chat"
placeholder="Ask anything…"
emptyState={<EmptyHint />}
/>
</div>
);
}
Architectural decisions
Per learning_ai_common_plat/docs/ROADMAP_2026_DECISIONS.md:
- §10 hook shape —
useChat()returns the same shape as Vercel AI SDK'suseChat. Drop-in compatible for any engineer who has already written a chat UI with the AI SDK. - Transport is pluggable — products inject
endpoint,streamProtocol,fetcher, orheaders. We are not locked to Vercel's SSE wire format.
Components
<ChatStream>
Opinionated composition of useChat + <MessageBubble> +
<PromptComposer>. Auto-scrolls (sticky-bottom), shows Stop while
streaming, surfaces transport errors inline.
<MessageBubble>
Single chat message atom. Variants by role (user / assistant / system /
tool). Built-in "thinking" indicator while streaming with no content
yet. Honors --bl-* design tokens.
<PromptComposer>
Multi-line input. Enter submits, Shift+Enter newlines, Cmd/Ctrl+Enter
alternates submit. Auto-grows up to maxLines. Slot for leading
actions (slash-commands etc.).
Hooks
useChat(options?)
Vercel-AI-SDK-shaped:
const {
messages, input, setInput, handleInputChange, handleSubmit,
append, isLoading, error, stop, reload, setMessages
} = useChat({
endpoint: '/api/chat',
streamProtocol: 'text', // 'text' | 'sse' | 'data'
initialMessages: [],
onFinish: (msg) => console.log('done', msg),
onError: (err) => console.error(err),
});
streamText(response, protocol?, signal?)
Low-level async generator that yields text deltas from a streaming
HTTP response. Supports 'text', 'sse', and 'data' protocols.
Wire protocols
| Protocol | Body format | Use when |
|---|---|---|
'text' (default) |
Plain text, streamed chunk-by-chunk | Any backend that pipes an LLM stream directly |
'sse' |
Server-Sent Events with data: ... frames |
OpenAI-compatible, Anthropic, most HF inference |
'data' |
Vercel AI SDK "data stream" prefix protocol | Backends using streamText() from ai/server |
For tool calls / citations / images, use 'sse' or 'data' once the
matching components ship in 0.2.x.
Tests
pnpm --filter @bytelyst/ai-ui test
Roadmap
0.2.0—<ToolCallCard>,<CitationChip>,useToolCalls()0.3.0—<AgentTimeline>,<ModelPicker>0.4.0—<ToolPalette>with MCP discovery0.5.0—<Markdown>+<CodeDiff>(Wave 2 stretch)1.0.0— API freeze when 3+ products consume in production