Tool Context

Overview

The Tool Context provides a simple React context for sharing tool configurations across the application. It serves as a lightweight state management solution for tool-related data that needs to be accessed by multiple components.

Location: src/contexts/ToolContext.tsx
Dependencies: React Context API
Lines of Code: ~26

Purpose

The ToolContext enables:

  • Centralized tool configuration storage
  • Cross-component access to tool settings
  • Integration point for tool-related state management

Interface Definition

interface ToolContextType {
  toolConfigs: Record<string, Record<string, any>>;
}

Implementation

Context Creation

const ToolContext = createContext<ToolContextType>({
  toolConfigs: {},
});

Provider Component

export function ToolProvider({ 
  children, 
  toolConfigs 
}: { 
  children: React.ReactNode;
  toolConfigs: Record<string, Record<string, any>>;
}) {
  return (
    <ToolContext.Provider value=>
      {children}
    </ToolContext.Provider>
  );
}

Hook for Consumption

export const useToolContext = () => useContext(ToolContext);

Usage Examples

Provider Setup

function App() {
  const [toolConfigs, setToolConfigs] = useState({
    'vertex_search': {
      'datastore_id': 'aitana_public_welcome',
      'no-stream': false
    },
    'file-browser': {
      'bucketUrl': 'aitana-public-bucket',
      'rootPath': '/'
    }
  });

  return (
    <ToolProvider toolConfigs={toolConfigs}>
      <AssistantInterface />
    </ToolProvider>
  );
}

Context Consumption

function ToolStatusDisplay() {
  const { toolConfigs } = useToolContext();
  
  return (
    <div>
      {Object.entries(toolConfigs).map(([toolId, config]) => (
        <div key={toolId}>
          <h3>{toolId}</h3>
          <pre>{JSON.stringify(config, null, 2)}</pre>
        </div>
      ))}
    </div>
  );
}

Integration with Tool Components

function CustomToolComponent() {
  const { toolConfigs } = useToolContext();
  const myToolConfig = toolConfigs['my-tool'] || {};
  
  // Use tool configuration in component logic
  const enabled = myToolConfig.enabled !== false;
  const apiKey = myToolConfig.apiKey;
  
  return (
    <div>
      Status: {enabled ? 'Enabled' : 'Disabled'}
      {/* Component implementation */}
    </div>
  );
}

Integration Points

The ToolContext integrates with:

  1. ToolSelector Component
    • Provides tool configurations to context
    • Updates context when configurations change
  2. ToolConfigurator Component
    • Reads current configurations from context
    • Updates context with new configurations
  3. Assistant Components
    • Access tool configurations for API calls
    • Use configurations to modify behavior

Backend Integration

Tool configurations from the context are typically sent to the backend:

// Example API call using tool configurations
const { toolConfigs } = useToolContext();

const response = await fetch('/api/assistant', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    message: userMessage,
    tools_to_use: selectedTools,
    toolConfigs: toolConfigs
  })
});

State Management Pattern

Simple State Flow

User Interaction → ToolSelector → ToolContext → Components
                     ↓
              ToolConfigurator → ToolContext → API Calls

Configuration Updates

// Typical pattern for updating tool configurations
function updateToolConfig(toolId: string, newConfig: Record<string, any>) {
  setToolConfigs(prev => ({
    ...prev,
    [toolId]: {
      ...prev[toolId],
      ...newConfig
    }
  }));
}

Limitations

Simple Design

  • Read-only in context: Context provides configurations but doesn’t handle updates
  • No validation: Context doesn’t validate configuration data
  • No persistence: Context doesn’t handle saving/loading configurations

Usage Recommendations

Use ToolContext for:

  • Reading tool configurations across components
  • Providing configurations to API calls
  • Simple state sharing

Don’t use ToolContext for:

  • Complex state management (use Redux or Zustand instead)
  • Configuration validation (handle in components)
  • Persistent storage (use localStorage or backend)

Alternative Approaches

Local State Management

For simple use cases, local state might be sufficient:

function AssistantPage() {
  const [toolConfigs, setToolConfigs] = useState({});
  
  return (
    <div>
      <ToolSelector 
        toolConfigs={toolConfigs}
        onConfigChange={(toolId, config) => {
          setToolConfigs(prev => ({ ...prev, [toolId]: config }));
        }}
      />
      <ChatInterface toolConfigs={toolConfigs} />
    </div>
  );
}

Global State Management

For complex applications, consider more robust solutions:

// Using Zustand or Redux
const useToolStore = create((set) => ({
  toolConfigs: {},
  updateToolConfig: (toolId, config) => 
    set((state) => ({
      toolConfigs: { ...state.toolConfigs, [toolId]: config }
    }))
}));

Testing

Context Testing

import { render } from '@testing-library/react';
import { ToolProvider, useToolContext } from './ToolContext';

describe('ToolContext', () => {
  it('provides tool configurations to children', () => {
    const testConfigs = {
      'test-tool': { enabled: true }
    };
    
    function TestComponent() {
      const { toolConfigs } = useToolContext();
      return <div data-testid="config">{JSON.stringify(toolConfigs)}</div>;
    }
    
    const { getByTestId } = render(
      <ToolProvider toolConfigs={testConfigs}>
        <TestComponent />
      </ToolProvider>
    );
    
    expect(getByTestId('config')).toHaveTextContent('{"test-tool":{"enabled":true}}');
  });
});

API Reference

Types

interface ToolContextType {
  toolConfigs: Record<string, Record<string, any>>;
}

Provider Props

Prop Type Required Description
children React.ReactNode Yes Child components to wrap
toolConfigs Record<string, Record<string, any>> Yes Tool configuration objects

Hook Return Value

Property Type Description
toolConfigs Record<string, Record<string, any>> Current tool configurations

File Structure

src/contexts/
└── ToolContext.tsx    # Context implementation (26 lines)

src/components/tools/
├── ToolSelector.tsx   # Uses context for configurations
└── ToolConfigurator.tsx # Updates context via callbacks