# Integrating the Omni Copilot with your app

The Omni Copilot SDK will be available for the following platforms:

* Android Native
* React Native(Android/iOS)
* Flutter (Android/iOS)

{% hint style="info" %}
Note: These APIs are under active development and could change
{% endhint %}

## 1. Configure the build system

The first step is to update the app's build system to include Conva Omni Copilot SDK.

{% tabs %}
{% tab title="Android" %}
Add the path to the Slang maven repository to your top-level Gradle file

```
// Add this to your project build.gradle file

allprojects {  
    repositories {        
        maven { url "https://gitlab.com/api/v4/projects/25706948/packages/maven" }  
    }
}
```

Add the Omni Copilot dependency to your app's Gradle file

```
# Add this to your app's Gradle file

dependencies {  
    …   
    implementation 'in.slanglabs.conva:conva-omni-copilot:1.+'
}
```

{% endtab %}

{% tab title="Flutter" %}
**Install the Conva Omni Copilot package**

**Run the below command to install the required packages inside your code repo.**

```
 $ flutter pub add conva_omni_copilot
```

**Once done, run the command '`dart pub get`' and ensure Conva Omni Copilot is added to the dependencies.**

```

dependencies:
  conva_omni_copilot: ^1.1.5
```

#### **For iOS:-**

**Add the path to the Slang Cocoapod repository to your Podfile**

```
# Add this to your podfile

source 'https://github.com/SlangLabs/cocoapod-specs'
```

**Add support for granting microphone permission**\
In iOS, the user must explicitly grant permission for an app to [access the user’s data and resources](https://developer.apple.com/design/human-interface-guidelines/ios/app-architecture/accessing-user-data/). An app with the ConvaOmniCopilot requires access to the User’s device microphone for voice interactions.<br>

To comply with this requirement, you must add `NSMicrophoneUsageDescription` key to the `Info.plist` file of your app and provide a message about why your app requires access to the microphone. The message will be displayed only when the ConvaOmniCopilot needs to activate the microphone.

To add the key:

1. In the Xcode project, go to the **Info** tab.
2. In the **Custom iOS Target Properties** section, hover over any key in the list and click the plus icon to the right.
3. From the list, select **Privacy - Microphone Usage Description**.
4. In the **Value** field to the right, provide a description for the added key. This description will be displayed to the user when the app is launched. \
   \&#xNAN;*For example: "We require microphone permission to enable the voice assistant platform"*

#### **Next is to import Conva Omni Copilot in your dart code.**

```
import 'package:conva_omni_copilot/conva_omni_copilot.dart';
```

{% hint style="info" %}
**Try out the** [**playground app**](https://github.com/slanglabs-projects/Conva-Omni-Copilot-Flutter-Demo) **for developers to understand the assistant.**
{% endhint %}
{% endtab %}

{% tab title="React Native" %}

### **Install the Conva Omni Copilot package**

**The next step is to install the required packages inside your code repo**<br>

**yarn setup**

**If you use yarn for install packages, run the below command**

```
yarn add @slanglabs/conva-omni-copilot
```

**npm setup**

**If you use npm for managing your packages, run the below command**&#x20;

```bash
npm install @slanglabs/conva-omni-copilot --save
```

**Because Slang uses native libraries, you need to link the package to your codebase to run the automatic linking steps**

```
react-native link @slanglabs/slang-conva-react-native-retail-assistant
```

#### **For iOS:-**

**Add the path to the Slang Cocoapod repository to your Podfile**

```
# Add this to your podfile

source 'https://github.com/SlangLabs/cocoapod-specs'
```

**Add support for granting microphone permission**\
In iOS, the user must explicitly grant permission for an app to [access the user’s data and resources](https://developer.apple.com/design/human-interface-guidelines/ios/app-architecture/accessing-user-data/). An app with the ConvaOmniCopilot requires access to the User’s device microphone for voice interactions.<br>

To comply with this requirement, you must add `NSMicrophoneUsageDescription` key to the `Info.plist` file of your app and provide a message about why your app requires access to the microphone. The message will be displayed only when the ConvaOmniCopilot needs to activate the microphone.

To add the key:

1. In the Xcode project, go to the **Info** tab.
2. In the **Custom iOS Target Properties** section, hover over any key in the list and click the plus icon to the right.
3. From the list, select **Privacy - Microphone Usage Description**.
4. In the **Value** field to the right, provide a description for the added key. This description will be displayed to the user when the app is launched. \
   \&#xNAN;*For example: "We require microphone permission to enable the voice assistant platform"*
   {% endtab %}
   {% endtabs %}

## 2. Code Integration

### a. Initialization

The next step is to initialize the SDK with the keys and set of information required.

{% tabs %}
{% tab title="Android" %}
Our recommendation is to perform this initialization in the `onCreate` method of the `Application` class or the main `Activity` of your application.

```java
protected void onCreate(Bundle savedInstance) {
  // ...
  // This list, `waveGradientColor`, is designed to provide a 
  // collection of multi-wave gradient color combinations. 
  List<List<String>> waveGradientColor = Arrays.asList(
            Arrays.asList("#0197FF", "#FFFFFF"),
            Arrays.asList("#9701FF", "#FF0197"),
            Arrays.asList("#FF0197", "#FF9701")
  );
        
  OmniCopilotConfiguration configuration = new OmniCopilotConfiguration.Builder()
    .setAPIKey("your-api-key")
    .setCopilotID("your-copilot-id")
    .setApplication(getApplication())
    .setBrandColor("<Color Hex Code>")
    .enableApptrigger(false) // Set this to true if you want to use 
     //custom trigger instead of Global Trigger
    .setEnvironment(Environment.PRODUCTION)
    .setWaveGradientColor(waveGradientColor)
    .build();
  ConvaOmniCopilot.initialize(configuration);
}
```

{% endtab %}

{% tab title="Flutter" %}
This should ideally be done inside the main method.

<pre class="language-dart"><code class="lang-dart">import 'package:conva_omni_copilot/conva_omni_copilot.dart';


// This list, `waveGradientColor`, is designed to provide a 
// collection of multi-wave gradient color combinations. 
List&#x3C;List&#x3C;String>> waveGradientColor = [
      // Color pair 1
      ["#0197FF", "#FFFFFF"],
      // Color pair 2
      ["#9701FF", "#FF0197"],
      // Color pair 3
      ["#FF0197", "#FF9701"],
    ];
    
var assistantConfig = new OmniCopilotConfiguration()
 ..copilotId = "&#x3C;CopilotId>"
 ..apiKey = "&#x3C;APIKey>"
<strong> ..environment = CopilotEnvironment.PRODUCTION
</strong> ..uiMode = CopilotUIMode.LIGHT
 ..waveGradientColor = waveGradientColor
 ..enableCustomTrigger = false // Set this to true if you want to use 
 //custom trigger instead of Global Trigger
 ..fontPaths = ["&#x3C;Array of required font paths>"] 
 // Example:- ["fonts/TerminalDosis-Regular.ttf", "fonts/TerminalDosis-SemiBold.ttf"]
 ..brandColor = "&#x3C;Color Hex Code>";

ConvaOmniCopilot.initialize(assistantConfig);
</code></pre>

{% endtab %}

{% tab title="React Native" %}
This should ideally be done in the componentDidMount of your main app component.

<pre class="language-typescript"><code class="lang-typescript">import { ConvaOmniCopilot } from '@slanglabs/conva-omni-copilot';

const waveGradientColor: string[][] = [
    // Color pair 1
    ["#0197FF", "#FFFFFF"],
    // Color pair 2
    ["#9701FF", "#FF0197"],
    // Color pair 3
    ["#FF0197", "#FF9701"],
];

const config: OmniCopilotConfiguration = {
    copilotId: '&#x3C;CopilotId>',
    apiKey: '&#x3C;ApiKey>',
    environment: CopilotEnvironment.Production,
    uiMode: CopilotUIMode.Light,
<strong>    waveGradientColor: waveGradientColor,
</strong><strong>    brandColor = "&#x3C;Color Hex Code>",
</strong><strong>    enableAppTrigger = false // Set this to true if you want to use 
</strong>     //custom trigger instead of Global Trigger
};

ConvaOmniCopilot.initialize(config)
</code></pre>

{% endtab %}
{% endtabs %}

### b. Start Interaction with the Omni Copilot

Initiates a user interaction session in the Conva OmniCopilot platform.

When the custom trigger is tapped, it should call `startUserInteraction()` method to initiate the interaction.

{% tabs %}
{% tab title="Android" %}

```java
ConvaOmniCopilot.startUserInteraction();
```

**Parameters**

* `text` (optional): A string representing the text to be used for interaction.

```java
ConvaOmniCopilot.startUserInteraction("Custom text to start the interaction");
```

{% endtab %}

{% tab title="Flutter" %}

```dart
ConvaOmniCopilot.startUserInteraction();
```

**Parameters**

* `text` (optional): A string representing the text to be used for interaction.

```dart
ConvaOmniCopilot.startUserInteraction(text: "Custom text to start the interaction");
```

{% endtab %}

{% tab title="React Native" %}

```typescript
ConvaOmniCopilot.startUserInteraction();
```

**Parameters**

* `text` (optional): A string representing the text to be used for interaction.

```typescript
ConvaOmniCopilot.startUserInteraction("Custom text to start the interaction");
```

{% endtab %}
{% endtabs %}

### c. Displaying the Omni Copilot trigger

Trigger refers to the UI element that appears on the screen, which the user will click on to bring up the Copilot.

{% tabs %}
{% tab title="Android" %}
For Global trigger:-

```java
protected void onResume(Bundle savedInstance) {
    // ...
    CopilotUI.setGlobalTrigger();
    CopilotUI.showTrigger(this);
}
```

{% endtab %}

{% tab title="Flutter" %}
For Global Trigger:-

```dart
ConvaOmniCopilot.getUI().setGlobalTrigger();
ConvaOmniCopilot.getUI().showTrigger();
```

For Inline Trigger:-

Incorporate the following component into your UI definition at the desired location to display the trigger (typically represented by a microphone icon), often positioned alongside the search bar.

```dart
Container(
       height: 60,
       width: 60,
       child: ConvaOmniTrigger(enableCircularBackground: true,)
)
```

{% endtab %}

{% tab title="React Native" %}
For Global Trigger:-

```typescript
ConvaOmniCopilot.getUI().showTrigger();
```

{% endtab %}
{% endtabs %}

The trigger is sticky, which means that it will show up on all Activities after it is made visible. To prevent the trigger from showing up on specific activities, you will need to call:&#x20;

Note:- Follow this step only if you are using Global Trigger

{% tabs %}
{% tab title="Android" %}

```java
protected void onResume(Bundle savedInstance) {
    // ...
    CopilotUI.hideTrigger(this);
}
```

{% endtab %}

{% tab title="Flutter" %}

```dart
ConvaOmniCopilot.getUI().hideTrigger();
```

{% endtab %}

{% tab title="React Native" %}

```typescript
ConvaOmniCopilot.getUI().hideTrigger();
```

{% endtab %}
{% endtabs %}

### d. Customize Surface UI

To pause the Copilot Surface

{% tabs %}
{% tab title="Android" %}

```java
CopilotUI.pauseSurface();
```

{% endtab %}

{% tab title="Flutter" %}

```dart
ConvaOmniCopilot.getUI().pauseSurface();
```

{% endtab %}

{% tab title="React Native" %}

```
// TBD
```

{% endtab %}
{% endtabs %}

To resume the Copilot Surface

{% tabs %}
{% tab title="Android" %}

```java
CopilotUI.resumeSurface();
```

{% endtab %}

{% tab title="Flutter" %}

```dart
ConvaOmniCopilot.getUI().resumeSurface();
```

{% endtab %}

{% tab title="React Native" %}

```
// TBD
```

{% endtab %}
{% endtabs %}

To set a bottom margin to the Copilot Surface

{% tabs %}
{% tab title="Android Native" %}

```java
CopilotUI.setSurfaceBottomMargin(<bottomMargin>)
```

{% endtab %}

{% tab title="Flutter" %}

```dart
ConvaOmniCopilot.getUI().setSurfaceBottomMargin(<bottom_margin>);
```

{% endtab %}

{% tab title="React Native" %}

```
// TBD
```

{% endtab %}
{% endtabs %}

To reset the Surface Context:-

{% tabs %}
{% tab title="Android" %}
API to reset conversation history: SDK now by default retains conversation history on the UI. So re-invoking the surface would continue from the last session of the user. If the app wants to reset the conversation history at any point, the app can call the following API:

Param: (resetConversationHistory) => Boolean value

```java
CopilotUI.resetSurfaceContext(<resetConversationHistory>)
```

After this API is called, the SDK will refresh the UI context (prompts, hints) for the next user interaction.
{% endtab %}

{% tab title="Flutter" %}
API to reset conversation history: SDK now by default retains conversation history on the UI. So re-invoking the surface would continue from the last session of the user. If the app wants to reset the conversation history at any point, the app can call the following API:

```dart
ConvaOmniCopilot.getUI().resetCopilotSurfaceContext();
```

After this API is called, the SDK will refresh the UI context (prompts, hints) for the next user interaction.
{% endtab %}

{% tab title="React Native" %}

```
// TBD
```

{% endtab %}
{% endtabs %}

To set custom UI hints&#x20;

{% tabs %}
{% tab title="Android" %}

```java
HashMap<String, String> params = new HashMap<>();
params.put("param1", "value1");
params.put("param2", "value2");

List<HintInfo> hints = new ArrayList<>();
hints.add(new HintInfo("Example 1", "https://example1.com/username-help", params));
hints.add(new HintInfo("Example 2", "https://example2.com/username-help", params));

CopilotUI.setUIHints(hintInfo)
```

{% endtab %}

{% tab title="Flutter" %}

<pre class="language-dart"><code class="lang-dart"><strong>Map&#x3C;String, String> params = {
</strong>  "param1": "value1",
  "param2": "value2",
};

List&#x3C;HintInfo> hints = [
   HintInfo(hint: 'Example 1', url: 'https://example1.com/username-help', params: params),
   HintInfo(hint: 'Example 2', url: 'https://example2.com/username-help', params: params),
 ];
 ConvaOmniCopilot.getUI().setUIHints(hints);
</code></pre>

{% endtab %}

{% tab title="React Native" %}

```
// TBD
```

{% endtab %}
{% endtabs %}

HintInfo Properties:-

```
- `hint`: String
  - Description: The hint text.
- `url`: String (optional)
  - Description: The URL associated with the hint.
- `params`: `MutableMap<String, String>`
  - Description: Additional parameters associated with the hint.
```

To minimize the Copilot Surface

{% tabs %}
{% tab title="Android" %}

```java
CopilotUI.setCopilotSurfaceMode(CopilotUI.CopilotSurfaceMode.MINIMIZE)
```

{% endtab %}

{% tab title="Flutter " %}

```dart
ConvaOmniCopilot.getUI().minimizeSurface(); 
```

{% endtab %}

{% tab title="React Native" %}

```
// TBD
```

{% endtab %}
{% endtabs %}

To maximize the Copilot Surface

{% tabs %}
{% tab title="Android" %}

```java
CopilotUI.setCopilotSurfaceMode(CopilotUI.CopilotSurfaceMode.MAXIMIZE)
```

{% endtab %}

{% tab title="Flutter" %}

```dart
ConvaOmniCopilot.getUI().maximizeSurface(); 
```

{% endtab %}

{% tab title="React Native" %}

```
// TBD
```

{% endtab %}
{% endtabs %}

### e. Implementing actions

The app will need to register actions that can be invoked by the Copilot whenever it receives the necessary information from the user. These actions will be invoked automatically by the Copilot whenever the user provides input either via text or voice and it gets processed by the backend, resulting in an app action.

{% tabs %}
{% tab title="Android" %}

```java
ConvaOmniCopilot.setAction(new CopilotAction() {
        @Override
        public void onSearch(@NonNull SearchInfo searchInfo) {
            // Fire the search action
            // You can access searchInfo properties to perform the search
            // For example:
            //System.out.println("Search term: " + searchInfo.searchTerm);
        }
        @Override
        public void onNavigation(@NonNull NavigationInfo navigationInfo) {
            // Fire the navigation action
            // You can access navigationInfo properties to perform navigation
            // For example:
            // System.out.println("Navigation target: " + navigationInfo.target);
    }
        }
    });
```

{% endtab %}

{% tab title="Flutter" %}

```dart
//Set the action handler via the setAction method
class AppAction implements CopilotAction {

  @override
  void initState() {
    super.initState();
    ConvaOmniCopilot.setAction(this);
  }
  @override
  void onNavigation(NavigationInfo navigationInfo) {
    // Handle navigation requests
  }

  @override
  void onSearch(SearchInfo searchInfo) {
    // Handle search requests
  }
}

var action = new AppAction();
ConvaOmniCopilot.setAction(action);

```

{% endtab %}

{% tab title="React Native" %}

<pre class="language-typescript"><code class="lang-typescript">ConvaOmniCopilot.setAction({
    onSearch: (searchInfo: any) => {
        // Fire the search action
        // You can access searchInfo properties to perform the search
        // For example:
<strong>        // var searchterm : string = searchInfo["searchTerm"]
</strong>    },
    onNavigation: (navigationInfo: any) => {
        // Fire the navigation action
        // You can access navigationInfo properties to perform the search
        // For example:
        // var navigationTarget : string = navigationInfo["target"]
    }
});
</code></pre>

{% endtab %}
{% endtabs %}

The parameter`SearchInfo`  contains the breakdown of the original search request. Its structure is as described below:&#x20;

{% tabs %}
{% tab title="Android" %}

```java
// Type definitions
public class SearchInfo {
    public String searchTerm; // returns the full search term
    public @Nullable String category; // returns the category for the user query
    public @Nullable String app; // returns the app for the user query
    public @Nullable List<FilterInfo> filters; // returns the list of filters applied
    public @Nullable SortInfo sortInfo; // returns the sorting info applied
}

public class FilterInfo {
    public String key; // returns the filter key
    public Map<String, Object> params; // Additional parameters associated with the filter.
}
public class SortInfo {
    public String sortKey; // returns the sort key
}
```

{% endtab %}

{% tab title="Flutter" %}

```dart
class SearchInfo {
  String get searchTerm // (String): Returns the entire search term.
  String? get category // (String, Nullable): Returns the category for the user query, if available.
  String? get app // (String, Nullable): Returns the app for the user query, if available.
  List<FilterInfo>? get filters // (List of FilterInfo, Nullable): Returns the list of filters applied, if any.
  SortInfo? get sortInfo // (SortInfo, Nullable): Returns the sorting info applied, if available.
}

class FilterInfo {
  String get filterCategory // (String): Returns the filter category.
  String get filterLabel // (String): Returns the filter label.
  String? get filterId // (String, Nullable): Returns the filter ID, if available.
}

class SortInfo {
  String? get sortKey // (String, Nullable): Returns the sort key.
}
```

{% endtab %}

{% tab title="React Native" %}

```json
// When the user searches for something 
// This is how the SearchInfo parameter would be populated
// Example

{
	"filters": [],
	"app": "",
	"category": "",
	"sortInfo": {
		"sortKey": "popularity"
	},
	"searchTerm": "sunscreen"
}
```

{% endtab %}
{% endtabs %}

The parameter NavigationInfo contains the breakdown of the original navigation request. Its structure is as described below:&#x20;

{% tabs %}
{% tab title="Android" %}

```java
public class NavigationInfo {
    public String target; // Represents the target of the navigation action.
    public @Nullable String url; // Represents the URL associated with the navigation action, if any.
    public @Nullable Map<String,String> parameters; // Represents additional parameters associated with the navigation action.
}
```

{% endtab %}

{% tab title="Flutter" %}

```dart
class NavigationInfo {
     String get target; // Represents the target of the navigation action.
     String? get url; // Represents the URL associated with the navigation action, if any.
     Map<String,String>? get parameters; // Represents additional parameters associated with the navigation action.
}
```

{% endtab %}

{% tab title="React Native" %}

```json
// When the user searches for something 
// This is how the NavigationInfo parameter would be populated
// Example

{
	"target": "home",
	"url": "<Url to your target>",
}
```

{% endtab %}
{% endtabs %}

### f. Notifying the current context to Omni Copilot

The following APIs can be used to provide context or filter content-based on the selected app.

{% tabs %}
{% tab title="Android" %}
For notifying the current app name

```java
ConvaOmniCopilot.setCurrentApp(<"current_app_name">);
```

For notifying the current app category

```java
ConvaOmniCopilot.setCurrentCategory(<"current_app_category">);
```

{% endtab %}

{% tab title="Flutter" %}
For notifying the current app name

```dart
ConvaOmniCopilot.setCurrentApp(<"current_app_name">);
```

{% endtab %}

{% tab title="React Native" %}

```
// TBD
```

{% endtab %}
{% endtabs %}

### g. Notifying the Omni Copilot

The following APIs can be used to provide contextual information to the Omni Copilot

{% tabs %}
{% tab title="Android" %}

```java
// Update the user profile
ConvaOmniCopilot.updateUserProfileInfo(
    "<user_id>", 
    new HashMap<String, String>() {
            {
                // Any additional user info
                put("user_info_1","info_1");
                put("user_info_2","info_2");
            }
);

// Notify text search
ConvaOmniCopilot.notifyTextSearch("<SearchString>");

// Notify CTR event
ConvaOmniCopilot.notifyCTREvent("eventInfo",
    new HashMap<String, String>() {
        {
            // The section that was clicked. Here are some
            // examples of events 
            // "NavigatedToProductPage"
            // "AddedToCart"
            // "AddedToWishlist"
            put("eventName","<event>"); 
            // The product item that was clicked
            // Eg: "Organic Onions"
            put("itemName","<item>");
        }
});
```

{% endtab %}

{% tab title="Flutter" %}

<pre class="language-dart"><code class="lang-dart">// Update the user profile
<strong>Map&#x3C;String, String> userMetaData = {
</strong>      'user_info_1': '&#x3C;info_1>',
      'user_info_2': '&#x3C;info_2>',
};
ConvaOmniCopilot.setUserInfo("&#x3C;user_id>", userMetaData);


// Notify text search
Map&#x3C;String, String> searchMetaData = {
      'searchName1': '&#x3C;searchData1>',
      'searchName2': '&#x3C;searchData2>',
};
ConvaOmniCopilot.notifyTextSearch("&#x3C;searchItem>", searchMetaData);


// Notify CTR event
Map&#x3C;String, String> eventMetaData = {
      // The section that was clicked. Here are the
      // supported strings 
      // "NavigatedToProductPage"
      // "AddedToCart"
      // "AddedToWishlist"
      'eventName': '&#x3C;event>',
      // The product item that was clicked
      // Eg: "Organic Onions"
      'itemName': '&#x3C;item>',
};
ConvaOmniCopilot.notifyCTREvent("&#x3C;eventInfo>", eventMetaData);

</code></pre>

{% endtab %}

{% tab title="React Native" %}

```
// TBD
```

{% endtab %}
{% endtabs %}

### h. Copilot Lifecycle Events

The Omni Copilot handles most of the heavy lifting of interacting with the end-users and notifies the app when there is some action to be performed by the app. But in some cases, apps may want to be notified of low-level events that the Copilot is aware of.  For example, whether a user clicks on the trigger (the microphone button) or the copilot is initialized.

The Copilot's Lifecycle Events API provides access to low-level Assistant events.

#### Registering for events

The app can register with the Assistant to be notified of all interesting life-cycle events via the `setLifeCycleObserver` method.

{% tabs %}
{% tab title="Android" %}

```java
ConvaOmniCopilot.setLifecycleObserver(new OmniLifecycleObserver() {
    @Override
    public void onCopilotInitSuccess() {
        // Called when the Conva OmniCopilot initialization is successful.
    }

    @Override
    public void onCopilotInitFailure(String description) {
        // Called when the Conva OmniCopilot initialization fails, providing a description of the failure.
    }

    @Override
    public void onCopilotInteractionBegin(boolean isVoice) {
        // Called when a user interaction with Conva OmniCopilot begins, indicating whether the interaction is voice-initiated (`true`) or not (`false`).
    }

    @Override
    public void onCopilotInteractionEnd(boolean isCanceled) {
        // Called when a user interaction with Conva OmniCopilot ends, indicating whether the interaction was canceled (`true`) or not (`false`).
    }

    @Override
    public void onCopilotSurfaceDismissed() {
        // Called when the Conva OmniCopilot surface (e.g., UI overlay) is dismissed.
    }
    
    @Override
    public void onCopilotError(CopilotError errorType) {
        // Callback method invoked when an error occurs during a Copilot interaction.
        //
        // [error] The error that occurred during the Copilot interaction.
        //         Possible values are defined in the [ErrorType] enum.
    }
    
    
});
```

{% endtab %}

{% tab title="Flutter" %}

```dart
class _MyAppState extends State<MyApp> implements
        CopilotLifeCycleObserver {
        
  @override
  void initState() {
    super.initState();
    ConvaOmniCopilot.setLifeCycleObserver(this);
  }
  
  @override
  void onCopilotInitFailure(String description) {
    // Called when the Conva OmniCopilot initialization fails, providing a description of the failure.
  }

  @override
  void onCopilotInitSuccess() {
    // Called when the Conva OmniCopilot initialization is successful.
  }

  @override
  void onCopilotInteractionBegin(bool isVoice) {
    // Called when a user interaction with Conva OmniCopilot begins, indicating whether the interaction is voice-initiated (`true`) or not (`false`).
  }
  
  @override
  void onCopilotInteractionEnd(bool isCanceled) {
    // Called when a user interaction with Conva OmniCopilot ends, indicating whether the interaction was canceled (`true`) or not (`false`).
  }

  @override
  void onCopilotSurfaceDismissed() {
    // Called when the Conva OmniCopilot surface (e.g., UI overlay) is dismissed.
  }
  
  @override
  void onCopilotError(CopilotError error) {
    // Callback method invoked when an error occurs during a Copilot interaction.
    //
    // [error] The error that occurred during the Copilot interaction.
    //         Possible values are defined in the [ErrorType] enum.
  }
}
```

{% endtab %}

{% tab title="React Native" %}

```typescript
ConvaOmniCopilot.setLifeCycleObserver({
    onCopilotInitFailure: (description: string) => {
        // Called when the Conva OmniCopilot initialization fails, 
        // providing a description of the failure.
    },
    onCopilotInitSuccess: () => {
        // Called when the Conva OmniCopilot initialization is successful.
    },
    onCopilotInteractionBegin: (isVoice: boolean) => {
        // Called when a user interaction with Conva OmniCopilot begins, 
        // indicating whether the interaction is voice-initiated (`true`) or not (`false`).
    },
    onCopilotInteractionEnd: (isCanceled: boolean) => {
        // Called when a user interaction with Conva OmniCopilot ends,
        // indicating whether the interaction was canceled (`true`) or not (`false`).
    },
    onCopilotSurfaceDismissed: () => {
        // Called when the Conva OmniCopilot surface (e.g., UI overlay) is dismissed.
    }
  
});
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.conva.ai/conva-omni/integrating-the-omni-copilot-with-your-app.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
