New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@rodgerai/ui

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@rodgerai/ui

React UI components for Rodger.ai agents

latest
npmnpm
Version
2.0.4
Version published
Maintainers
1
Created
Source

@rodger/ui

Beautiful, customizable React components for building AI chat interfaces powered by Rodger.ai agents.

Features

  • Pre-built Chat UI - Thread, messages, composer components
  • useRodgerChat Hook - Simple integration with backend agents
  • Widget System - Extensible tool result rendering
  • Built on assistant-ui - Leverage the powerful assistant-ui primitives
  • TypeScript-First - Full type safety and IntelliSense
  • Tailwind Styled - Easy customization with Tailwind CSS
  • Animated - Smooth animations with Motion

Installation

npm install @rodger/ui @rodger/core
# or
pnpm add @rodger/ui @rodger/core

Peer Dependencies

This package requires:

{
  "react": "^18.0.0 || ^19.0.0",
  "react-dom": "^18.0.0 || ^19.0.0",
  "@assistant-ui/react": "^0.11.0",
  "@assistant-ui/react-ai-sdk": "^1.1.0"
}

These will be automatically installed if not present.

Quick Start

1. Set Up Your Backend API

Create an API route that uses @rodger/core:

// app/api/chat/route.ts
import { createAgent } from '@rodger/core';
import { streamText } from 'ai';

const agent = createAgent({
  name: 'Chat Agent',
  llm: { provider: 'openai', model: 'gpt-4o' },
  systemPrompt: 'You are a helpful assistant.'
});

export async function POST(req: Request) {
  const { messages, sessionId } = await req.json();
  const userMessage = messages[messages.length - 1].content;

  // Stream response from agent
  const response = await agent.chat(userMessage, { sessionId });

  return streamText({
    text: response.text
  });
}

2. Build Your Chat UI

'use client';

import { RodgerProvider, Thread, useRodgerChat } from '@rodger/ui';

export default function ChatPage() {
  const { runtime, isLoadingHistory } = useRodgerChat({
    endpoint: '/api/chat',
    sessionId: 'user-session-123'
  });

  if (isLoadingHistory) {
    return <div>Loading conversation...</div>;
  }

  return (
    <RodgerProvider runtime={runtime}>
      <div className="h-screen">
        <Thread
          welcomeMessage={
            <div>
              <h1 className="text-4xl font-bold">Welcome!</h1>
              <p className="text-muted-foreground">How can I help you today?</p>
            </div>
          }
          suggestions={[
            { title: 'Weather', label: 'Get the weather', action: 'What is the weather?' },
            { title: 'Joke', label: 'Tell me a joke', action: 'Tell me a joke' }
          ]}
          placeholder="Ask me anything..."
        />
      </div>
    </RodgerProvider>
  );
}

That's it! You now have a fully functional chat interface.

Core Components

Thread

Main chat interface displaying messages and composer.

import { Thread } from '@rodger/ui';

<Thread
  // Optional: Custom welcome message
  welcomeMessage={<CustomWelcome />}

  // Optional: Suggested prompts
  suggestions={[
    {
      title: 'Quick Start',
      label: 'Get started',
      action: 'Help me get started'
    }
  ]}

  // Optional: Custom placeholder
  placeholder="Send a message..."

  // Optional: Custom widgets for tool results
  widgets={{
    myTool: MyCustomWidget
  }}

  // Optional: Custom CSS classes
  className="custom-thread"
/>

Props:

  • welcomeMessage (ReactNode) - Custom welcome screen content
  • suggestions (Suggestion[]) - Suggestion chips for quick actions
  • placeholder (string) - Input placeholder text
  • widgets (Record<string, FC>) - Custom widgets for tool results
  • className (string) - Additional CSS classes

RodgerProvider

Context provider that wraps your chat UI.

import { RodgerProvider } from '@rodger/ui';

<RodgerProvider runtime={runtime}>
  {/* Your chat UI components */}
  <Thread />
</RodgerProvider>

Props:

  • runtime (AssistantRuntime) - Runtime from useRodgerChat
  • children (ReactNode) - Child components

Features:

  • Provides runtime context to all child components
  • Built-in error boundary for runtime errors
  • Handles runtime lifecycle automatically

Hooks

useRodgerChat

Primary hook for connecting to your backend agent.

import { useRodgerChat } from '@rodger/ui';

const { runtime, isLoadingHistory } = useRodgerChat({
  // Required: API endpoint
  endpoint: '/api/chat',

  // Required: Session identifier
  sessionId: 'user-123',

  // Optional: Additional request body params
  body: {
    maxSteps: 10,
    temperature: 0.7
  },

  // Optional: Lifecycle callbacks
  onBeforeRun: (input) => {
    console.log('User sent:', input);
  },
  onAfterRun: (output) => {
    console.log('Agent replied:', output);
  }
});

Options:

  • endpoint (string) - API route for chat
  • sessionId (string) - Unique session ID for conversation history
  • body (object, optional) - Additional parameters sent with each request
  • onBeforeRun (function, optional) - Called before agent processes input
  • onAfterRun (function, optional) - Called after agent responds

Returns:

  • runtime (AssistantRuntime) - Runtime instance for RodgerProvider
  • isLoadingHistory (boolean) - Loading state for message history

Features:

  • Automatic message history loading from {endpoint}/history
  • AssistantChatTransport configuration
  • Lifecycle hooks for monitoring
  • Session-based conversation management

useChat

Low-level hook for direct assistant-ui integration.

import { useChat } from '@rodger/ui';

const { messages, append, isLoading } = useChat({
  api: '/api/chat'
});

See @assistant-ui/react documentation for full details.

Custom Widgets

Widgets render tool results with custom UI components.

Creating a Widget

// components/WeatherWidget.tsx
import { makeAssistantToolUI } from '@assistant-ui/react';

export const WeatherWidget = makeAssistantToolUI({
  toolName: 'getWeather',
  render: ({ result }) => {
    const weather = result as { temp: number; condition: string };

    return (
      <div className="p-4 bg-blue-50 rounded-lg">
        <h3 className="font-bold">Weather</h3>
        <p>Temperature: {weather.temp}°F</p>
        <p>Condition: {weather.condition}</p>
      </div>
    );
  }
});

Registering Widgets

Pass widgets to the Thread component:

import { Thread } from '@rodger/ui';
import { WeatherWidget } from './components/WeatherWidget';
import { CartBuilderUI } from '@rodger/widgets';

<Thread
  widgets={{
    getWeather: WeatherWidget,
    cartBuilder: CartBuilderUI
  }}
/>

Now when your agent uses these tools, the custom widgets will render the results!

Widget Best Practices

  • Type Safety - Use TypeScript for tool result types:
interface WeatherResult {
  temp: number;
  condition: string;
  location: string;
}

render: ({ result }) => {
  const weather = result as WeatherResult;
  // Now you have full type safety
}
  • Error Handling - Handle missing or malformed data:
render: ({ result }) => {
  if (!result || typeof result !== 'object') {
    return <div>Invalid weather data</div>;
  }
  // Render normally
}
  • Loading States - Show loading indicators:
render: ({ result, status }) => {
  if (status === 'loading') {
    return <div>Loading weather...</div>;
  }
  // Render result
}

Styling and Theming

Tailwind Configuration

Add @rodger/ui to your Tailwind config:

// tailwind.config.js
module.exports = {
  content: [
    './app/**/*.{js,ts,jsx,tsx}',
    './node_modules/@rodger/ui/dist/**/*.{js,mjs}'
  ],
  theme: {
    extend: {
      colors: {
        background: 'hsl(var(--background))',
        foreground: 'hsl(var(--foreground))',
        primary: 'hsl(var(--primary))',
        'muted-foreground': 'hsl(var(--muted-foreground))',
        border: 'hsl(var(--border))',
        accent: 'hsl(var(--accent))'
      }
    }
  }
};

CSS Variables

Define your theme colors:

/* app/globals.css */
:root {
  --background: 0 0% 100%;
  --foreground: 222.2 84% 4.9%;
  --primary: 221.2 83.2% 53.3%;
  --muted-foreground: 215.4 16.3% 46.9%;
  --border: 214.3 31.8% 91.4%;
  --accent: 210 40% 96.1%;
}

.dark {
  --background: 222.2 84% 4.9%;
  --foreground: 210 40% 98%;
  --primary: 217.2 91.2% 59.8%;
  --muted-foreground: 215 20.2% 65.1%;
  --border: 217.2 32.6% 17.5%;
  --accent: 217.2 32.6% 17.5%;
}

Custom Styling

Override component styles with className:

<Thread
  className="border rounded-lg shadow-lg"
/>

Or use Tailwind's @apply for global customization:

/* Custom message styles */
.aui-user-message {
  @apply bg-blue-500 text-white rounded-2xl;
}

.aui-assistant-message {
  @apply bg-gray-100 dark:bg-gray-800 rounded-2xl;
}

Advanced Usage

With Pre-built Widgets

Combine with @rodger/widgets for instant tool UIs:

import { Thread } from '@rodger/ui';
import { CartBuilderUI, ProductLookupUI } from '@rodger/widgets';

<Thread
  widgets={{
    cartBuilder: CartBuilderUI,
    productLookup: ProductLookupUI
  }}
/>

With Custom Tools

Create tools with @rodger/tools and render with custom widgets:

// Backend: app/api/chat/route.ts
import { createAgent } from '@rodger/core';
import { cartBuilder, productLookup } from '@rodger/tools';

const agent = createAgent({
  name: 'Shopping Agent',
  llm: { provider: 'openai', model: 'gpt-4o' },
  tools: {
    cartBuilder,
    productLookup
  }
});

// Frontend: components/Chat.tsx
import { Thread } from '@rodger/ui';
import { CartBuilderUI, ProductLookupUI } from '@rodger/widgets';

<Thread
  widgets={{
    cartBuilder: CartBuilderUI,
    productLookup: ProductLookupUI
  }}
/>

Message History Management

Handle message history in your API:

// app/api/chat/history/route.ts
export async function POST(req: Request) {
  const { sessionId } = await req.json();

  // Fetch from database
  const messages = await db.messages.findMany({
    where: { sessionId },
    orderBy: { createdAt: 'asc' }
  });

  return Response.json({ messages });
}

useRodgerChat automatically loads history from {endpoint}/history.

Lifecycle Monitoring

Monitor chat activity with callbacks:

const { runtime } = useRodgerChat({
  endpoint: '/api/chat',
  sessionId: 'user-123',
  onBeforeRun: (input) => {
    // Track user input
    analytics.track('message.sent', { input });
  },
  onAfterRun: (output) => {
    // Track agent response
    analytics.track('message.received', { output });
  }
});

Custom Runtime Configuration

For advanced use cases, create your own runtime:

import { useChatRuntime } from '@assistant-ui/react-ai-sdk';
import { AssistantChatTransport } from '@assistant-ui/react-ai-sdk';

const runtime = useChatRuntime({
  transport: new AssistantChatTransport({
    api: '/api/chat',
    body: { sessionId: 'user-123' }
  }),
  initialMessages: [], // Pre-load messages
  maxToolRoundtrips: 10 // Limit tool calls
});

Component Reference

Thread Props

interface ThreadProps {
  welcomeMessage?: ReactNode;
  suggestions?: Suggestion[];
  placeholder?: string;
  widgets?: Record<string, FC<ToolUIProps>>;
  className?: string;
}

interface Suggestion {
  title: string;
  label: string;
  action: string;
}

useRodgerChat Options

interface UseRodgerChatOptions {
  endpoint: string;
  sessionId: string;
  body?: Record<string, unknown>;
  onBeforeRun?: (input: string) => void;
  onAfterRun?: (output: string) => void;
}

Examples

Basic Chat

import { RodgerProvider, Thread, useRodgerChat } from '@rodger/ui';

function Chat() {
  const { runtime, isLoadingHistory } = useRodgerChat({
    endpoint: '/api/chat',
    sessionId: 'user-123'
  });

  if (isLoadingHistory) return <div>Loading...</div>;

  return (
    <RodgerProvider runtime={runtime}>
      <Thread />
    </RodgerProvider>
  );
}

With Suggestions

<Thread
  suggestions={[
    { title: 'Get Started', label: 'Learn the basics', action: 'How do I get started?' },
    { title: 'Examples', label: 'See examples', action: 'Show me some examples' },
    { title: 'Help', label: 'Get help', action: 'I need help' }
  ]}
/>

With Custom Welcome

<Thread
  welcomeMessage={
    <div className="space-y-4">
      <h1 className="text-5xl font-bold">Welcome to AI Chat</h1>
      <p className="text-lg text-muted-foreground">
        Ask me anything about your business.
      </p>
    </div>
  }
/>
'use client';

import { RodgerProvider, Thread, useRodgerChat } from '@rodger/ui';
import { CartBuilderUI, ProductLookupUI } from '@rodger/widgets';

export default function ShoppingChat() {
  const { runtime, isLoadingHistory } = useRodgerChat({
    endpoint: '/api/chat',
    sessionId: 'shopping-session-123',
    body: {
      maxSteps: 10,
      temperature: 0.7
    },
    onBeforeRun: (input) => {
      console.log('User:', input);
    },
    onAfterRun: (output) => {
      console.log('Agent:', output);
    }
  });

  if (isLoadingHistory) {
    return (
      <div className="flex items-center justify-center h-screen">
        <div className="animate-spin">Loading...</div>
      </div>
    );
  }

  return (
    <RodgerProvider runtime={runtime}>
      <div className="h-screen bg-background">
        <Thread
          welcomeMessage={
            <div>
              <h1 className="text-4xl font-bold">Shopping Assistant</h1>
              <p className="mt-4 text-muted-foreground">
                I can help you find products and build your cart.
              </p>
            </div>
          }
          suggestions={[
            {
              title: 'Browse Products',
              label: 'See what we have',
              action: 'Show me your products'
            },
            {
              title: 'Build Cart',
              label: 'Start shopping',
              action: 'Help me build a cart'
            }
          ]}
          placeholder="Ask about products..."
          widgets={{
            cartBuilder: CartBuilderUI,
            productLookup: ProductLookupUI
          }}
        />
      </div>
    </RodgerProvider>
  );
}

TypeScript Support

Full TypeScript support with exported types:

import type {
  ThreadProps,
  Suggestion,
  UseRodgerChatOptions,
  UseRodgerChatReturn,
  RodgerProviderProps
} from '@rodger/ui';

Documentation

License

MIT

Keywords

rodger

FAQs

Package last updated on 31 Oct 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts