@prashanth2911/ui-agent
v0.1.13
Published
Chat-based UI agent components for React apps
Maintainers
Readme
UI Agent React Library
UI Agent is a lightweight React helper that turns natural-language chat prompts into UI automation intents. It detects intents, extracts entities, and executes mapped actions—like navigation, clicks, search, filtering, scrolling, resetting, editing, copying, closing, and logout—using developer-provided handlers. Drop in the provider, hook, and chat widget to give any product a practical agent experience.
Features
- Natural-language → intent+entity parsing with keyword, example, and entity definitions.
- Fuzzy-matching search index with configurable scoring thresholds plus optional suggestions.
- Config-driven action routing with sensible defaults for the core UI verbs.
- Provider + hook to wire conversations into any experience.
- Ready-made ChatWidget component with quick actions, typing indicator, reset control, and pluggable footer/empty states.
- Typed events for logging/analytics plus history limiting and optional system persona.
configureUIAgenthelper to normalize config + parser tuning so teams can stay focused on intents, not boilerplate.
Installation
npm install ui-agent
# or: pnpm add ui-agentThis package expects React 18+ as a peer dependency.
Quick start
import {
UIAgentProvider,
ChatWidget,
configureUIAgent,
} from "ui-agent";
const agentConfig = configureUIAgent({
systemPrompt: "You help operators drive the dashboard safely.",
historyLimit: 20,
defaultResponse: "I couldn't map that yet—try a clearer command.",
typingDelayMs: 450,
parserOptions: {
minScore: 0.45,
fuzzyThreshold: 0.62,
},
suggestionOptions: {
limit: 6,
debounceMs: 150,
},
intents: [
{
id: "nav.dashboard",
label: "Go to dashboard",
keywords: ["dashboard", "home"],
examples: ["take me to the dashboard", "open home"],
actions: [
{
type: "navigate",
params: { target: "/dashboard" },
},
],
},
{
id: "filter.status",
label: "Filter by status",
keywords: ["filter", "show", "only"],
entities: [
{
name: "status",
sampleValues: ["open", "closed", "in progress"],
patterns: ["status (?:is|equals) (\\w+)"],
},
],
actions: [
{
type: "filter",
params: { field: "status" },
},
],
},
],
actionHandlers: {
navigate: async ({ action }) => {
// route via your router of choice
router.push(String(action.params?.target));
return { success: true, response: "Heading there now." };
},
filter: async ({ entities, action }) => {
const value = entities.status ?? action.params?.value;
applyFilter(String(action.params?.field), value);
return { success: true, response: `Filtering by ${value}.` };
},
},
});
export function SupportAgent() {
return (
<UIAgentProvider config={agentConfig}>
<ChatWidget
title="Assistant"
quickActions={[
{ label: "Go home", prompt: "Open the dashboard" },
{ label: "Show pending", prompt: "Filter to pending items" },
]}
/>
</UIAgentProvider>
);
}Floating assistant
Drop the chat experience into any page without touching your layout by using the floating launcher:
import {
UIAgentProvider,
FloatingChatWidget,
configureUIAgent,
} from "ui-agent";
const agentConfig = configureUIAgent({ /* ... */ });
export function FloatingSupportAgent() {
return (
<UIAgentProvider config={agentConfig}>
<FloatingChatWidget
title="Assistant"
buttonLabel="Need help?"
buttonIcon={<span role="img" aria-label="chat">💬</span>}
quickActions={[
{ label: "Reset filters", prompt: "reset filters" },
{ label: "Open billing", prompt: "go to billing settings" },
]}
/>
</UIAgentProvider>
);
}FloatingChatWidget renders a portal anchored to the bottom-right corner (switch to bottom-left via position="bottom-left"), hides the launcher while the panel is open, and mirrors the launcher's buttonIcon inside the chat header through the shared titleIcon prop. It exposes the same props as ChatWidget and ships with a dedicated close toolbar. Use portalContainer if you need to mount inside a shadow root or specific DOM node.
Need a single-surface look? FloatingChatWidget automatically renders ChatWidget in frameless mode so you don't see duplicate borders. You can also set frameless on a standalone ChatWidget if you embed it inside your own cards:
<ChatWidget frameless title="Inline assistant" />Config anatomy
intents: core mapping definition. Provide keywords, short examples, entity definitions, and the ordered actions to execute.actionHandlers: supply concrete side effects for each action type. Defaults emit descriptive confirmations if you want to get started without wiring everything yet.historyLimit: trims chat history while preserving the optional system prompt.typingDelayMs: adds natural response latency; set to0to disable.onEvent: receivemessage,intent:matched,action:executed, anderrorevents for logging or analytics.parserOptions: tune scoring withminScore,maxSuggestions, andfuzzyThreshold(default fuzzy matching is on for intent discovery).suggestionOptions: configure the auto-suggestion engine (limit, debounce, or custom provider) powering the chat widget hints.
Configuration helper
configureUIAgent(config) merges sensible defaults (history size, typing delay, parser options) so you can provide the minimal shape and still get optimal performance. It returns the normalized config that you pass straight into UIAgentProvider.
Intent tips
- Use 3–5 high-signal keywords and a couple of example utterances per intent to boost scoring accuracy.
- Attach
entitieswithpatterns,sampleValues, or a customextractfunction for advanced parsing. The entity values are injected into theentitiesobject that action handlers receive. - Chain multiple
actionsinside one intent to do things likescrollthenclick, orsearchfollowed byfilter.
Using the hook directly
import { useUIAgent } from "ui-agent";
function VoiceButton() {
const { sendMessage, status } = useUIAgent();
const handleCommand = (command: string) => {
sendMessage(command);
};
return (
<button onClick={() => handleCommand("log me out")}>
{status === "thinking" ? "Working…" : "Voice logout"}
</button>
);
}Development scripts
npm run build– bundle the library with tsup (CJS + ESM + types).npm run dev– watch mode.npm run typecheck– TypeScript only.
Practical scenarios to test
- Multistep UI flows (e.g., “scroll down and open billing settings”).
- State-changing actions with entity extraction (“filter to open invoices created today”).
- Recovery prompts (“reset filters”, “close this modal”, “log me out”).
- Data entry/edit operations (“edit customer email to ...”, “copy the order ID”).
Model the above in your configuration to give the agent contextually rich intents that tie directly into your product workflow. The library handles the chat plumbing so you can focus on meaningful actions.
Action types & example scenarios
navigate: route to dashboards, tabs, or modal contexts (/settings/billing, “jump to analytics view”).click: trigger specific buttons, CTA elements, or icon toggles (“click the publish button”, “dismiss alert banner”).filter: apply grid/list filters like status, owner, date ranges, priority, or tags.search: run global or scoped searches (“search for invoices over $10k”, “find user Sierra”).scroll: move around long forms or feeds (“scroll to the comments section”, “scroll down a little more”).reset: clear filters, form state, or revert panels to defaults (“reset filters”, “clear this form”).edit: update fields, patch records, rename items, or change inputs (“set due date to Friday”, “rename project to Atlas”).copy: copy IDs, summaries, shareable links, or status updates to the clipboard.close: shut dialogs, modals, drawers, or contextual panels (“close the activity drawer”).logout: trigger auth sign-out or session termination flows.refresh: re-fetch dashboards or data blocks (“refresh campaign metrics”).expand/collapse: open or close accordions and panels (“expand billing details”, “collapse sidebar”).openModal: launch modal workflows (“open the share modal”).toggle: flip feature switches/modes (“toggle compact view”).favorite: star/bookmark items (“favorite this report”).assign: change ownership or watchers (“assign this bug to Priya”).duplicate: clone templates or records (“duplicate the Q2 campaign”).export: kick off CSV/PDF exports (“export filtered list to CSV”).notify: send alerts or messages (“notify support about this outage”).upload: start file import flows (“upload the signed contract”).
Use these primitives singly or in sequence per intent to cover most chat-controlled UI maneuvers without proliferating handler types.
Auto suggestions
- The chat widget now surfaces VS Code-style inline intent hints: as you type, a faint completion appears inline and
Tabaccepts it while keeping your cursor in place (Enterstill sends). - Customize suggestion behavior with
suggestionOptions:limit(default5) controls how many intents to evaluate for inline hints (the best match is shown).debounceMs(default180ms) defines how quickly the helper refreshes.providerlets you override suggestion labels and prompts using your own ranking logic.
- Disable in any widget via
enableSuggestions={false}or rename the inline helper label withsuggestionTitle="Actions"to match your UX copy.
