> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sammylabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Text Mode & Tour System

> Enable text-based conversations with interactive DOM element highlighting and step-by-step user guidance

# Text Mode & Tour System

The Text Mode agent provides a lightweight, text-only alternative to the voice agent with an innovative **Tour System** that can visually guide users through web interfaces by highlighting DOM elements and providing contextual instructions.

<Note>
  Text mode is perfect for environments where audio isn't suitable, users prefer typing, or you need lower bandwidth requirements.
</Note>

## Quick Start

Enable text mode in your Sammy Agent by setting the `mode` prop:

```tsx Basic Text Mode Setup theme={null}
import { SammyAgentProvider, useSammyAgent } from '@sammy-labs/sammy-three';

function App() {
  return (
    <SammyAgentProvider
      config={yourConfig}
      mode="text"           // Enable text mode
      enableTour={true}     // Enable tour feature
    >
      <YourChatComponent />
    </SammyAgentProvider>
  );
}
```

## Text Mode Features

### Streaming Responses

Text mode provides real-time streaming of agent responses through the `streamingMessage` property:

```tsx Streaming Messages theme={null}
function ChatComponent() {
  const { sendMessage, streamingMessage } = useSammyAgent();
  
  return (
    <div>
      {streamingMessage && (
        <div className="streaming-response">
          {streamingMessage}
        </div>
      )}
    </div>
  );
}
```

### Starting a Text Session

```tsx Starting Text Agent theme={null}
const { startAgent } = useSammyAgent();

// Start with specific source tracking
await startAgent({
  agentMode: AgentMode.USER,
  source: 'chat'  // or 'tour' for tour-initiated conversations
});
```

### Message Handling

Text mode provides a simple interface for sending and receiving messages:

```tsx Message Management theme={null}
function Chat() {
  const { sendMessage, activeSession } = useSammyAgent();
  const [messages, setMessages] = useState([]);

  const handleSend = (text) => {
    // Send message to agent
    sendMessage(text);
    
    // Add to local message history
    setMessages(prev => [...prev, {
      type: 'user',
      content: text,
      timestamp: new Date()
    }]);
  };
  
  // Listen for completed agent responses
  const onTurnComplete = ({ agent, user, source }) => {
    if (source !== 'tour') {  // Filter out tour messages
      setMessages(prev => [...prev, {
        type: 'agent',
        content: agent,
        timestamp: new Date()
      }]);
    }
  };
}
```

## Tour System

The Tour System enables agents to create interactive guides by highlighting elements on the page and providing step-by-step instructions.

<Info>
  Tours are perfect for onboarding, troubleshooting, form assistance, and interactive tutorials.
</Info>

### How Tours Work

1. **Agent identifies elements** - The agent receives DOM context with numbered interactive elements
2. **Highlights target** - Purple border appears around the selected element
3. **Shows instructions** - Popover displays contextual guidance
4. **Waits for user** - User performs action or asks questions
5. **Proceeds to next step** - Process repeats for multi-step workflows

### Tour Tool Usage

The agent can trigger tours using the built-in `tour()` tool:

```typescript Tour Tool Schema theme={null}
tour({
  element: 1,                           // Numeric ID from DOM context
  title: "Click Submit",                // Short title
  instruction: "Click here to submit"   // Clear instruction
})
```

### Tour Callbacks

Set up callbacks to handle tour interactions:

```tsx Tour Callbacks theme={null}
import { setTourCallbacks } from '@sammy-labs/sammy-three';

useEffect(() => {
  setTourCallbacks(
    // Handle user actions (clicks, cancellations)
    (action: string) => {
      console.log('User action:', action);
      agent.sendUserAction(action);
    },
    // Handle chat messages from tour popover
    (message: string) => {
      console.log('Tour chat:', message);
      agent.sendMessage(message);
    }
  );
}, [agent]);
```

### Manual Tour Creation

You can also create tours programmatically:

```tsx Manual Tour theme={null}
import { createTourHighlight, clearExistingHighlight } from '@sammy-labs/sammy-three';

// Create a tour highlight
createTourHighlight({
  element: document.querySelector('#submit-button'),
  title: 'Submit Form',
  description: 'Click this button to submit your application'
});

// Clear when done
clearExistingHighlight();
```

## Advanced Usage

### Direct Core Usage

For advanced scenarios, use the text agent core directly:

```tsx Text Agent Core theme={null}
import { SammyTextAgentCore } from '@sammy-labs/sammy-three';

const textAgent = new SammyTextAgentCore({
  config: yourConfig,
  callbacks: {
    onTextResponse: (text) => {
      console.log('Streaming:', text);
    },
    onTurnComplete: ({ user, agent, source }) => {
      console.log('Turn complete:', { user, agent, source });
    }
  },
  enableTour: true,
  updateAgentState: (key, value) => {
    // State management
  }
});

// Start session
await textAgent.start({
  agentMode: AgentMode.USER,
  source: 'chat'
});

// Send messages
textAgent.sendMessage('Help me fill out this form');

// Clean up
await textAgent.destroy();
```

### Context Injection

Text mode supports all context injection features:

```tsx Context Management theme={null}
const textAgent = new SammyTextAgentCore({
  config: {
    contextInjection: {
      enabled: true,
      pageTracking: true,    // Track page navigation
      memorySearch: true,    // Search relevant memories
      clickTracking: false   // No click tracking in text mode
    }
  }
});

// Inject custom context
await textAgent.injectContext(
  "User is on checkout page with 3 items in cart",
  { source: 'custom' }
);

// Update page context
await textAgent.updatePageContext({
  title: 'Checkout - Payment',
  url: window.location.href,
  path: '/checkout/payment'
});
```

### Screen Capture

Text mode can capture screenshots for visual context:

```tsx Screen Capture Config theme={null}
const config = {
  captureMethod: 'render',  // Periodic screenshots
  // Screen capture runs every 2 seconds by default
};
```

## Configuration Reference

### Provider Props

<ResponseField name="mode" type="'text' | 'voice'" default="'voice'">
  Selects between text-only or voice agent modes
</ResponseField>

<ResponseField name="enableTour" type="boolean" default="false">
  Enables the tour tool for interactive guidance (text mode only)
</ResponseField>

<ResponseField name="streamingMessage" type="string | null">
  Current streaming agent response (available via useSammyAgent hook)
</ResponseField>

### Text Start Options

<ResponseField name="agentMode" type="AgentMode" required>
  The agent mode (typically AgentMode.USER)
</ResponseField>

<ResponseField name="source" type="'chat' | 'tour'" default="'chat'">
  Identifies the source of the conversation for analytics
</ResponseField>

<ResponseField name="guideId" type="string">
  Optional guide ID for guided experiences
</ResponseField>

### Tour Configuration

<ResponseField name="element" type="HTMLElement" required>
  The DOM element to highlight
</ResponseField>

<ResponseField name="title" type="string" required>
  Short title displayed in the popover header
</ResponseField>

<ResponseField name="description" type="string" required>
  Detailed instruction or description for the user
</ResponseField>

## Tour UI Components

The tour system includes several UI elements:

### Highlight Border

* **Purple border** (#8b5cf6) around target element
* **8px padding** for visibility
* **Dark overlay** on rest of page
* **Smooth transitions** when moving between elements

### Instruction Popover

* **Smart positioning** - Automatically positions to avoid viewport edges
* **Arrow indicator** - Points to highlighted element
* **Chat interface** - Users can ask questions directly
* **Response display** - Shows agent responses in real-time

### User Interactions

* **Click detection** - Tracks when users click highlighted elements
* **Cancellation** - Detects when users click outside to cancel
* **Chat input** - Allows questions at any step
* **Progress tracking** - Maintains state across steps

## Best Practices

### For Text Mode

<Steps>
  <Step title="Choose the right mode">
    Use text mode when:

    * Audio is not suitable (quiet environments, accessibility)
    * Users prefer typing over speaking
    * Lower bandwidth is required
    * You need precise text logs for compliance
  </Step>

  <Step title="Handle streaming properly">
    * Show typing indicators during streaming
    * Update UI smoothly as text arrives
    * Handle partial responses gracefully
  </Step>

  <Step title="Manage conversation history">
    * Keep reasonable history limits (e.g., last 50 messages)
    * Persist important conversations
    * Clear history on mode switches
  </Step>
</Steps>

### For Tours

<Steps>
  <Step title="Write clear instructions">
    * Use imperative language ("Click the Submit button")
    * Be specific about what users should do
    * Keep instructions concise and actionable
  </Step>

  <Step title="Handle dynamic content">
    * Wait for elements to load before highlighting
    * Gracefully handle missing elements
    * Provide fallback text instructions
  </Step>

  <Step title="Test thoroughly">
    * Verify tours work on different screen sizes
    * Test with various page layouts
    * Ensure z-index doesn't conflict with your app
  </Step>
</Steps>

## Examples

### Complete Chat Implementation

<CodeGroup>
  ```tsx React Implementation theme={null}
  import { useState, useEffect } from 'react';
  import { 
    SammyAgentProvider, 
    useSammyAgent,
    AgentMode 
  } from '@sammy-labs/sammy-three';

  function ChatApp() {
    return (
      <SammyAgentProvider
        config={{
          auth: { token: 'YOUR_TOKEN' },
          contextInjection: { enabled: true }
        }}
        mode="text"
        enableTour={true}
        onTurnComplete={handleTurnComplete}
      >
        <ChatInterface />
      </SammyAgentProvider>
    );
  }

  function ChatInterface() {
    const { 
      startAgent, 
      sendMessage, 
      streamingMessage, 
      agentStatus 
    } = useSammyAgent();
    
    const [messages, setMessages] = useState([]);
    const [input, setInput] = useState('');
    
    useEffect(() => {
      // Auto-start agent
      if (agentStatus === 'disconnected') {
        startAgent({ 
          agentMode: AgentMode.USER,
          source: 'chat'
        });
      }
    }, [agentStatus]);
    
    const handleSend = () => {
      if (input.trim()) {
        sendMessage(input);
        setMessages(prev => [...prev, {
          type: 'user',
          content: input
        }]);
        setInput('');
      }
    };
    
    return (
      <div className="chat-container">
        <div className="messages">
          {messages.map((msg, i) => (
            <div key={i} className={`message ${msg.type}`}>
              {msg.content}
            </div>
          ))}
          {streamingMessage && (
            <div className="message agent streaming">
              {streamingMessage}
            </div>
          )}
        </div>
        <input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyPress={(e) => e.key === 'Enter' && handleSend()}
          placeholder="Type your message..."
        />
      </div>
    );
  }
  ```

  ```typescript TypeScript Core theme={null}
  import { SammyTextAgentCore, TextStartOptions } from '@sammy-labs/sammy-three';

  class TextChatManager {
    private agent: SammyTextAgentCore;
    private messages: ChatMessage[] = [];
    
    constructor(config: SammyAgentConfig) {
      this.agent = new SammyTextAgentCore({
        config,
        callbacks: {
          onTextResponse: this.handleStreaming.bind(this),
          onTurnComplete: this.handleTurnComplete.bind(this),
          onError: this.handleError.bind(this)
        },
        enableTour: true,
        updateAgentState: this.updateState.bind(this)
      });
    }
    
    async start(): Promise<void> {
      await this.agent.start({
        agentMode: AgentMode.USER,
        source: 'chat'
      });
    }
    
    async sendMessage(text: string): Promise<void> {
      this.messages.push({
        id: Date.now().toString(),
        type: 'user',
        content: text,
        timestamp: new Date()
      });
      
      await this.agent.sendMessage(text);
    }
    
    private handleStreaming(text: string): void {
      // Update UI with streaming text
      this.updateStreamingDisplay(text);
    }
    
    private handleTurnComplete(summary: TurnSummary): void {
      if (summary.source !== 'tour') {
        this.messages.push({
          id: Date.now().toString(),
          type: 'agent',
          content: summary.agent,
          timestamp: new Date()
        });
      }
    }
    
    async destroy(): Promise<void> {
      await this.agent.destroy();
    }
  }
  ```
</CodeGroup>

### Tour-Enabled Form Assistant

```tsx Form Assistant with Tours theme={null}
function FormAssistant() {
  const { sendMessage } = useSammyAgent();
  
  const requestHelp = () => {
    // Agent will use tour() to highlight form fields
    sendMessage(
      "Help me fill out this application form step by step"
    );
  };
  
  return (
    <div>
      <button onClick={requestHelp}>
        Get Help with Form
      </button>
      
      <form id="application-form">
        <input id="name" placeholder="Full Name" />
        <input id="email" placeholder="Email" />
        <textarea id="experience" placeholder="Experience" />
        <button id="submit">Submit</button>
      </form>
    </div>
  );
}
```

## Troubleshooting

<Warning>
  Common issues and their solutions
</Warning>

### Tour not highlighting elements

* **Check DOM context**: Ensure elements are numbered in context
* **Wait for render**: Elements must exist before highlighting
* **Verify z-index**: Tour overlays need high z-index (999999+)

### Streaming messages not appearing

* **Check connection**: Ensure agent is connected before sending
* **Verify mode**: Streaming only works in text mode
* **Handle errors**: Check onError callback for issues

### Chat messages mixed with tour messages

* **Filter by source**: Check `source` field in onTurnComplete
* **Separate handlers**: Use different callbacks for chat vs tour

## Migration Guide

### From Voice to Text Mode

```tsx Migration Example theme={null}
// Before - Voice mode
<SammyAgentProvider
  config={config}
  enableHighlighting={true}  // Voice highlighting
>

// After - Text mode
<SammyAgentProvider
  config={config}
  mode="text"
  enableTour={true}          // Text tour system
  enableHighlighting={false}  // Not used in text mode
>
```

### Adding Tours to Existing Text Implementation

```tsx Adding Tours theme={null}
// Step 1: Enable tour in provider
<SammyAgentProvider
  mode="text"
  enableTour={true}  // Add this
>

// Step 2: Set up tour callbacks
import { setTourCallbacks } from '@sammy-labs/sammy-three';

useEffect(() => {
  setTourCallbacks(
    (action) => agent.sendUserAction(action),
    (message) => agent.sendMessage(message)
  );
}, [agent]);
```

## Performance

Text mode offers several performance advantages:

<Columns cols={2}>
  <Card title="Lower Memory Usage" icon="memory">
    \~30% less memory than voice mode due to no audio buffers
  </Card>

  <Card title="Reduced Bandwidth" icon="network">
    Text-only WebSocket uses \< 1KB per message typically
  </Card>

  <Card title="Minimal CPU" icon="cpu">
    No audio processing overhead, just text handling
  </Card>

  <Card title="Fast Response" icon="bolt">
    \< 200ms message round-trip typical latency
  </Card>
</Columns>

## Summary

Text mode with the Tour System provides a powerful combination for creating accessible, bandwidth-efficient conversational experiences with visual guidance capabilities. It's ideal for:

* **Customer support** - Guide users through troubleshooting
* **Onboarding** - Interactive product tours
* **Form assistance** - Step-by-step form completion
* **Training** - Interactive tutorials and learning paths
* **Accessibility** - Text-based alternative for all users

The tour feature transforms static help into dynamic, contextual guidance that adapts to your application's current state.
