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

# Context Handoff Example

> Technical deep dive into context preservation and enrichment between apps

# Context Handoff: Technical Implementation

This guide explores the technical mechanisms behind SuperModel's context handoff system, showing how context flows seamlessly between different specialized UI apps while maintaining zero server inference.

## Overview

Context handoff enables SuperModel apps to build on previous user interactions, creating personalized experiences that span multiple specialized interfaces. The key innovation is that **context flows through the client**, not the server, maintaining our zero-inference guarantee.

## Context Flow Architecture

```mermaid
sequenceDiagram
    participant User
    participant Client
    participant Gateway
    participant App1
    participant App2
    
    User->>Gateway: Initial request
    Gateway->>Client: Route via sampling
    Client->>Gateway: Route to App1
    Gateway->>App1: Execute with context
    App1->>Client: Generate UI via sampling
    App1->>Client: UI + captured context
    Client->>User: Render App1 UI
    
    Note over User,Client: User interacts with App1
    User->>Gateway: Transition request
    Gateway->>Client: Route with accumulated context
    Client->>Gateway: Route to App2 + enriched context
    Gateway->>App2: Execute with full context
    App2->>Client: Generate contextual UI
    Client->>User: Render App2 UI
```

## Context Data Structure

SuperModel uses a standardized context object that grows throughout the user journey:

```typescript
interface UserContext {
  // Session information
  sessionId: string;
  userId?: string;
  timestamp: number;
  
  // Journey tracking
  journey: {
    currentApp: string;
    previousApps: string[];
    startTime: number;
    interactions: InteractionEvent[];
  };
  
  // User preferences and behavior
  preferences: {
    priorities: string[];
    values: Record<string, boolean>;
    interaction_patterns: string[];
  };
  
  // Domain-specific data
  data: {
    selections: Record<string, any>;
    filters: Record<string, any>;
    budget?: number;
    use_case?: string;
  };
  
  // Next step predictions
  predictions: {
    likely_next_app?: string;
    suggested_actions?: string[];
    confidence_score?: number;
  };
}
```

## Implementation Examples

### 1. Context Capture in UI Components

Apps capture context through AG-UI events:

<CodeGroup>
  ```jsx Product Search App Context Capture
  function ProductSearchUI({ products, context, onEvent }) {
    const [selectedProducts, setSelectedProducts] = useState([]);
    const [appliedFilters, setAppliedFilters] = useState({});

    const handleProductSelect = (product) => {
      const newSelection = [...selectedProducts, product];
      setSelectedProducts(newSelection);
      
      // Capture context through AG-UI event
      onEvent({
        type: 'CONTEXT_UPDATE',
        payload: {
          context: {
            ...context,
            data: {
              ...context.data,
              selected_products: newSelection,
              selection_criteria: appliedFilters
            },
            preferences: {
              ...context.preferences,
              // Infer preferences from selections
              values_quality: product.rating > 4.5,
              budget_conscious: product.price < context.data.budget * 0.8
            },
            journey: {
              ...context.journey,
              interactions: [
                ...context.journey.interactions,
                {
                  type: 'product_selected',
                  product_id: product.id,
                  timestamp: Date.now(),
                  selection_reason: 'user_choice'
                }
              ]
            }
          }
        }
      });
    };

    const handleTransition = (targetApp) => {
      onEvent({
        type: 'INTENT',
        payload: {
          intent: 'transition_to_app',
          target_app: targetApp,
          context: {
            ...context,
            predictions: {
              likely_next_app: targetApp,
              suggested_actions: ['compare_products', 'build_bundle'],
              confidence_score: 0.9
            }
          }
        }
      });
    };

    return (
      <div className="product-search">
        {/* Product grid with context-aware interactions */}
        {products.map(product => (
          <ProductCard 
            key={product.id}
            product={product}
            onSelect={() => handleProductSelect(product)}
            // Highlight based on context
            highlighted={
              context.preferences?.values_quality && product.rating > 4.5
            }
          />
        ))}
        
        {selectedProducts.length > 0 && (
          <div className="transition-actions">
            <button onClick={() => handleTransition('bundle-builder-ui')}>
              Build Complete Setup ({selectedProducts.length} items)
            </button>
          </div>
        )}
      </div>
    );
  }
  ```

  ```typescript Context Manager Implementation
  class ContextManager {
    private context: UserContext;
    
    constructor(initialContext: Partial<UserContext> = {}) {
      this.context = {
        sessionId: generateSessionId(),
        timestamp: Date.now(),
        journey: {
          currentApp: '',
          previousApps: [],
          startTime: Date.now(),
          interactions: []
        },
        preferences: {
          priorities: [],
          values: {},
          interaction_patterns: []
        },
        data: {},
        predictions: {},
        ...initialContext
      };
    }

    updateContext(updates: Partial<UserContext>): UserContext {
      this.context = this.mergeContext(this.context, updates);
      return this.context;
    }

    async routeWithContext(
      userAction: string, 
      availableApps: AppDefinition[]
    ): Promise<RoutingDecision> {
      // Use MCP sampling for routing decision
      const routingResponse = await this.gateway.sample({
        messages: [{
          role: "user",
          content: {
            type: "text",
            text: this.buildRoutingPrompt(userAction, availableApps)
          }
        }],
        systemPrompt: "You are a context-aware routing assistant. Consider the user's journey, preferences, and accumulated context."
      });

      const decision = JSON.parse(routingResponse.content.text);
      
      // Update journey tracking
      this.updateContext({
        journey: {
          ...this.context.journey,
          previousApps: [...this.context.journey.previousApps, this.context.journey.currentApp],
          currentApp: decision.app
        }
      });

      return decision;
    }

    private buildRoutingPrompt(userAction: string, apps: AppDefinition[]): string {
      return `
  Context from user journey:
  ${JSON.stringify(this.context, null, 2)}

  User action: "${userAction}"

  Available apps:
  ${apps.map(app => `- ${app.id}: ${app.description}`).join('\n')}

  Based on the user's journey, preferences, and current context, which app should handle this request?

  Consider:
  1. User's demonstrated preferences and values
  2. Logical next steps in their journey
  3. Context that would be valuable to preserve
  4. Opportunities to personalize the experience

  Return JSON: {
    "app": "app-id",
    "context": {
      // Additional context to pass to the app
    },
    "reasoning": "Why this app is the best choice"
  }`;
    }
  }
  ```
</CodeGroup>

### 2. Context-Aware UI Generation

Apps use accumulated context to personalize generated interfaces:

```json Context-Aware Generation Prompt
{
  "method": "sampling/createMessage",
  "params": {
    "messages": [{
      "role": "user",
      "content": {
        "type": "text",
        "text": "Generate a bundle builder UI with the following context:\n\nUser Journey:\n- Started with product search for home office headphones\n- Prioritized comfort and noise canceling\n- Selected premium products (Sony WH-1000XM5)\n- Demonstrated willingness to pay for quality\n- Values thorough research (compared multiple options)\n\nUser Preferences:\n- values_quality: true\n- comfort_focused: true\n- budget_conscious: false\n- thorough_researcher: true\n\nSelected Products:\n- Sony WH-1000XM5 ($299) - chosen for comfort rating\n\nBudget Context:\n- Original budget: $300\n- Spent: $299\n- Willing to exceed for right accessories\n\nGenerate a bundle builder that:\n1. Acknowledges their quality focus ('Perfect for your comfort priority')\n2. Suggests premium accessories that match their demonstrated values\n3. Shows confidence in recommending higher-end options\n4. Provides detailed justifications (appeals to their research style)\n\nUse AG-UI for all interactions."
      }
    }],
    "systemPrompt": "Generate AG-UI component that leverages user context for hyper-personalized experience. Reference their demonstrated preferences and journey."
  }
}
```

### 3. Context Enrichment Between Apps

Each app can enrich context for future apps:

<CodeGroup>
  ```typescript Context Enrichment Example
  // Bundle Builder App enriches context based on user selections
  class BundleBuilderTool {
    async execute(request: any, context: UserContext): Promise<UIResource> {
      // Generate personalized UI
      const uiResponse = await this.generateContextualUI(request, context);
      
      // Enrich context based on app-specific insights
      const enrichedContext = {
        ...context,
        preferences: {
          ...context.preferences,
          // Infer new preferences from bundle building behavior
          values_bundles: true,
          ecosystem_thinker: context.data.selected_accessories?.length > 2,
          convenience_focused: context.data.selected_accessories?.includes('wireless-charger')
        },
        data: {
          ...context.data,
          bundle_theme: this.inferBundleTheme(context),
          price_sensitivity: this.analyzePriceSensitivity(context)
        },
        predictions: {
          likely_next_app: 'checkout-ui',
          suggested_actions: ['review_bundle', 'add_warranty', 'apply_discounts'],
          confidence_score: 0.95
        }
      };

      return {
        type: 'resource',
        resource: {
          uri: `ui://bundle-builder/${Date.now()}`,
          mimeType: 'application/vnd.mcp-ui.ag-ui',
          text: uiResponse.content.text
        },
        context: enrichedContext // Pass enriched context back to client
      };
    }

    private inferBundleTheme(context: UserContext): string {
      const { use_case, selected_products, priorities } = context.data;
      
      if (use_case === 'home_office' && priorities?.includes('comfort')) {
        return 'productivity_comfort';
      }
      // ... other theme logic
      return 'general';
    }
  }
  ```

  ```typescript Client-Side Context Orchestration
  class SuperModelClient {
    private contextManager: ContextManager;
    
    async handleAppTransition(
      intent: string, 
      targetApp: string, 
      currentContext: UserContext
    ): Promise<void> {
      // Enrich context based on transition intent
      const transitionContext = {
        ...currentContext,
        journey: {
          ...currentContext.journey,
          transition_reason: intent,
          transition_timestamp: Date.now()
        }
      };

      // Route to next app with enriched context
      const routingDecision = await this.contextManager.routeWithContext(
        intent,
        this.availableApps
      );

      // Execute next app with full context
      const response = await this.gateway.executeApp(
        routingDecision.app,
        transitionContext
      );

      // Update context with response
      if (response.context) {
        this.contextManager.updateContext(response.context);
      }

      // Render new UI
      this.renderApp(response.ui, this.contextManager.getContext());
    }
  }
  ```
</CodeGroup>

## Context Persistence Strategies

<AccordionGroup>
  <Accordion title="Session Storage">
    ```typescript
    // Store context in browser session
    class SessionContextStore {
      save(context: UserContext): void {
        sessionStorage.setItem('supermodel-context', JSON.stringify(context));
      }
      
      load(): UserContext | null {
        const stored = sessionStorage.getItem('supermodel-context');
        return stored ? JSON.parse(stored) : null;
      }
    }
    ```
  </Accordion>

  <Accordion title="Context Compression">
    ```typescript
    // Compress context for efficiency
    class ContextCompressor {
      compress(context: UserContext): CompressedContext {
        return {
          essential: {
            preferences: context.preferences,
            key_selections: this.extractKeySelections(context.data),
            journey_stage: this.inferJourneyStage(context.journey)
          },
          metadata: {
            session_id: context.sessionId,
            compression_timestamp: Date.now()
          }
        };
      }
    }
    ```
  </Accordion>

  <Accordion title="Cross-Session Context">
    ```typescript
    // Optional: Persist context across sessions
    class PersistentContextStore {
      async saveUserProfile(userId: string, context: UserContext): Promise<void> {
        const profile = {
          preferences: context.preferences,
          interaction_patterns: this.extractPatterns(context.journey),
          value_indicators: this.extractValues(context.data)
        };
        
        // Save to user profile service
        await this.userService.updateProfile(userId, profile);
      }
    }
    ```
  </Accordion>
</AccordionGroup>

## Benefits of Context Handoff

<CardGroup cols={2}>
  <Card title="Personalized Experiences" icon="user-check">
    Each app builds on previous interactions, creating increasingly personalized and relevant experiences.
  </Card>

  <Card title="Reduced Cognitive Load" icon="brain">
    Users don't need to re-explain preferences or re-select options. Context carries forward automatically.
  </Card>

  <Card title="Intelligent Routing" icon="route">
    Routing decisions consider user journey and context, leading to more appropriate app selections.
  </Card>

  <Card title="Zero Server Inference" icon="dollar-sign">
    All context processing happens on the client. Server never interprets or analyzes context data.
  </Card>
</CardGroup>

## Best Practices

<Steps>
  <Step title="Design for Context Growth">
    Structure your context schema to accommodate new data as the user journey progresses.
  </Step>

  <Step title="Capture User Intent">
    Don't just track what users do - capture why they do it through interaction patterns.
  </Step>

  <Step title="Graceful Degradation">
    Ensure apps work even with minimal or missing context. Context should enhance, not break experiences.
  </Step>

  <Step title="Privacy by Design">
    Keep sensitive data in client-side context only. Server should never store personal preferences.
  </Step>
</Steps>

## Next Steps

<CardGroup cols={2}>
  <Card title="Gateway Pattern" icon="route" href="/concepts/gateway-pattern">
    Learn how SuperModel orchestrates multi-app workflows with intelligent routing.
  </Card>

  <Card title="Multi-App Workflow" icon="workflow" href="/examples/multi-app-workflow">
    See context handoff in action with a complete shopping journey example.
  </Card>
</CardGroup>
