React Hooks

InAppAI React exports several hooks for managing tools dynamically. These hooks are useful when you need to register tools from different parts of your application or manage tools based on component lifecycle.

useTools

A hook for managing tools within a single component.

Import

import { useTools } from '@inappai/react';

Basic Usage

import { useState, useEffect } from 'react';
import { useTools, InAppAI, Message } from '@inappai/react';

function MyComponent() {
  const [messages, setMessages] = useState<Message[]>([]);
  const { tools, registerTool, unregisterTool } = useTools();
  const [todos, setTodos] = useState<string[]>([]);

  useEffect(() => {
    registerTool({
      name: 'addTodo',
      description: 'Add a new todo item',
      parameters: {
        type: 'object',
        properties: {
          task: { type: 'string', description: 'The task to add' }
        },
        required: ['task']
      },
      handler: async ({ task }) => {
        setTodos(prev => [...prev, task]);
        return { success: true, message: `Added "${task}" to your list` };
      }
    });

    return () => unregisterTool('addTodo');
  }, [registerTool, unregisterTool]);

  return (
    <InAppAI
      agentId="your-agent-id"
      messages={messages}
      onMessagesChange={setMessages}
      tools={tools}
    />
  );
}

Options

interface UseToolsOptions {
  /**
   * Initial tools to register
   */
  initialTools?: Tool[];

  /**
   * Whether to automatically cleanup tools on unmount
   * @default true
   */
  autoCleanup?: boolean;
}

Return Value

interface UseToolsReturn {
  /**
   * Current array of registered tools
   */
  tools: Tool[];

  /**
   * Register a new tool
   * @throws {Error} If tool with same name already exists
   */
  registerTool: (tool: Tool) => void;

  /**
   * Unregister a tool by name
   */
  unregisterTool: (name: string) => void;

  /**
   * Clear all registered tools
   */
  clearTools: () => void;

  /**
   * Check if a tool with the given name exists
   */
  hasTool: (name: string) => boolean;
}

With Initial Tools

const { tools, registerTool } = useTools({
  initialTools: [
    {
      name: 'getTime',
      description: 'Get the current time',
      parameters: { type: 'object', properties: {} },
      handler: async () => ({ time: new Date().toISOString() })
    }
  ]
});

Dynamic Tool Registration

function FeatureComponent({ featureEnabled }: { featureEnabled: boolean }) {
  const { registerTool, unregisterTool, hasTool } = useTools();

  useEffect(() => {
    if (featureEnabled && !hasTool('specialFeature')) {
      registerTool({
        name: 'specialFeature',
        description: 'A special feature tool',
        parameters: { type: 'object', properties: {} },
        handler: async () => ({ result: 'special' })
      });
    } else if (!featureEnabled && hasTool('specialFeature')) {
      unregisterTool('specialFeature');
    }
  }, [featureEnabled, registerTool, unregisterTool, hasTool]);

  // ...
}

useToolRegistry

A hook for managing tools across multiple components using React Context. This is useful for larger applications where tools need to be registered from different parts of the component tree.

Import

import { useToolRegistry, ToolRegistryProvider } from '@inappai/react';

Setup

First, wrap your app with the provider:

import { ToolRegistryProvider } from '@inappai/react';

function App() {
  return (
    <ToolRegistryProvider>
      <MyApp />
    </ToolRegistryProvider>
  );
}

Usage in Components

function TodoPage() {
  const registry = useToolRegistry();
  const [todos, setTodos] = useState<Todo[]>([]);

  useEffect(() => {
    // Register tools for this page
    registry.register('todos', [
      {
        name: 'addTodo',
        description: 'Add a new todo',
        parameters: {
          type: 'object',
          properties: {
            task: { type: 'string' }
          },
          required: ['task']
        },
        handler: async ({ task }) => {
          setTodos(prev => [...prev, { id: Date.now(), text: task }]);
          return { success: true };
        }
      },
      {
        name: 'listTodos',
        description: 'List all todos',
        parameters: { type: 'object', properties: {} },
        handler: async () => ({ todos })
      }
    ]);

    // Cleanup on unmount
    return () => registry.unregister('todos');
  }, [registry, todos]);

  return <TodoList todos={todos} />;
}

Using Tools in Chat Widget

function ChatWidget() {
  const registry = useToolRegistry();
  const [messages, setMessages] = useState<Message[]>([]);

  // Get all tools from all registered namespaces
  const allTools = registry.getAllTools();

  return (
    <InAppAI
      agentId="your-agent-id"
      messages={messages}
      onMessagesChange={setMessages}
      tools={allTools}
    />
  );
}

ToolRegistry Interface

interface ToolRegistry {
  /**
   * Register tools under a namespace
   */
  register(namespace: string, tools: Tool[]): void;

  /**
   * Unregister all tools for a namespace
   */
  unregister(namespace: string): void;

  /**
   * Get tools for a specific namespace
   */
  getTools(namespace: string): Tool[];

  /**
   * Get all registered tools from all namespaces
   */
  getAllTools(): Tool[];

  /**
   * Clear all registered tools from all namespaces
   */
  clear(): void;

  /**
   * Get all registered namespace names
   */
  getNamespaces(): string[];
}

Provider Props

interface ToolRegistryProviderProps {
  /**
   * Child components
   */
  children: React.ReactNode;

  /**
   * Initial tools organized by namespace
   */
  initialTools?: Record<string, Tool[]>;
}

With Initial Tools

<ToolRegistryProvider
  initialTools={{
    global: [
      {
        name: 'getHelp',
        description: 'Get help information',
        parameters: { type: 'object', properties: {} },
        handler: async () => ({ help: 'Contact support@example.com' })
      }
    ]
  }}
>
  <App />
</ToolRegistryProvider>

Multi-Page Example

// pages/Dashboard.tsx
function Dashboard() {
  const registry = useToolRegistry();

  useEffect(() => {
    registry.register('dashboard', [
      {
        name: 'getMetrics',
        description: 'Get dashboard metrics',
        parameters: { type: 'object', properties: {} },
        handler: async () => ({ users: 1000, revenue: 50000 })
      }
    ]);

    return () => registry.unregister('dashboard');
  }, [registry]);

  return <DashboardContent />;
}

// pages/Settings.tsx
function Settings() {
  const registry = useToolRegistry();

  useEffect(() => {
    registry.register('settings', [
      {
        name: 'updateSettings',
        description: 'Update user settings',
        parameters: {
          type: 'object',
          properties: {
            theme: { type: 'string', enum: ['light', 'dark'] }
          }
        },
        handler: async ({ theme }) => {
          // Update settings...
          return { success: true };
        }
      }
    ]);

    return () => registry.unregister('settings');
  }, [registry]);

  return <SettingsContent />;
}

// components/GlobalChat.tsx
function GlobalChat() {
  const registry = useToolRegistry();
  const [messages, setMessages] = useState<Message[]>([]);

  // This will include tools from whichever page is currently mounted
  const tools = registry.getAllTools();

  return (
    <InAppAI
      agentId="your-agent-id"
      messages={messages}
      onMessagesChange={setMessages}
      tools={tools}
    />
  );
}

When to Use Each Hook

ScenarioRecommended Hook
Single component with toolsuseTools
Tools that change based on props/stateuseTools
Multiple components registering toolsuseToolRegistry
Page-specific toolsuseToolRegistry
Global app-wide toolsuseToolRegistry

TypeScript Types

All hooks are fully typed. Import types from the package:

import type {
  UseToolsOptions,
  UseToolsReturn,
  ToolRegistry,
  ToolRegistryProviderProps,
  Tool,
} from '@inappai/react';

Next Steps