Contextual Assistance

Provide timely help and suggestions based on the user's current task, history, and needs without requiring explicit requests.

Problem

Users often need guidance but may not know what to ask for or when to ask. Traditional help systems require users to interrupt their workflow to search for assistance.

Solution

Create intelligent assistance that proactively offers relevant help, suggestions, or information based on the user's current context, behavior patterns, and needs. The system should anticipate user requirements rather than waiting for explicit requests.

Examples in the Wild

Google Smart Compose

Google Smart Compose

Predicts and suggests text completions while typing emails, based on the email context and common phrases.

Google Smart Compose suggesting email text completions

Interactive Code Example

Smart Text Editor with Contextual Suggestions

This React component implements a text editor that offers contextual suggestions based on what the user is typing. It uses a debounce function to prevent too many API calls and maintains clear user control over accepting suggestions.

tsx
1'use client';
2
3import React, { useState, useEffect, useRef } from 'react';
4import { motion, AnimatePresence } from 'framer-motion';
5
6// Type definitions
7interface Suggestion {
8  text: string;
9  confidence: number;
10}
11
12// Custom hook for debouncing
13function useDebounce<T>(value: T, delay: number): T {
14  const [debouncedValue, setDebouncedValue] = useState<T>(value);
15  
16  useEffect(() => {
17    const handler = setTimeout(() => {
18      setDebouncedValue(value);
19    }, delay);
20    
21    return () => {
22      clearTimeout(handler);
23    };
24  }, [value, delay]);
25  
26  return debouncedValue;
27}
28
29// Mock AI service - in a real app, replace with actual API call
30async function getContextualSuggestions(text: string): Promise<Suggestion[]> {
31  const suggestions: Record<string, string[]> = {
32    "i want to": ["create a new project", "learn more about", "schedule a meeting"],
33    "i need": ["more information about", "to finish this by", "help with"],
34    "can you": ["provide more details", "explain how this works", "help me understand"],
35    "how do i": ["implement this feature", "solve this problem", "get started with"],
36  };
37  
38  const lowerText = text.toLowerCase();
39  for (const [trigger, options] of Object.entries(suggestions)) {
40    if (lowerText.endsWith(trigger)) {
41      await new Promise(resolve => setTimeout(resolve, 300));
42      return options.map(option => ({
43        text: option,
44        confidence: Math.random() * 0.4 + 0.6
45      }));
46    }
47  }
48  return [];
49}
50
51export default function ContextualAssistanceDemo() {
52  const [text, setText] = useState("");
53  const [suggestions, setSuggestions] = useState<Suggestion[]>([]);
54  const [loading, setLoading] = useState(false);
55  const [selectedSuggestion, setSelectedSuggestion] = useState<number | null>(null);
56  const textAreaRef = useRef<HTMLTextAreaElement>(null);
57  
58  const debouncedText = useDebounce(text, 500);
59  
60  useEffect(() => {
61    const fetchSuggestions = async () => {
62      if (debouncedText.length > 5) {
63        setLoading(true);
64        try {
65          const newSuggestions = await getContextualSuggestions(debouncedText);
66          setSuggestions(newSuggestions);
67        } catch (error) {
68          console.error("Error fetching suggestions:", error);
69        } finally {
70          setLoading(false);
71        }
72      } else {
73        setSuggestions([]);
74      }
75    };
76    
77    fetchSuggestions();
78  }, [debouncedText]);
79  
80  const acceptSuggestion = (suggestion: string) => {
81    const newText = debouncedText + " " + suggestion;
82    setText(newText);
83    setSuggestions([]);
84    
85    if (textAreaRef.current) {
86      textAreaRef.current.focus();
87    }
88  };
89  
90  const handleTextChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
91    setText(e.target.value);
92    setSelectedSuggestion(null);
93  };
94  
95  return (
96    <div className="relative max-w-2xl w-full mx-auto">
97      <div className="relative bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden">
98        <div className="bg-gray-100 px-4 py-2 border-b border-gray-200 flex items-center">
99          <span className="text-xs text-gray-600 font-medium">Smart Text Editor</span>
100        </div>
101        <div className="p-4">
102          <textarea
103            ref={textAreaRef}
104            className="w-full p-3 border border-gray-300 rounded-lg shadow-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent resize-none"
105            placeholder="Start typing... (Try phrases like 'I want to' or 'Can you')"
106            value={text}
107            onChange={handleTextChange}
108            style={{ minHeight: "120px", maxHeight: "150px" }}
109          />
110        </div>
111      </div>
112      
113      <AnimatePresence>
114        {suggestions.length > 0 && (
115          <motion.div
116            initial={{ opacity: 0, y: -10 }}
117            animate={{ opacity: 1, y: 0 }}
118            exit={{ opacity: 0, y: -10 }}
119            className="absolute mt-2 w-full bg-white rounded-lg shadow-lg border border-gray-200 overflow-hidden z-10"
120          >
121            <div className="p-2 bg-blue-50 border-b border-gray-200">
122              <span className="text-sm font-medium text-blue-700">AI Suggestions</span>
123            </div>
124            <ul className="py-1">
125              {suggestions.map((suggestion, index) => (
126                <li 
127                  key={index}
128                  className="px-4 py-2 hover:bg-blue-50 cursor-pointer"
129                  onClick={() => acceptSuggestion(suggestion.text)}
130                >
131                  <span>{suggestion.text}</span>
132                </li>
133              ))}
134            </ul>
135          </motion.div>
136        )}
137      </AnimatePresence>
138    </div>
139  );
140}

Implementation & Considerations

Implementation Guidelines

1

Make assistance subtle and non-intrusive; don't interrupt the user's flow

2

Provide clear indications that suggestions are AI-generated

3

Allow users to easily accept, modify, or dismiss suggestions

4

Gradually improve suggestions based on user feedback and acceptance patterns

5

Offer ways to access more detailed help when contextual assistance isn't sufficient

Design Considerations

1

Balance between proactive help and avoiding unnecessary interruptions

2

Consider privacy implications of analyzing user behavior to provide contextual help

3

Ensure the system doesn't make assumptions that could frustrate users if incorrect

4

Provide transparency about why certain suggestions are being made

5

Include settings to adjust the frequency and type of assistance

Related Patterns