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

# User sessions

# Your Command Center: UserSessions

Remember Alex from our authentication story? Now that they're connected, the cloud creates a UserSession - their personal command center. Think of it as a smart assistant that manages everything happening with their glasses.

## What is a UserSession?

A UserSession is the heart of a user's experience in MentraOS Cloud. It's a long-lived object that:

* Maintains the WebSocket connection to the glasses
* Manages all the specialized services (managers)
* Tracks which apps are running
* Handles all message routing
* Survives temporary disconnections

```typescript theme={null}
// Simplified view of UserSession
class UserSession {
  userId: string;                    // alex@example.com
  websocket: WebSocket;              // Connection to glasses
  appWebsockets: Map<string, WebSocket>; // Connections to apps
  startTime: Date;                   // When session started
  
  // The managers (our departments)
  appManager: AppManager;
  audioManager: AudioManager;
  displayManager: DisplayManager;
  // ... and more
}
```

## Meet the Managers

Think of managers as specialized departments in Alex's personal cloud office. Each one handles a specific type of functionality:

### 🎯 AppManager - The App Orchestrator

Manages the lifecycle of third-party apps:

```typescript theme={null}
// What it tracks for each app
{
  packageName: "com.translate.app",
  state: "RUNNING" | "GRACE_PERIOD" | "RESURRECTING" | "STOPPING",
  websocket: WebSocket,
  lastHeartbeat: Date
}
```

**Key Responsibilities:**

* Starting and stopping apps
* Monitoring app health with heartbeats
* Handling app reconnections
* Managing the 20-second grace period when apps disconnect

**Real Example:**
When Alex says "Start translator", AppManager:

1. Finds the translator app in installed apps
2. Notifies the app via webhook to start
3. Waits for app to connect via WebSocket
4. Monitors the app's health

### 🎤 AudioManager - The Sound Department

Handles all things audio:

```typescript theme={null}
// Managing audio streams
audioManager.startStreaming();  // Start receiving audio from glasses
audioManager.stopStreaming();   // Stop audio stream
audioManager.playAudio(audioData, format); // Play audio on glasses
```

**Key Responsibilities:**

* Receiving audio streams from glasses microphone
* Buffering audio data for processing
* Sending audio to glasses speakers
* Managing audio format conversions

### 📺 DisplayManager - The Visual Controller

Controls what appears on the glasses display:

```typescript theme={null}
// Display update request
displayManager.updateDisplay({
  type: "cards",
  cards: [{
    title: "Weather",
    body: "72°F and sunny"
  }]
});
```

**Key Responsibilities:**

* Rendering layouts from apps
* Enforcing the 200-300ms throttle between updates
* Managing display queues
* Preventing display spam

**Important:** The glasses have a simple display that can only show text. No images, no colors (except green), just text and simple layouts.

### 🎙️ TranscriptionManager - The Speech-to-Text Expert

Converts speech to text in real-time:

```typescript theme={null}
// Start transcribing
transcriptionManager.startTranscription("en-US");

// Receive transcription events
transcriptionManager.on('transcription', (text) => {
  console.log("User said:", text);
});
```

**Key Responsibilities:**

* Managing transcription providers (Deepgram, Assembly, etc.)
* Streaming audio to transcription services
* Handling multiple language streams
* Distributing transcripts to subscribed apps

### 📸 PhotoManager - The Camera Controller

Handles photo capture:

```typescript theme={null}
// App requests a photo
photoManager.requestPhoto();

// Photo arrives from glasses
photoManager.on('photoReceived', (photoData) => {
  // Process and distribute to requesting app
});
```

### 🌐 MicrophoneManager - The Audio Gate

Controls the glasses microphone:

```typescript theme={null}
// Turn microphone on/off
microphoneManager.setMicrophoneState(true);  // On
microphoneManager.setMicrophoneState(false); // Off
```

### 📊 DashboardManager - The Always-On Display

Manages the dashboard mode (always-visible information):

```typescript theme={null}
// Update dashboard content
dashboardManager.updateContent({
  text: "3 new messages",
  priority: "high"
});
```

## How Managers Work Together

Let's see how managers collaborate when Alex says "Take a photo":

1. **AudioManager** receives the audio stream
2. **TranscriptionManager** converts it to text: "Take a photo"
3. **AppManager** routes the transcript to subscribed apps
4. App recognizes the command and tells **PhotoManager**
5. **PhotoManager** sends photo request to glasses
6. Glasses capture photo and send it back
7. **PhotoManager** receives photo and gives it to the app
8. App processes photo and uses **DisplayManager** to show "Photo saved!"

## Session Lifecycle

### Birth: Session Creation

When Alex connects:

```typescript theme={null}
const session = new UserSession(userId, websocket);
// All managers are initialized
session.appManager = new AppManager(session);
session.audioManager = new AudioManager(session);
// ... etc
```

### Life: Active Session

During normal operation:

* Heartbeat runs every 10 seconds
* Messages flow between glasses and apps
* Managers handle their specific duties
* Everything is logged for debugging

### Near-Death: Disconnection

When connection drops:

* 30-second grace period begins
* Apps enter "resurrecting" state
* Session waits for reconnection
* No data is lost

### Resurrection or Death

**If Alex reconnects within 30 seconds:**

* WebSocket is updated
* Apps are notified
* Everything continues normally

**If Alex doesn't reconnect:**

* Session is cleaned up
* All managers are destroyed
* Apps are notified of session end
* Memory is freed

## Session Storage

All active sessions live in SessionStorage:

```typescript theme={null}
class SessionStorage {
  private static sessions = new Map<string, UserSession>();
  
  static getSession(userId: string): UserSession | undefined {
    return this.sessions.get(userId);
  }
  
  static addSession(session: UserSession) {
    this.sessions.set(session.userId, session);
  }
}
```

This allows any part of the system to find Alex's session when needed.

## Best Practices

1. **Always check session exists** before using it
2. **Use the appropriate manager** for each task
3. **Let managers handle their domain** - don't bypass them
4. **Clean up resources** when sessions end
5. **Log important events** for debugging

## What's Next?

Now that you understand UserSessions and their managers, let's look at [the messages](./4-message-types.md) that flow through the system. These messages are how all the components talk to each other!
