npm package: @prashanth2911/ui-agent
Description: Chat-based UI agent components for React apps
Latest version: 0.1.13

## 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.
- `configureUIAgent` helper to normalize config + parser tuning so teams can stay focused on intents, not boilerplate.

### Installation

```bash
npm install ui-agent
# or: pnpm add ui-agent
```

This package expects React 18+ as a peer dependency.

### Quick start

```tsx
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:

```tsx
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:

```tsx
<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 to `0` to disable.
- `onEvent`: receive `message`, `intent:matched`, `action:executed`, and `error` events for logging or analytics.
- `parserOptions`: tune scoring with `minScore`, `maxSuggestions`, and `fuzzyThreshold` (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 `entities` with `patterns`, `sampleValues`, or a custom `extract` function for advanced parsing. The entity values are injected into the `entities` object that action handlers receive.
- Chain multiple `actions` inside one intent to do things like `scroll` then `click`, or `search` followed by `filter`.

### Using the hook directly

```tsx
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 `Tab` accepts it while keeping your cursor in place (`Enter` still sends).
- Customize suggestion behavior with `suggestionOptions`:
  - `limit` (default `5`) controls how many intents to evaluate for inline hints (the best match is shown).
  - `debounceMs` (default `180ms`) defines how quickly the helper refreshes.
  - `provider` lets you override suggestion labels and prompts using your own ranking logic.
- Disable in any widget via `enableSuggestions={false}` or rename the inline helper label with `suggestionTitle="Actions"` to match your UX copy.