Browse In-App Agent

React Native SDK — Release Notes

@revrag-ai/embed-react-native · release history, newest first. Install the latest with npm install @revrag-ai/embed-react-native@^1.3.0; confirm the current version on npm. Never install 1.1.0 — see 1.1.1.


1.3.0: upgrading from 1.2.x

Upgrade

npm install @revrag-ai/embed-react-native@^1.3.0
cd ios && pod install && cd ..

No code changes needed. The public API, the peer dependencies (same verified stacks) and the native code are unchanged from 1.2.0. Restart Metro with --reset-cache and rebuild.

The agent's taps now appear in click analytics. They arrive as the same ANALYTICS_DATA events as a person's, with data.source: "agent". If your dashboards or Embed.on(ANALYTICS_DATA) listeners count clicks, filter on data.source — see The agent's taps are reported, tagged.


Changed

The agent's taps are reported, tagged

1.2.0 dropped every tap the agent made during a call. They are now sent like a person's, and data.source tells them apart:

Who tapped1.2.01.3.0
A personsent, source: "user"sent, source: "user"
The agent, during a callnot sentsent, source: "agent"
The SDK widget's own buttonsnot sentnot sent

This matches the web SDK's data.source. A person tapping the same control right after the agent is sent too — the 300 ms repeat filter now applies per source.


Fixed

The agent no longer acts on the screen behind a modal

With a React Native <Modal> open, the agent could still tap, type into or move a slider on the screen behind it — pressing a control the user couldn't see or reach. The screen behind an open modal is now reported to the agent as not visible, and actions aimed at it are refused; the agent works on the modal itself.

Menus, popovers and toasts don't block the screen behind them, and neither does an overlay parked off-screen. When two modals are open, the one shown last is on top. A sheet that isn't an RN <Modal> counts as part of the screen unless its container sets accessibilityViewIsModal. See Modals and overlays.

Highlights draw on top of an open modal

A highlight on a modal's content was drawn underneath the modal, so the user never saw it. It now draws on top, in the same window as the widget.


1.2.0: upgrading from 1.1.x

Upgrade

npm install @revrag-ai/embed-react-native@^1.2.0
cd ios && pod install && cd ..

No code changes needed. Nothing was removed or changed in the public API, the peer dependencies are the same as 1.1.1 (same verified stacks), and no native code changed. Restart Metro with --reset-cache and rebuild.

Click analytics event names and payload change in this release. If your dashboards, funnels or Embed.on(ANALYTICS_DATA) listeners use the SDK's *_pressed events, read Taps on your app are named by what they do before you ship.


Changed

Taps on your app are named by what they do

While the button is visible, the SDK reports taps on Pressable and the Touchable family as ANALYTICS_DATA events. It now follows the Android and web SDKs' naming:

Touchable's role1.11.2.0
button, imagebutton, tab<name>_pressed<name>_pressed, type: button_click
checkbox, switch, togglebutton<name>_pressed<name>_toggled, type: checkbox_toggle
radio<name>_pressed<name>_selected, type: radio_select
combobox<name>_pressed<name>_opened, type: button_click
link, or no role<name>_pressed<name>_pressed, type: element_click

The <name> comes from your own id, name or testID first, used as written — an existing submit_pressed stays submit_pressed. Without one, the SDK uses the accessibility label, the visible text or an icon name, cleaned up to at most four words with digits and currency words left out:

1.11.2.0
pressable-7_pressed (no id, "Apply Now" text)apply_now_pressed
touchableopacity-3_pressed (icon-only back button)arrow_back_pressed
dark_mode_pressed (a switch with id="dark_mode")dark_mode_toggled

data is now flat: element_id, type, kind, role, checked (the state after the tap), source, click_sequence, component, and legacy_event_name when the name changed, so dashboards can map old names to new. The 1.1 nested metadata: { timestamp, type, component, clickSequence } is gone — move listeners to data.

No longer reported: the SDK widget's own buttons, the agent's own taps, and a second identical event within 300 ms. Text with an email, UPI id or masked number never becomes a name.

See Automatic click / press tracking for the full rules, including how to declare a toggle's state.

The widget follows more of your dashboard

Dashboard setting1.11.2.0
Collapsed state (isCollapsed: false)ignoredthe card starts open
Left / top paddingfixed spacingused; a top-anchored button can be dragged down
Collapse time, when not setthe card stays openthe card folds after 15 s (paused while captions are on)
Gradient fill (fillType: "gradient")left → rightdiagonal, as on Android; one gradient color alone themes the card
Corner radiusrounded the button and the cardrounds the open card only (default 20); the button stays a pill
Panel close delay (viewCloseDelay)not usedhow long the calculation panel stays open

Check the widget on a device after upgrading — the same dashboard settings can look different.

Agent status and captions

  • The status line follows Android: "Listening", "Speaking", "Thinking", and a muted state when the user has muted themselves (a muted user used to see "Listening…").
  • Captions show the whole sentence; a long answer scrolls instead of ending in "…".
  • The captions (CC) badge uses the card's text color, so it stays visible on light cards.

Less text in UI snapshots

UI snapshots no longer carry each element's combined descendant text (subtree_text), so less of each screen's text leaves the device. What is captured, and the redaction rules, are unchanged.


Fixed

A touch on your app stops the agent

Touching your app while the agent was tapping, scrolling or highlighting did nothing — it kept acting over the user. Now what it was doing is cancelled and the highlight disappears. Touches on the SDK widget and the agent's own taps never count.

The agent no longer presses disabled controls

A disabled button kept its onPress, and the agent called it directly, bypassing your guard on a "Pay" or "Submit" button. Disabled touchables and read-only TextInputs are now refused, and targeting the label inside a disabled button no longer taps the card around it.

Resuming the agent keeps a user's mute

resumeAgent() unmuted a user who had muted themselves before the pause. It now unmutes only if the pause muted.

Other fixes

  • Events report the correct sdk_version (1.1.1 reported "1.1.0").
  • React Native role values such as img, option, listitem and searchbox are understood by the agent.

1.1.1

Fixes a crash in 1.1.0: every screen that rendered a FlatList or SectionList failed with "Cannot read property 'Consumer' of undefined". Do not install 1.1.0 — go to 1.2.0.

  • Patched components keep their statics (ScrollView.Context, TextInput.State).
  • The SDK installs its component wrappers when the package loads, not when EmbedProvider mounts. On 1.1.0, lists and inputs already on screen were remounted once (scroll reset, keyboard dropped).
  • Jest: a snapshot containing a <Modal> gains one wrapper View once the SDK is imported — update those snapshots.

1.1.0

The Action Intelligence release — the agent can now see and act on your screens — plus a stricter, more predictable integration contract. Upgrading from 1.0.35 requires a few code changes; work through the upgrade steps below.

Breaking changes

ChangeWhat to do
appVersion is required in useInitializeMove it out of EmbedProvider into useInitialize({ apiKey, appVersion }). The provider prop is now an override only.
navigationRef is required for the widget to appearPass the same ref to EmbedProvider and NavigationContainer. Without it the button never shows and startCall() fails.
Do not call LiveKit's registerGlobals() yourselfRemove it from index.js — useInitialize calls it; a second call duplicates native event listeners.
iOS module renamedimport livekit_react_native and LivekitReactNative.setup() (lowercase "k") in AppDelegate.swift — the old import LiveKitReactNative no longer resolves.
Android permissions now merged by the SDKRemove manually added RECORD_AUDIO / MODIFY_AUDIO_SETTINGS — the SDK's manifest merges them (plus BLUETOOTH_CONNECT). Voice-only apps may strip camera with tools:node="remove".
ProGuard package changedReplace -keep class com.revrag.embed.** with -keep class com.revragai.embedreactnative.** { *; }. WebRTC/LiveKit/Lottie ship their own consumer rules — drop those manual keeps.
Supported React Native narrowed to 0.76 – 0.86Hermes required. RN ≥ 0.82 needs the New-Architecture stack: Reanimated 4.5.2 + react-native-worklets + Gesture Handler 3.x, with react-native-worklets/plugin as the last Babel plugin. See the Dependency & Compatibility Guide.

New

  • Action Intelligence / UI capture — the agent reads the on-screen element tree (stableId targeting via testID) and can tap, type, select, scroll, and highlight, with action verification. Sensitive-field controls: secureTextEntry (never captured, agent refuses to touch) and nativeID="embed-redact-…" (value masked).
  • Widget visibility system — showOnAllScreens, includeScreens, excludeScreens, endCallWhenHiddenByVisibility, embedButtonContinuity, embedButtonDelayMs, and grouped embedButtonVisibilityConfig (per-group delay/inset/continuity).
  • Agent lifecycle events — one embedOnAgent subscription for all events (AGENT_VISIBLE, AGENT_TAP_TO_OPEN/_CLOSE, POPUP_MESSAGE_VISIBLE, AGENT_CONVERSATION_STARTED/_ENDED, GEN_TOOL_TRIGGERED, MICROPHONE_PERMISSION_ALLOWED/_DENIED). AGENT_CONNECTED/AGENT_DISCONNECTED are deprecated aliases.
  • Automatic click/press tracking — taps on Pressable and the Touchable family emit ANALYTICS_DATA events named from the element's id/name prop (<id>_pressed).
  • Manual controls — startCall/endCall/isCallActive, pauseAgent/resumeAgent, expandWidget/collapseWidget, EmbedLogout, checkPermissions/openAppSettings, and setScreenMatching (alias/ancestor/structure screen matching).
  • Screenshot consent props — sessionScreenshotEnabled / passiveScreenshotEnabled (both default false, double consent with a backend flag).

Fixed / clarified

  • startCall() returns false only when the widget is hidden or unmounted. A missing USER_DATA no longer rejects — the token request aborts while the promise resolves true, so observe AGENT_CONVERSATION_STARTED for the real outcome.
  • USER_DATA is persisted only after the backend accepts it — re-send it if it was first sent offline.
  • SCREEN_STATE events are analytics tags only; they do not drive widget visibility or UI capture.
  • excludeScreens is consulted only in showOnAllScreens mode; in includeScreens mode the allow-list alone decides.

Upgrade steps: 1.0.35 → 1.1.0

  1. npm install @revrag-ai/embed-react-native@^1.2.0 (never 1.1.0), then re-pin peers per the Dependency & Compatibility Guide and run pod install.
  2. Move appVersion into useInitialize; remove it from EmbedProvider.
  3. Ensure navigationRef is passed to both EmbedProvider and NavigationContainer.
  4. Delete any registerGlobals() call from index.js.
  5. Update AppDelegate.swift to import livekit_react_native / LivekitReactNative.setup().
  6. Remove manually declared Android audio permissions and update the ProGuard keep rule.
  7. Rebuild fully (gradlew clean, pod install) and re-test a call on a real device.

1.0.35 and earlier

The pre–Action Intelligence line: floating voice-agent button (LiveKit), route tracking via EmbedProvider, and the four Embed.Event keys (USER_DATA, SCREEN_STATE, CUSTOM_EVENT, ANALYTICS_DATA). Supported React Native 0.70+. No UI capture, no agent actions, no visibility groups. If you are still on this line, upgrade via the steps above — 1.0.x is not maintained.



Support