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

# Synheart Behavior - Flutter SDK

> On-device behavioral signal inference for Flutter applications

## Overview

The Synheart Behavior Flutter SDK provides real-time behavioral signal inference from digital interactions for cross-platform mobile applications.

## Installation

Add to `pubspec.yaml`:

```yaml theme={null}
dependencies:
  synheart_behavior: ^0.2.1
```

Install:

```bash theme={null}
flutter pub get
```

### Requirements

* Flutter >= 3.10.0
* Dart >= 3.0.0

## Quick Start

### Basic Usage

```dart theme={null}
import 'package:synheart_behavior/synheart_behavior.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Initialize SDK
  final behavior = await SynheartBehavior.initialize(
    config: const BehaviorConfig(
      enableInputSignals: true,
      enableAttentionSignals: true,
      enableMotionLite: true, // Enable motion state inference (LAYING, MOVING, SITTING, STANDING)
    ),
  );

  runApp(MyApp(behavior: behavior));
}

class MyApp extends StatelessWidget {
  final SynheartBehavior behavior;

  const MyApp({super.key, required this.behavior});

  @override
  Widget build(BuildContext context) {
    return behavior.wrapWithGestureDetector(
      MaterialApp(
        title: 'My App',
        home: HomePage(behavior: behavior),
      ),
    );
  }
}
```

### Real-Time Event Tracking

```dart theme={null}
// Listen to real-time events
behavior.onEvent.listen((event) {
  print('Event: ${event.eventType} at ${event.timestamp}');
  print('Metrics: ${event.metrics}');

  // Handle different event types
  switch (event.eventType) {
    case BehaviorEventType.scroll:
      final velocity = event.metrics['velocity'] as double?;
      print('Scroll velocity: $velocity px/s');
      break;
    case BehaviorEventType.tap:
      final duration = event.metrics['tap_duration_ms'] as int?;
      print('Tap duration: $duration ms');
      break;
    case BehaviorEventType.swipe:
      final direction = event.metrics['direction'] as String?;
      print('Swipe direction: $direction');
      break;
    case BehaviorEventType.typing:
      final speed = event.metrics['typing_speed'] as double?;
      final tapCount = event.metrics['typing_tap_count'] as int?;
      print('Typing speed: $speed, tap count: $tapCount');
      break;
    default:
      break;
  }
});
```

### Session Management

```dart theme={null}
// Start a session
final session = await behavior.startSession();
print('Session started: ${session.sessionId}');

// ... user interacts with app ...

// End session and get summary
final summary = await session.end();
print('Session duration: ${summary.durationMs}ms');
print('Total events: ${summary.activitySummary.totalEvents}');
print('Focus hint: ${summary.behavioralMetrics.focusHint}');
print('Distraction score: ${summary.behavioralMetrics.distractionScore}');
```

### On-Demand Metrics Calculation

Calculate behavioral metrics for a custom time range within a session:

```dart theme={null}
// Calculate metrics for a specific time range
final metrics = await behavior.calculateMetricsForTimeRange(
  startTimestampSeconds: 1767688063,  // Unix timestamp in seconds
  endTimestampSeconds: 1767688130,     // Unix timestamp in seconds
  sessionId: 'SESS-1767688063415',     // Optional: uses current session if not provided
);

// Access the calculated metrics
print('Total events: ${metrics['activity_summary']['total_events']}');
print('App switches: ${metrics['activity_summary']['app_switch_count']}');
print('Interaction intensity: ${metrics['behavioral_metrics']['interaction_intensity']}');
print('Distraction score: ${metrics['behavioral_metrics']['behavioral_distraction_score']}');
print('Focus hint: ${metrics['behavioral_metrics']['focus_hint']}');

// Motion state (if motion data is available)
if (metrics['motion_state'] != null) {
  print('Motion state: ${metrics['motion_state']['major_state']}');
  print('Confidence: ${metrics['motion_state']['confidence']}');
}

// Device context
print('Screen brightness: ${metrics['device_context']['avg_screen_brightness']}');
print('Orientation: ${metrics['device_context']['start_orientation']}');

// System state
print('Internet: ${metrics['system_state']['internet_state']}');
print('Do not disturb: ${metrics['system_state']['do_not_disturb']}');
```

**Note**: The time range must be within the session's start and end times. The SDK automatically validates this and will throw an error if the range is out of bounds.

## API Reference

### `SynheartBehavior`

**Main Methods:**

| Method                              | Description                             | Returns                        |
| ----------------------------------- | --------------------------------------- | ------------------------------ |
| `initialize({config})`              | Initialize SDK                          | `Future<SynheartBehavior>`     |
| `wrapWithGestureDetector(widget)`   | Wrap app to enable gesture tracking     | `Widget`                       |
| `startSession({sessionId})`         | Start a new session                     | `Future<BehaviorSession>`      |
| `calculateMetricsForTimeRange(...)` | Calculate metrics for custom time range | `Future<Map<String, dynamic>>` |
| `getCurrentStats()`                 | Get current statistics                  | `Future<BehaviorStats>`        |
| `onEvent`                           | Stream of behavioral events             | `Stream<BehaviorEvent>`        |
| `dispose()`                         | Clean up resources                      | `void`                         |

#### `calculateMetricsForTimeRange()`

Calculate behavioral metrics for a custom time range within a session.

**Parameters:**

| Parameter               | Type      | Required | Description                                       |
| ----------------------- | --------- | -------- | ------------------------------------------------- |
| `startTimestampSeconds` | `int`     | Yes      | Start time as Unix timestamp in seconds           |
| `endTimestampSeconds`   | `int`     | Yes      | End time as Unix timestamp in seconds             |
| `sessionId`             | `String?` | No       | Session ID (uses current session if not provided) |

**Returns:** `Future<Map<String, dynamic>>` - Map containing all behavioral metrics for the specified time range

**Throws:** `Exception` if time range is out of session bounds or session not found

**Example:**

```dart theme={null}
final metrics = await behavior.calculateMetricsForTimeRange(
  startTimestampSeconds: DateTime.now().subtract(Duration(minutes: 5)).millisecondsSinceEpoch ~/ 1000,
  endTimestampSeconds: DateTime.now().millisecondsSinceEpoch ~/ 1000,
);

// Access metrics
final totalEvents = metrics['activity_summary']['total_events'] as int;
final intensity = metrics['behavioral_metrics']['interaction_intensity'] as double;
```

**Properties:**

| Property           | Type      | Description                |
| ------------------ | --------- | -------------------------- |
| `isInitialized`    | `bool`    | Whether SDK is initialized |
| `currentSessionId` | `String?` | Current active session ID  |

### `BehaviorConfig`

**Parameters:**

| Parameter                | Type      | Default | Description                                    |
| ------------------------ | --------- | ------- | ---------------------------------------------- |
| `enableInputSignals`     | `bool`    | `true`  | Enable scroll, tap, swipe, typing tracking     |
| `enableAttentionSignals` | `bool`    | `true`  | Enable app switching, idle gaps                |
| `enableMotionLite`       | `bool`    | `false` | Enable motion state inference                  |
| `sessionIdPrefix`        | `String?` | `null`  | Prefix for session IDs (null = auto-generated) |
| `userId`                 | `String?` | `null`  | Optional user identifier                       |
| `deviceId`               | `String?` | `null`  | Optional device identifier                     |
| `eventBatchSize`         | `int`     | `10`    | Events per batch                               |
| `maxIdleGapSeconds`      | `double`  | `10.0`  | Max idle time before task drop                 |

### `BehaviorEvent`

**Properties:**

| Property    | Type                   | Description             |
| ----------- | ---------------------- | ----------------------- |
| `eventId`   | `String`               | Unique event identifier |
| `sessionId` | `String`               | Associated session ID   |
| `timestamp` | `DateTime`             | Event timestamp         |
| `eventType` | `BehaviorEventType`    | Type of event           |
| `metrics`   | `Map<String, dynamic>` | Event-specific metrics  |

**Event Types:**

* `BehaviorEventType.scroll` - Scroll interactions
* `BehaviorEventType.tap` - Tap interactions
* `BehaviorEventType.swipe` - Swipe interactions
* `BehaviorEventType.appSwitch` - Foreground / background app-switch events (`app_switch`)
* `BehaviorEventType.notification` - Notification events
* `BehaviorEventType.call` - Call events
* `BehaviorEventType.typing` - Typing session events (timing only — never characters)
* `BehaviorEventType.clipboard` - Clipboard activity (copy / paste / cut counts only — never content)

### `BehaviorSession`

**Methods:**

| Method  | Description                 | Returns                          |
| ------- | --------------------------- | -------------------------------- |
| `end()` | End session and get summary | `Future<BehaviorSessionSummary>` |

**Properties:**

| Property    | Type     | Description        |
| ----------- | -------- | ------------------ |
| `sessionId` | `String` | Session identifier |

### `BehaviorSessionSummary`

**Properties:**

| Property               | Type                    | Description                                |
| ---------------------- | ----------------------- | ------------------------------------------ |
| `sessionId`            | `String`                | Session identifier                         |
| `startAt`              | `String`                | Session start time (ISO 8601)              |
| `endAt`                | `String`                | Session end time (ISO 8601)                |
| `durationMs`           | `int` (getter)          | Session duration in milliseconds           |
| `behavioralMetrics`    | `BehavioralMetrics`     | Behavioral metrics                         |
| `activitySummary`      | `ActivitySummary`       | Activity summary                           |
| `notificationSummary`  | `NotificationSummary`   | Notification summary                       |
| `typingSessionSummary` | `TypingSessionSummary?` | Typing aggregates (when typing was active) |
| `appId` / `appName`    | `String`                | Host app identifiers                       |
| `os`                   | `Map<String, dynamic>`  | OS / device platform info                  |
| `microSession`         | `MicroSession?`         | Micro-session metadata                     |
| `sessionSpacing`       | `SessionSpacing?`       | Spacing relative to previous session       |
| `deviceContext`        | `DeviceContext?`        | Device-state context                       |
| `systemState`          | `SystemState?`          | System-level state at session boundaries   |
| `performanceInfo`      | `PerformanceInfo?`      | Per-session performance counters           |

> Motion classification runs in the Synheart Runtime —
> consumers subscribe to `onMotionSample` and forward raw 50 Hz
> accelerometer batches to the Synheart Runtime's motion classifier.

### `BehavioralMetrics`

**Properties** (12 total):

| Property                     | Type                   | Description                                 |
| ---------------------------- | ---------------------- | ------------------------------------------- |
| `interactionIntensity`       | `double`               | Overall interaction rate (0-1)              |
| `taskSwitchRate`             | `double`               | App-switching frequency                     |
| `taskSwitchCost`             | `int`                  | Task-switch cost in milliseconds            |
| `idleTimeRatio`              | `double`               | Proportion of session that was idle (0-1)   |
| `activeTimeRatio`            | `double`               | Proportion of session that was active (0-1) |
| `notificationLoad`           | `double`               | Notification pressure                       |
| `burstiness`                 | `double`               | Temporal clustering of events               |
| `behavioralDistractionScore` | `double`               | Distraction proxy (0-1)                     |
| `focusHint`                  | `double`               | Focus quality proxy (0-1)                   |
| `fragmentedIdleRatio`        | `double`               | Fragmented vs. continuous idle              |
| `scrollJitterRate`           | `double`               | Scroll pattern irregularity                 |
| `deepFocusBlocks`            | `List<DeepFocusBlock>` | Sustained focus periods                     |

### `TypingSessionSummary`

The aggregated typing fields live on `TypingSessionSummary`, accessed
via `BehaviorSessionSummary.typingSessionSummary` (null when typing
was not active during the session).

| Property                     | Type     | Description                                    |
| ---------------------------- | -------- | ---------------------------------------------- |
| `typingSpeed`                | `double` | Average typing speed (taps per second)         |
| `typingCadenceStability`     | `double` | Consistency of typing rhythm (0-1)             |
| `typingCadenceVariability`   | `double` | Variability in timing between taps             |
| `typingActivityRatio`        | `double` | Fraction of session with active typing (0-1)   |
| `typingGapRatio`             | `double` | Proportion of intervals that are gaps (0-1)    |
| `typingBurstiness`           | `double` | Temporal clustering of typing events           |
| `typingInteractionIntensity` | `double` | Overall typing engagement (0-1)                |
| `clipboardActivityRate`      | `double` | `(copy+paste+cut)/(typing+clipboard)`          |
| `correctionRate`             | `double` | `(backspace+delete)/(typing+backspace+delete)` |

## Permissions

### Notification Permission

```dart theme={null}
// Check if permission is granted
final hasPermission = await behavior.checkNotificationPermission();

if (!hasPermission) {
  // Request permission
  final granted = await behavior.requestNotificationPermission();
  if (granted) {
    print('Notification permission granted');
  }
}
```

### Call Permission

```dart theme={null}
// Check if permission is granted
final hasPermission = await behavior.checkCallPermission();

if (!hasPermission) {
  // Request permission
  await behavior.requestCallPermission();
}
```

## Configuration

### Update Configuration at Runtime

```dart theme={null}
 await behavior.updateConfig(const BehaviorConfig(
  enableInputSignals: true,
  enableAttentionSignals: true,
  enableMotionLite: true,  
));
```

## Resources

* **pub.dev**: [synheart\_behavior](https://pub.dev/packages/synheart_behavior)
* **Repository**: [synheart-behavior-flutter](https://github.com/synheart-ai/synheart-behavior-flutter)
* **Full README**: [View on GitHub](https://github.com/synheart-ai/synheart-behavior-flutter#readme)

For comprehensive documentation, see the [full README on GitHub](https://github.com/synheart-ai/synheart-behavior-flutter#readme).
