learning_ai_common_plat/packages/ai-ui
saravanakumardb1 e2eea086dc feat(packages): Wave 2 v0.4 + Wave 3 v0.1 — ai-ui expanded, command-palette new
═══════════════════════════════════════════════════════════════════════
@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)
2026-05-27 12:43:23 -07:00
..
src feat(packages): Wave 2 v0.4 + Wave 3 v0.1 — ai-ui expanded, command-palette new 2026-05-27 12:43:23 -07:00
package.json feat(packages): Wave 2 v0.4 + Wave 3 v0.1 — ai-ui expanded, command-palette new 2026-05-27 12:43:23 -07:00
README.md feat(ai-ui): Wave 2 MVP @bytelyst/ai-ui@0.1.0 2026-05-27 12:07:23 -07:00
tsconfig.json feat(ai-ui): Wave 2 MVP @bytelyst/ai-ui@0.1.0 2026-05-27 12:07:23 -07:00
vitest.config.ts feat(ai-ui): Wave 2 MVP @bytelyst/ai-ui@0.1.0 2026-05-27 12:07:23 -07:00

@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.0 MVP — 3 components + 1 hook + 1 utility. Subsequent 0.x bumps add <ToolCallCard>, <CitationChip>, <AgentTimeline>, <ModelPicker>, <ToolPalette>, and the useToolCalls / usePromptHistory / useTokenCount hooks.

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 shapeuseChat() returns the same shape as Vercel AI SDK's useChat. 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, or headers. 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 discovery
  • 0.5.0<Markdown> + <CodeDiff> (Wave 2 stretch)
  • 1.0.0 — API freeze when 3+ products consume in production